爲了讓絕大多數人均可以看懂,因此我就用簡單的話語來說解機器學習每個算法php
第一次寫ML的博文,因此可能會有些地方出錯,歡迎各位大佬提出意見或錯誤python
祝你們開心進步每一天~算法
博文代碼所有爲python機器學習
簡單的說一下什麼是機器學習,機器學習英文名稱是Machine Learning, MLide
KNN(k-Nearest Neighbor)中文名爲K近鄰,是分類算法的一種,KNN的思路爲在在數據和標籤已知的狀況下將測試數據的特徵和訓練集中的特徵進行比較,找到與之最類似的k的數據,那麼這個數據對應的類別就是k個數據中出現次數最多的那個類別函數
尋找類似度有多重方法,最經常使用的爲歐幾里得度量,皮爾遜相關係數,餘弦類似度性能
算法流程大體分爲 學習
本文使用iris數據集,可從UCI處下載 傳送門測試
使用py的三種庫pandas,numpy,sklearnidea
查看數據集
前4列爲特徵,最後一列爲標籤
1 #獲取數據 2 X=np.loadtxt("/Users/galan/py/ML-D/iris.data.txt",delimiter=",",dtype=float,usecols=(0,1,2,3)) 3 y=np.loadtxt("/Users/galan/py/ML-D/iris.data.txt",delimiter=",",dtype=str,usecols=(4,)) 4 #建立訓練數據和測試數據 5 X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=.7)
第2,3行爲獲取特徵和標籤
第五行中使用sklearn庫的train_test_split函數,用來方便分隔測試集和訓練集
本文使用歐幾里得度量算法,在下方也會列出皮爾遜類似性和餘弦類似度的py代碼
歐幾里得度量多爲計算空間中兩點間的距離
def eculidean(p,q): sumSq=0.0 #講差值德平方累加起來 for i in range(len(p)): sumSq+=sum(p[i]-q[i])**2 #求平方根 return (sumSq**0.5)
皮爾遜相關係數是度量兩個變量之間相關程度,介於-1和1之間,1表明變量徹底正相關,0表明無關,-1表明徹底負關係
def pearson(x,y): n=len(x) vals=range(n) #簡單求和 sumx=sum([float(x[i]) for i in vals]) sumy=sum([float(y[i]) for i in vals]) #求平方和 sumxSq=sum([x[i]**2.0 for i in vals]) sumySq=sum([y[i]**2.0 for i in vals]) #求乘積之和 pSum=sum([x[i]*y[i] for i in vals]) #計算皮爾遜評價值 num=pSum-(sumx*sumy/n) den=((sumxSq-pow(sumx,2)/n)*(sumySq-pow(sumy,2)/n))**.5 if den==0:return 1 r=num/den return r
餘弦類似度將向量根據座標值,繪製到向量空間中求得他們的夾角,並得出夾角對應的餘弦值,夾角越小,餘弦值越接近於1,它們的方向更加吻合,則越類似。
#vect1,vect2位兩個一維向量如(1,1) def getCost(vect1,vect2): sum_x=0.0 sum_y=0.0 sum_xy=0.0 for a,b in zip(vect1,vect2): sum_xy+=a*b sum_x+=a**2 sum_y+=b**2 if sum_x==0.0 or sum_y==0.0: return None else: return sum_xy/((sum_x*sum_y)**0.5)
knn的求證過程
#K值 k=5 #計算全部的歐氏距離組合成字典 Dists={} for i in range(len(X_train)): Dists[eculidean(X_test[0],X_train[i])]=y_train[i] #排序字典 sortedDist=sorted(Dists.iteritems(),reverse=True,key=lambda x:x[0])[:k] classCount={} #尋找最多的類別標籤 for i in sortedDist: if i[1] in classCount: classCount[i[1]]+=1 else: classCount[i[1]]=1 print classCount
下面貼出全部的代碼
#coding:utf-8 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split #獲取數據 X=np.loadtxt("./ML-D/iris.data.txt",delimiter=",",dtype=float,usecols=(0,1,2,3)) y=np.loadtxt("./ML-D/iris.data.txt",delimiter=",",dtype=str,usecols=(4,)) #建立訓練數據和測試數據 X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=.7) def eculidean(p,q): sumSq=0.0 #講差值德平方累加起來 for i in range(len(p)): sumSq+=sum(p-q[i])**2 #求平方根 return (sumSq**0.5) def classify(X_train,X_test,k): #計算全部的歐氏距離 Dists={} for i in range(len(X_train)): Dists[eculidean(X_test,X_train[i])]=y_train[i] #排序字典 sortedDist=sorted(Dists.iteritems(),reverse=True,key=lambda x:x[0])[:k] classCount={} #尋找最多的類別標籤 for i in sortedDist: if i[1] in classCount: classCount[i[1]]+=1 else: classCount[i[1]]=1 return sorted(classCount.iteritems(),key=lambda x:x[1],reverse=True) if __name__ == '__main__': print "%s的類別爲%s"%(X_test[15],classify(X_train,X_test[0],5)[0][0])
我會每週更新一篇ML博文,方便你們學習,^_^ 共同窗習共同提升,歡迎你們前來對個人文章提出寶貴意見
祝你們週末愉快~