1. 程式人生 > >《Machine Learning in Action》| 第1章 k-近鄰演算法

《Machine Learning in Action》| 第1章 k-近鄰演算法

準備:使用 Python 匯入資料

"""
@函式說明: 建立資料集
"""
def createDataSet():
    # 四組二維特徵
    group = np.array([[3,104],[2,100],[101,10],[99,5]])
    # 四組特徵的標籤
    labels = ['愛情片','愛情片','動作片','動作片']
    return group, labels

"""

實施kNN演算法

  • 函式的虛擬碼如下: 對未知類別屬性的資料集中的每個點依次執行以下操作: (1) 計算已知類別資料集中的點與當前點之間的距離; (2) 按照距離遞增次序排序; (3) 選取與當前點距離最小的k個點; (4) 確定前k個點所在類別的出現頻率; (5) 返回前k個點出現頻率最高的類別作為當前點的預測分類。
程式清單 2-1 k-近鄰演算法

"""
@函式說明:kNN分類(k近鄰演算法)
Parameters:
	inX - 用於分類的資料(測試集)
	dataSet - 用於訓練的資料(訓練集)
	labels - 類別標籤
	k - 選擇最近鄰居的數目
Returns:
	sortedClassCount[0][0] - 分類結果
"""
def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0] # numpy函式shape[0]返回dataSet的行數,4行
    
    # 歐式距離計算
    # 橫向複製inX共1次,縱向複製inX共dataSize次
# print(np.tile(inX, (dataSetSize,1))) """ 構造相同行數的測試集test [[ 10 120] [ 10 120] [ 10 120] [ 10 120]] """ diffMat = np.tile(inX, (dataSetSize,1)) - dataSet # 沿橫向、縱向複製多維陣列 """ test: group: diffMat: [[ 10 120] [[ 3 104] [[ 7 16] [ 10 120] —— [ 2 100] = [ 8 20] [ 10 120] [101 10] [-91 110] [ 10 120]] [ 99 5]] [-89 115]] """
# print(diffMat) # 二維特徵相減後平方 sqDiffMat = diffMat ** 2 # print(sqDiffMat) """ sqDiffMat(每個元素平方): [[ 49 256] [ 64 400] [ 8281 12100] [ 7921 13225]] """ # sum()將所有元素相加,sum(0)列相加,sum(1)行相加 sqDistances = sqDiffMat.sum(axis=1) # print("sqDistances:\n",sqDistances) """ sqDistances: [ 305 464 20381 21146] """ # 開方,計算出距離 distances = sqDistances ** 0.5 # print(" distances:\n", distances) """ distances(算出來的最終的歐式距離): [ 17.4642492 21.54065923 142.76203977 145.41664279] """ sortedDistIndices = distances.argsort() # 返回distances中元素從小到大排序後的索引值 # print(sortedDistIndices) # [0 1 2 3] classCount = {} # 定義記錄類別次數的字典 for i in range(k): voteIlabel = labels[sortedDistIndices[i]] # 取出前K個元素的類別,前3個類別為:愛情片 愛情片 動作片 # print(voteIlabel) #dict.get(key,default=None),字典的get()方法,返回指定鍵的值,如果值不在字典中返回預設值。 #計算類別次數 # print(classCount.get(voteIlabel,0)) classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # 沒出現過的返回0再+1就是1次,愛情片(在空字典中沒出現過,+1作為1次)、愛情片(出現過1次,+1是兩次)、動作片(沒出現過,+1作為1次) # print(classCount[voteIlabel]) # 愛情片 愛情片 動作片, 1 2 1 # classCount: {'愛情片': 2, '動作片': 1} """ python內建函式:sorted函式 sorted(iterable<可迭代物件>, cmp<對函式排序>, key<對元素排序>, reverse<True降序,False升序(預設)>) sort 是應用在 list 上的方法,sorted 可以對所有可迭代的物件進行排序操作。 內建函式 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。 詳解:http://www.runoob.com/python/python-func-sorted.html """ #python3中用items()替換python2中的iteritems() #key=operator.itemgetter(1)根據字典的值value進行排序 #key=operator.itemgetter(0)根據字典的鍵key進行排序 #reverse降序排序字典,reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(預設) sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) # print('sortedClassCount:\n',sortedClassCount) """ sortedClassCount: [('愛情片', 2), ('動作片', 1)] """ return sortedClassCount[0][0]

示例:使用 k-近鄰演算法改進約會網站的配對效果

準備資料:從文字檔案中解析資料

程式清單 2-2 將文字記錄轉換為NumPy的解析程式
"""
函式說明:開啟並解析檔案,對資料進行分類:1代表不喜歡、2代表魅力一般,3代表極具魅力
Parameters:
    filename - 檔名
Return:
    returnMat - 特徵矩陣
    classLabelVector - 分類Label向量
"""
def file2matrix(filename):
    loveDict = {'didntLike':1,'smallDoses':2,'largeDoses':3}
    fr = open(filename) # 開啟檔案
    arrayOlines = fr.readlines() # 逐行讀取
#    print(arrayOlines)
    '''
    arrayOlines:
    ['40920\t8.326976\t0.953952\tlargeDoses\n', '14488\t7.153469\t1.673904\tsmallDoses\n',...,'43757\t7.882601\t1.332446\tlargeDoses\n']
    '''
    numberOfLines = len(arrayOlines) # 得到檔案行數,共1000行資料
#    print(numberOfLines)
    returnMat = np.zeros( (numberOfLines,3) ) # 初始化特徵矩陣,解析完成的資料:numberOfLines行3列
    classLabelVector = [] # 初始化分類標籤向量
    index = 0 # 行的索引值
    for line in arrayOlines:
        # s.strip(rm),當rm空時,預設刪除空白符(包括'\n','\r','\t',' ')
        line = line.strip() # 刪去字串首尾部空字元
#        print(line)
        '''
        如最後兩行line:
        48111   9.134528        0.728045        largeDoses
        43757   7.882601        1.332446        largeDoses
        '''
        # 使用s.split(str="",num=string,cout(str))將字串根據'\t'分隔符進行切片
        listFromLine = line.split('\t') # 按'\t'對字串進行分割,listFromLine是列表
#        print(listFromLine) # 分割成列表
        '''
        如最後兩行listFromLine(列表):
        ['48111', '9.134528', '0.728045', 'largeDoses']
        ['43757', '7.882601', '1.332446', 'largeDoses']
        '''
        returnMat[index,:] = listFromLine[0:3] # 將資料前三列(特徵)一行一行賦值給returnMat
        index += 1
        # 根據文字中標記的喜歡的程度進行分類,1代表不喜歡,2代表魅力一般,3代表極具魅力
        # 讀取的listFromLine的最後一列為類別標籤
        if listFromLine[-1].isdigit(): # 如果listFromLine最後一列是數字,資料集datingTestSet.txt
            classLabelVector.append(int(listFromLine[-1])) # 直接賦值給classLabelVector
        else: # 如果listFromLine最後一列不是數字,而是字串,資料集datingTestSet2.txt
            classLabelVector.append(loveDict.get(listFromLine[-1]))       
    return returnMat, classLabelVector # 返回的類別標籤向量是1,2,3
    '''
    returnMat:                                           classLabelVector:
    [[4.0920000e+04 8.3269760e+00 9.5395200e-01]         [3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2,
    [1.4488000e+04 7.1534690e+00 1.6739040e+00]           1, 1, 1, 1, 1, 2, 3, 2, 1, 2, 3, 2, 3, 
    [2.6052000e+04 1.4418710e+00 8.0512400e-01]           ...
    ...                                                   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 
    [2.6575000e+04 1.0650102e+01 8.6662700e-01]           2, 2, 2, 1, 3, 3, 3]
    [4.8111000e+04 9.1345280e+00 7.2804500e-01]
    [4.3757000e+04 7.8826010e+00 1.3324460e+00]]
    '''

準備資料:歸一化數值

程式清單 2-3 歸一化特徵值

"""
函式說明:特徵歸一化函式,對資料進行歸一化
Parameters:
    dataSet - 特徵矩陣
Returns:
    normDataSet - 歸一化後的特徵矩陣
    ranges - 資料範圍
    minVals - 資料最小值
"""
def autoNorm(dataSet):
    minVals = dataSet.min(0) # 獲取資料每一列的最小值和最大值,返回一維列表,min(0) axis=0每一列,axis=1每一行
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals # 最大值和最小值的範圍
#    print('minVals:\n',minVals) # [0.       0.       0.001156]
#    print('maxVals:\n',maxVals) # [9.1273000e+04 2.0919349e+01 1.6955170e+00]
#    print('ranges:\n',ranges) # [9.1273000e+04 2.0919349e+01 1.6943610e+00] 
    normDataSet = np.zeros(np.shape(dataSet)) # 初始化歸一化特徵矩陣,np.shape(dataSet)返回dataSet的矩陣行列數
#    print(dataSet.shape) # (1000, 3)
    m = dataSet.shape[0] # dataSet的行數,共1000行
    '''
    下面的公式可以將任意取值範圍的特徵值轉化為0到1區間內的值:
    newValue = (oldValue - min) / (max - min)
    其中min和max分別是資料集中的最小特徵值和最大特徵值。
    '''
    normDataSet = dataSet - np.tile(minVals, (m, 1)) # 原始值減去最小值
    normDataSet = normDataSet / np.tile(ranges, (m, 1)) # 再除以最大值和最小值的差,得到歸一化資料,normDataSet值被限定在[0, 1]之間
    return normDataSet, ranges, minVals # 返回歸一化資料結果,資料範圍,最小值
    '''
    normDataSet:
    [[0.44832535 0.39805139 0.56233353]
    [0.15873259 0.34195467 0.98724416]
    [0.28542943 0.06892523 0.47449629]
    ...
    [0.29115949 0.50910294 0.51079493]
    [0.52711097 0.43665451 0.4290048 ]
    [0.47940793 0.3768091  0.78571804]]
    ranges:
    [9.1273000e+04 2.0919349e+01 1.6943610e+00]
    minVals:
    [0.       0.       0.001156]
    '''

測試演算法:作為完整程式驗證分類器

程式清單 2-4 分類器針對約會網站的測試程式碼
"""
函式說明:分類器測試函式    
"""
def datingClassTest():
    hoRatio = 0.10 # 整個資料集的10%用來測試,即拿100個樣本作為測試集
    datingDataMat, datingLabels = file2matrix(r'D:\dataset\inaction\kNN\datingTestSet2.txt') # 匯入資料集
    normMat, ranges, minVals = autoNorm(datingDataMat) # 所有特徵歸一化,返回歸一化特徵矩陣,資料範圍,最小值
#    print(normMat.shape) # (1000, 3)
    m = normMat.shape[0] # 樣本個數,normMat的行數,共1000個樣本
    numTestVecs = int(m * hoRatio) # 測試樣本個數,100個
    errorCount = 0.0 # 分類錯誤計數
#    print('測試集第一條資料:\n',normMat[0,:], '------------------------------','\n訓練集:\n',normMat[numTestVecs:m,:])
    '''
    測試集第一條資料:
    [0.44832535 0.39805139 0.56233353] 
    ----------------------------------
    訓練集:
    [[0.46457331 0.53983597 0.12206372]       
    [0.36871802 0.31502142 0.79791792]
    [0.10047878 0.2252441  0.11391374]
    ...
    [0.29115949 0.50910294 0.51079493]
    [0.52711097 0.43665451 0.4290048 ]
    [0.47940793 0.3768091  0.78571804]]
    '''
    for i in range(numTestVecs):
        # 對測試集的每行資料進行分類測試
        classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m], 3)  # 取前numTestVecs個數據作為測試集,後m-numTestVecs個數據作為訓練集,datingLabels[numTestVecs:m]為訓練集標籤
        print("分類結果:%s, 真實類別:%d" % (classifierResult, datingLabels[i]))
        if classifierResult != datingLabels[i]:
            errorCount += 1.0
    print("錯誤率:%g%%" % (errorCount / float(numTestVecs)*100)) # 列印錯誤率
    print("錯誤個數:",errorCount)

使用演算法:構建完整可用系統

程式清單 2-5 約會網站預測函式
"""
函式說明:通過使用者輸入一個人的三維特徵,進行分類輸出
"""
def classifyPerson():
    resultList = ['一點也不喜歡','有點喜歡','非常喜歡']
    # 使用者輸入特徵
    precentTats = float(input("玩視訊遊戲所消耗時間百分比:"))
    ffMiles = float(input("每年獲得的飛行常客里程數:"))
    iceCream = float(input("每週消費的冰淇淋公升數:"))
    datingDataMat, datingLabels = file2matrix(r'D:\dataset\inaction\kNN\datingTestSet2.txt') # 開啟並處理資料集
    normMat, ranges, minVals = autoNorm(datingDataMat) # 訓練集歸一化
#    print('normMat:\n',normMat)
    inArr = np.array([ffMiles, precentTats, iceCream]) # 測試集,生成Numpy陣列
#    print('inArr:\n',inArr)
    norminArr = (inArr - minVals) / ranges # 測試集歸一化
#    print('norminArr:\n',norminArr)
    '''
    normMat:
    [[0.44832535 0.39805139 0.56233353]
    [0.15873259 0.34195467 0.98724416]
    [0.28542943 0.06892523 0.47449629]
    ...
    [0.29115949 0.50910294 0.51079493]
    [0.52711097 0.43665451 0.4290048 ]
    [0.47940793 0.3768091  0.78571804]]
    inArr:
    [1.34e+05 5.00e+01 9.00e-01]
    norminArr:
    [1.4681231  2.39013174 0.53049144]
    '''
    classifierResult = classify0(norminArr, normMat, datingLabels, 3) # 進行kNN分類
    print("你可能%s這個人" % (resultList[classifierResult-1])) # 列印分類結果,classifierResult-1,陣列下標從0起

示例:手寫識別系統

準備資料:將影象轉換為測試向量

"""
函式說明:將32*32的二進位制影象轉換成1*1024的向量
Parameters:
    filename - 檔名(路徑)
Returns:
    returnVect - 返回的二進位制影象的1*1024向量
"""
def img2vector(filename):
    returnVect = np.zeros((1, 1024)) # 建立1*1024的零向量,儲存圖片畫素的向量維度是1*1024
    fr = open(filename) # 開啟檔案
    for i in range(32): # 按行讀取
        lineStr = fr.readline() # 讀一行資料
        for j in range(32): # 每一行的前32個數據依次新增到returnVect中
            returnVect[0, 32*i+j] = int(lineStr[j]) # 圖片尺寸是32*32,將其依次放入向量returnVect
    return returnVect # 返回轉換後的1*1024向量

測試演算法:使用 k-近鄰演算法識別手寫數字

程式清單 2-6 手寫數字識別系統的測試程式碼
"""
函式說明:手寫數字分類測試
"""
def handwritingClassTest():
    hwLabels = [] # 測試集Labels
    trainingFileList = listdir(r'D:\dataset\inaction\kNN\trainingDigits') # 匯入訓練集,listdir() 返回指定資料夾名字的列表
    m = len(trainingFileList) # 資料夾下檔案的個數,1934個檔案
#    print(m)
    trainingMat = np.zeros((m, 1024)) # 初始化訓練矩陣
    for i in range(m):
        fileNameStr = trainingFileList[i] # 獲得每個檔案的名字,如 0_0.txt,9_99.txt
#        print(fileNameStr)
        fileStr = fileNameStr.split('.')[0] # 去掉 .txt , 剩下0_0,9_99
#        print(fileStr)
        classNumStr = int(fileStr.split('_')[0]) # 按下劃線‘_’劃分‘0_0’,取第一個元素為類別標籤
        hwLabels.append(classNumStr) # 將獲得的類別新增到hwLabels中
#        print(hwLabels)
        trainingMat[i,:] = img2vector(r'D:\dataset\inaction\kNN\trainingDigits\%s' % fileNameStr) # 將每一個檔案的1*1024資料儲存到trainingMat矩陣中
    testFileList = listdir(r'D:\dataset\inaction\kNN\testDigits') # 測試樣本,返回testDigits目錄下的檔名
    errorCount = 0.0 # 分類錯誤計數
    mTest = len(testFileList) # 測試樣本的個數
    for i in range(mTest):
        fileNameStr = testFileList[i] # 獲得每個檔案的名字,如 0_0.txt
        fileStr = fileNameStr.split('.')[0] # 去掉 .txt , 剩下0_0
        classNumStr = int(fileStr.split('_')[0]) # 按下劃線‘_’劃分‘0_0’,取第一個元素為類別標籤
        vectorUnderTest = img2vector(r'D:\dataset\inaction\kNN\testDigits\%s' % fileNameStr) # 獲得測試集的1*1024向量,用於訓練
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) # 呼叫kNN分類,獲得預測結果
        print("分類返回結果:%d, 真實結果:%d" % (classifierResult, classNumStr)) # 列印分類結果
        if classifierResult != classNumStr:
            errorCount += 1.0 # 分類錯誤個數計數
    print("錯誤總數:%d\n錯誤率:%f%%" % (errorCount, errorCount / float(mTest) * 100)) #列印錯誤個數及錯誤率
        

附所有程式碼:

# -*- coding: utf-8 -*-
"""
Created on Tue Oct  9 09:56:29 2018

@author: YAOTIANLONG
"""
# ------示例1: kNN電影分類 -------------------------------------
import numpy as np
import operator # 匯入運算子模組,sorted排序使用,key=operator.itemgetter(1)
from os import listdir # os.listdir() 方法用於返回指定的資料夾包含的檔案或資料夾的名字的列表
"""
@函式說明: 建立資料集
"""
def createDataSet():
    # 四組二維特徵
    group = np.array([[3,104],[2,100],[101,10],[99,5]])
    # 四組特徵的標籤
    labels = ['愛情片','愛情片','動作片','動作片']
    return group, labels

"""
@函式說明:kNN分類(k近鄰演算法)
Parameters:
	inX - 用於分類的資料(測試集)
	dataSet - 用於訓練的資料(訓練集)
	labels - 類別標籤
	k - 選擇最近鄰居的數目
Returns:
	sortedClassCount[0][0] - 分類結果
"""
def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0] # numpy函式shape[0]返回dataSet的行數,4行
    
    # 歐式距離計算
    # 橫向複製inX共1次,縱向複製inX共dataSize次
#    print(np.tile(inX, (dataSetSize,1)))
    """
    構造相同行數的測試集test
    [[ 10 120]
     [ 10 120]
     [ 10 120]
     [ 10 120]]
    """
    diffMat = np.tile(inX, (dataSetSize,1)) - dataSet # 沿橫向、縱向複製多維陣列
    """
    test:              group:            diffMat:
    [[ 10 120]         [[  3 104]        [[  7  16]
     [ 10 120]   ——     [  2 100]    =    [  8  20]
     [ 10 120]          [101  10]         [-91 110]
     [ 10 120]]         [ 99   5]]        [-89 115]]
    """
#    print(diffMat)
    # 二維特徵相減後平方
    sqDiffMat = diffMat ** 2
#    print(sqDiffMat)
    """
    sqDiffMat(每個元素平方):
    [[   49   256]
     [   64   400]
     [ 8281 12100]
     [ 7921 13225]]
    """
    # sum()將所有元素相加,sum(0)列相加,sum(1)行相加
    sqDistances = sqDiffMat.sum(axis=1)
#    print("sqDistances:\n",sqDistances)
    """
    sqDistances:
    [  305   464 20381 21146]
    """
    # 開方,計算出距離
    distances = sqDistances ** 0.5
#    print(" distances:\n", distances)
    """
    distances(算出來的最終的歐式距離):
    [ 17.4642492   21.54065923 142.76203977 145.41664279]
    """
    sortedDistIndices = distances.argsort() # 返回distances中元素從小到大排序後的索引值
#    print(sortedDistIndices) # [0 1 2 3]
    classCount = {} # 定義記錄類別次數的字典
    for i in range(k):
        voteIlabel = labels[sortedDistIndices[i]] # 取出前K個元素的類別,前3個類別為:愛情片 愛情片 動作片
#        print(voteIlabel)
        #dict.get(key,default=None),字典的get()方法,返回指定鍵的值,如果值不在字典中返回預設值。
		 #計算類別次數
#         print(classCount.get(voteIlabel,0))
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # 沒出現過的返回0再+1就是1次,愛情片(在空字典中沒出現過,+1作為1次)、愛情片(出現過1次,+1是兩次)、動作片(沒出現過,+1作為1次)
#        print(classCount[voteIlabel]) # 愛情片 愛情片 動作片, 1 2 1
#        classCount: {'愛情片': 2, '動作片': 1}
    """
    python內建函式:sorted函式
    sorted(iterable<可迭代物件>, cmp<對函式排序>, key<對元素排序>, reverse<True降序,False升序(預設)>)
    sort 是應用在 list 上的方法,sorted 可以對所有可迭代的物件進行排序操作。
    內建函式 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。
    詳解:http://www.runoob.com/python/python-func-sorted.html
    """
    #python3中用items()替換python2中的iteritems()
	#key=operator.itemgetter(1)根據字典的值value進行排序
	#key=operator.itemgetter(0)根據字典的鍵key進行排序
	#reverse降序排序字典,reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(預設)
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
#    print('sortedClassCount:\n',sortedClassCount)
    """
    sortedClassCount:
    [('愛情片', 2), ('動作片', 1)]
    """
    return sortedClassCount[0][0]
"""
函式說明:測試kNN電影分類
"""
def test0():
    group, labels = createDataSet() # 建立資料集
    print('group:\n',group) # 列印資料集
    print('labels:\n',labels)
    test = [101,20] # 測試集
    test_class = classify0(test, group, labels, 3) # kNN分類
    print(test_class)
    print('"',test,'kNN classify',test_class,'"') # 列印分類結果

# ------示例2: 使用kNN演算法改進約會網站的配對效果 -------------------------------------
"""
函式說明:開啟並解析檔案,對資料進行分類:1代表不喜歡、2代表魅力一般,3代表極具魅力
Parameters:
    filename - 檔名
Return:
    returnMat - 特徵矩陣
    classLabelVector - 分類Label向量
"""
def file2matrix(filename):
    loveDict = {'didntLike':1,'smallDoses':2,'largeDoses':3}
    fr = open(filename) # 開啟檔案
    arrayOlines = fr.readlines() # 逐行讀取
#    print(arrayOlines)
    '''
    arrayOlines:
    ['40920\t8.326976\t0.953952\tlargeDoses\n', '14488\t7.153469\t1.673904\tsmallDoses\n',...,'43757\t7.882601\t1.332446\tlargeDoses\n']
    '''
    numberOfLines = len(arrayOlines) # 得到檔案行數,共1000行資料
#    print(numberOfLines)
    returnMat = np.zeros( (numberOfLines,3) ) # 初始化特徵矩陣,解析完成的資料:numberOfLines行3列
    classLabelVector = [] # 初始化分類標籤向量
    index = 0 # 行的索引值
    for line in arrayOlines:
        # s.strip(rm),當rm空時,預設刪除空白符(包括'\n','\r','\t',' ')
        line = line.strip() # 刪去字串首尾部空字元
#        print(line)
        '''
        如最後兩行line:
        48111   9.134528        0.728045        largeDoses
        43757   7.882601        1.332446        largeDoses
        '''
        # 使用s.split(str="",num=string,cout(str))將字串根據'\t'分隔符進行切片
        listFromLine = line.split('\t') # 按'\t'對字串進行分割,listFromLine是列表
#        print(listFromLine) # 分割成列表
        '''
        如最後兩行listFromLine(列表):
        ['48111', '9.134528', '0.728045', 'largeDoses']
        ['43757', '7.882601', '1.332446', 'largeDoses']
        '''
        returnMat[index,:] = listFromLine[0:3] # 將資料前三列(特徵)一行一行賦值給returnMat
        index += 1
        # 根據文字中標記的喜歡的程度進行分類,1代表不喜歡,2代表魅力一般,3代表極具魅力
        # 讀取的listFromLine的最後一列為類別標籤
        if listFromLine[-1]