機器學習實戰之使用k-鄰近演算法改進約會網站的配對效果
1 準備資料,從文字檔案中解析資料
用到的資料是機器學習實戰書中datingTextSet2.txt
程式碼如下:
from numpy import * def file2matrix(filname): fr=open(filname) arrayOLines=fr.readlines() numberOfLines=len(arrayOLines) returnMat=zeros((numberOfLines,3)) classLabelVector=[] index=0 for line in arrayOLines: line=line.strip() listFromLine=line.split('\t') returnMat[index:]=listFromLine[0:3] classLabelVector.append(int(listFromLine[-1])) index+=1
return returnMat, classLabelVector在這要簡單介紹幾個函式的應用:
1).readlines()y一次性讀取整個檔案,自動將檔案內容分析成一個行的列表,該列表可以由 python 的 for... in ... 結構進行處理
.readline() 每次只讀取一行,通常比 .readlines() 慢得多。僅當沒有足夠記憶體可以一次讀取整個檔案時,才應該使用 它
.read() 每次讀取整個檔案,它通常用於將檔案內容放到一個字串變數中。然而 .read() 生成檔案內容最直接的字串表 示,但對於連續的面向行的處理,它卻是不必要的,並且如果檔案大於可用記憶體,則不可能實現這種處理。
2).strip(),本程式碼中實現的是擷取掉所有的回車字元
首先使用函式.strip擷取掉所有的回車字元,然後使用'\t'字元將上一步得到的整行資料分割成一個元素列表。接著,我們選取前3個元素,將它們儲存到特徵矩陣中。python語言可以使用索引值-1表示列表中的最後一列元素,利用這種負索引,我們可以很方便地將列表的最後一列儲存到向量classLabelVector中。需要注意的是,我們必須明確地通知直譯器,告訴它列表中儲存的元素值為整型,否則會將這些元素當作字串處理。
我們成功匯入了datingTestSet2.txt
2 分析資料:使用Matplotlib常見散點圖
我們用散點圖進行視覺化
在上述程式碼中加下面程式碼:
from numpy import * import matplotlib import matplotlib.pyplot as plt datingDataMat,datingLabels=file2matrix('E:\PythonProject\machineL\Ch02\datingTestSet2.txt') fig=plt.figure() ax=fig.add_subplot(111) ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels)) plt.xlabel(u'玩視訊遊戲所佔時間百分比', fontproperties='SimHei') plt.ylabel(u'每週消費冰淇淋公升數', fontproperties='SimHei') plt.show()注意:在加x,y軸標註時 一定要加上fontproperties='SimHei',這樣中文才能正常顯示。
結果如圖:
很清楚的可以看出,分為三類;分別是黃色部分、紫色部分和藍色部分,
我們是顯示了第二列和第一列的屬性,但如果我們顯示的是第二列和第三列屬性的話,效果遠不如此:
從圖中我們很難進行分類,比較分散。
3 資料準備:歸一化數值
def autoNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals, (m, 1)) normDataSet = normDataSet / tile(ranges, (m, 1)) # element wise divide return normDataSet, ranges, minVals4 測試演算法
def datingClassTest(): hoRatio = 0.50 # hold out 10% datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') # load data setfrom file normMat, ranges, minVals = autoNorm(datingDataMat) m = normMat.shape[0] numTestVecs = int(m * hoRatio) errorCount = 0.0 for i in range(numTestVecs): classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]) if (classifierResult != datingLabels[i]): errorCount += 1.0 print "the total error rate is: %f" % (errorCount / float(numTestVecs)) print errorCount
5 使用演算法
def classifyPerson(): resultList=['not at all','in small doses','in large doses'] percentTats=float(raw_input("percent games?")) ffMiles=float(raw_input("frequent flier miles?")) iceCream=float(raw_input("liters of ice cream per year?")) datingDataMat,datingLabels=file2matrix('E:\PythonProject\machineL\Ch02\datingTestSet2.txt') normMat,ranges,minVals=autoNorm(datingDataMat) inArr=array([ffMiles,percentTats,iceCream]) classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3) print "you will like this person",resultList[classifierResult-1]
結果: