本系列教程為《機器學習實戰(zhàn)》的讀書筆記。首先,講講寫本系列教程的原因:第一,《機器學習實戰(zhàn)》的代碼由Python2編寫,有些代碼在Python3上運行已會報錯,本教程基于Python3進行代碼的修訂;第二:之前看了一些機器學習的書籍,沒有進行記錄,很快就忘記掉了,通過編寫教程也是一種復習的過程;第三,機器學習相對于爬蟲和數(shù)據(jù)分析而言,學習難度更大,希望通過本系列文字教程,讓讀者在學習機器學習的路上少走彎路。
本系列教程特點:
基于《機器學習實戰(zhàn)》
盡量避免講太多數(shù)學公式,通過簡單直白的方式講解各算法的原理
對于算法實現(xiàn)的代碼進行詳細講解
哪些讀者可以食用:
了解機器學習的基本術(shù)語
會Python語言
會numpy和pandas庫的使用
k-近鄰算法(KNN)原理
KNN算法為分類算法。一句老話來描述KNN算法:“近朱者赤,近墨者黑”。 算法原理:計算測試樣本與每個訓練樣本的距離(距離計算方法見下文),取前k個距離最小的訓練樣本,最后選擇這k個樣本中出現(xiàn)最多的分類,作為測試樣本的分類。 如圖所示,綠色的為測試樣本,當k取3時,該樣本就屬于紅色類;當k取5時,就屬于藍色類了。所以k值的選擇很大程度影響著該算法的結(jié)果,通常k的取值不大于20。
KNN算法原理
介紹完原理后,看看KNN算法的偽代碼流程:
計算測試樣本與所有訓練樣本的距離
對距離進行升序排序,取前k個
計算k個樣本中最多的分類
KNN之約會對象分類
問題描述與數(shù)據(jù)情況
海倫使用約會網(wǎng)站尋找約會對象。經(jīng)過一段時間之后,她發(fā)現(xiàn)曾交往過三種類型的人:
不喜歡的人
魅力一般的人
極具魅力的人
這里海倫收集了1000行數(shù)據(jù),有三個特征:每年獲得的飛行??屠锍虜?shù);玩視頻游戲所耗時間百分比;每周消費的冰淇淋公升數(shù)。以及對象的類型標簽,如圖所示。
數(shù)據(jù)情況
解析數(shù)據(jù)
import numpy as np
import operator
def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines()
numberOflines = len(arrayOLines)
returnMat = np.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 = index + 1
return returnMat, classLabelVector
定義解析數(shù)據(jù)的函數(shù):4-9行:讀取文件,并獲取文件行數(shù),創(chuàng)建一個文件行數(shù)(1000行)和3列的Numpy全0數(shù)組,創(chuàng)建用于存放類標簽的classLabelVector列表。 10-17行:對文件進行循環(huán)遍歷,對前三列數(shù)據(jù)存放到returnMat數(shù)組中,最后一列存放到classLabelVector列表中。結(jié)果如圖所示。
解析數(shù)據(jù)
上面的代碼為書中所寫,其實用pandas讀取數(shù)據(jù)后再出來是很方便了,代碼如下:
import numpy as np
import operator
import pandas as pd
def file2matrix(filename):
data = pd.read_table(open(filename), sep='\t', header=None)
returnMat = data[[0,1,2]].values
classLabelVector = data[3].values
return returnMat, classLabelVector
歸一化
由于特征間的數(shù)值差別太大,在計算距離時,數(shù)值大的屬性會對結(jié)果產(chǎn)生更大的影響,這里需要對數(shù)據(jù)進行歸一化:new = (old-min)/(max-min)。代碼如下:
def autoNorm(dataSet):
minval = dataSet.min(0)
maxval = dataSet.max(0)
ranges = maxval - minval
normDataSet = np.zeros(np.shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - np.tile(minval, (m,1))
normDataSet = normDataSet/np.tile(ranges, (m,1))
return normDataSet, ranges, minval
傳入的參數(shù)為測試數(shù)據(jù)(就是returnMat);首先按0軸(也就是按列)進行min和max的計算,如圖所示進行簡單的示例;然后構(gòu)造和數(shù)據(jù)(normDataSet)一樣大小的0矩陣; tile函數(shù)的用法讀者可以自行百度,這里看下使用后的案例,作用就是讓一維數(shù)組重復m行,如圖所示,這樣就可以進行數(shù)據(jù)歸一化的計算。
示例
示例
結(jié)果
KNN算法
這里使用的距離為歐式距離,公式為:
歐式距離
def classify(inX, dataSet, labels, k):
dataSize = dataSet.shape[0]
diffMat = np.tile(inX, (dataSize,1)) -dataSet
sqdiffMat = diffMat ** 2
sqDistance = sqdiffMat.sum(axis = 1)
distances = sqDistance ** 0.5
sortedDist = distances.argsort()
classCount ={}
for i in range(k):
voteIlable = labels[sortedDist[i]]
classCount[voteIlable] = classCount.get(voteIlable, 0) + 1
sortedClassCount = sorted(classCount.items(),
key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
inX為訓練數(shù)據(jù);dataSet為測試數(shù)據(jù),labels為類別標簽;k為取值; 2-6行:計算歐式距離; 7-最后:對計算的距離進行索引排序(argsort),然后對字典進行排序,獲取值最多的分類。
對分類器進行測試
這里選擇前10%數(shù)據(jù)做為測試樣本,進行分類器的測試。
def test():
r = 0.1
X, y = file2matrix('數(shù)據(jù)/datingTestSet2.txt')
new_X, ranges, minval = autoNorm(X)
m = new_X.shape[0]
numTestVecs = int(m*r)
error = 0.0
for i in range(numTestVecs):
result = classify(new_X[i, :],new_X[numTestVecs:m, :], y[numTestVecs:m], 3)
print('分類結(jié)果: %d, 真實數(shù)據(jù): %d' %(result, y[i]))
if (result != y[i]):
error = error + 1.0
print('錯誤率: %f' % (error/float(numTestVecs)))
結(jié)果
測試系統(tǒng)
最后,編寫一個簡單的測試系統(tǒng),該代碼通過人為的輸入三個屬性特征,可以自動得到該約會對象的分類標簽。
def system():
style = ['不喜歡', '一般', '喜歡']
ffmile = float(input('飛行里程'))
game = float(input('游戲'))
ice = float(input('冰淇淋'))
X, y = file2matrix('數(shù)據(jù)/datingTestSet2.txt')
new_X, ranges, minval = autoNorm(X)
inArr = np.array([ffmile, game, ice])
result = classify((inArr - minval)/ranges, new_X, y, 3)
print('這個人', style[result - 1])
結(jié)果
算法優(yōu)缺點
優(yōu)點:精度高,對異常值不敏感
缺點:計算復雜(想想每個測試樣本都要與訓練樣本繼續(xù)距離計算)
作者:羅羅攀,Python中文社區(qū)專欄作者,《從零開始學網(wǎng)絡爬蟲》圖書作者。專欄地址: http://www.jianshu.com/u/9104ebf5e177
Python中文社區(qū)作為一個去中心化的全球技術(shù)社區(qū),以成為全球20萬Python中文開發(fā)者的精神部落為愿景,目前覆蓋各大主流媒體和協(xié)作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業(yè)界知名公司和技術(shù)社區(qū)建立了廣泛的聯(lián)系,擁有來自十多個國家和地區(qū)數(shù)萬名登記會員,會員來自以公安部、工信部、清華大學、北京大學、北京郵電大學、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機關(guān)、科研單位、金融機構(gòu)以及海內(nèi)外知名公司,全平臺近20萬開發(fā)者關(guān)注。
聯(lián)系客服