1. 程式人生 > >資料分析師養成之路之python:從頭學習機器學習(KNN_1)

資料分析師養成之路之python:從頭學習機器學習(KNN_1)

實現kNN分類演算法:
快速理解kNN分類演算法:
這裡寫圖片描述
如上圖,綠色圓即為我們要預測的樣本,K=3時,即距離綠色圓最近的3個樣本(最內圈內)
中,2個紅色三角,1個藍色方框,2>1,所以我們判定綠色圓為紅色三角
演算法:[距離–排序–取k–求概率–選類別]
1.計算要預測的樣本點 和 其他點的距離(已知類別)
2.得到的距離按照從小到大排序
3.選出最小的k個點
4.在這k個點中,計算其類別出現的概率
5.找到概率最高的類別,即作為我們要預測的樣本點 的類別

from numpy import *
import operator
#訓練資料集, group,labels
group = array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]]) labels = ['A', 'A', 'B', 'B'] #預測資料 intX=[0.1,0.3] # tile(intX,[4,1]) 為把預測資料變為和訓練資料group一樣的維度,便於進行計算 ,這裡求差 # 4行2列,每一行是x,和y,這裡每一列計算(x1-x2),(y1-y2) diffMat=tile(intX,[4,1])-group # 求平方 即 每一列計算 (x1-x2)**2,(y1-y2)**2 sqdistance=diffMat**2 # 取距離,即( (x1-x2)**2+(y1-y2)**2)--維度變為4行1列
distance=sqdistance.sum(axis=1) # 開根號 distance=distance **0.5 # 從小到大排序,並取每個的位置( disArg中存放的是distance從小到大的位置) disArg=distance.argsort() classCount={} # k取3,即找距離最近的3個樣本點 for i in range(3): # 這3個樣本點的類別 voteLabel=labels[disArg[i]] # 對該樣本點的類別數目進行統計 classCount[voteLabel]=classCount.get(voteLabel,0)+1
# 對統計數目從大到小排序 sortedClasscount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) # 取最大的值所在的類別 print(sortedClasscount[0][0])

以上距離 使用歐式距離公式,計算兩點間距離
sklearn的實現

from sklearn.neighbors import KNeighborsClassifier 
# k=3
knn=KNeighborsClassifier(n_neighbors=3) 
knn.fit(group,labels)
# 注意,這裡的維度, expected 2D array 而intX是1D array,所以,需要[intX]變為2維
knn.predict([intX])

為便於理解,再實現一個栗子:

from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
import operator
from numpy import *
import numpy as np

# load dataset
iris=datasets.load_iris()
data_X=iris.data
data_y=iris.target

# normalize  (oldValues-min)/(max-min)
minVals=data_X.min(0)
maxVals=data_X.max(0)
ranges=maxVals-minVals
# oldValues-min(同緯度相減)
normDataSet=data_X-tile(minVals,(m,1))
# normDataSet/(max-min)
normDataSet=normDataSet/tile(ranges,(m,1))

#資料集劃分
index0=np.random.permutation(len(normDataSet))
train_data=normDataSet[index0[:-50]]
test_data=normDataSet[index0[-50:]]
y_train=data_y[index0[:-50]]
y_test=data_y[index0[-50:]]

# 用於分類 
def Classify(m,train_data,y_train):
    distance=(m-train_data)**2
    distance=distance.sum(axis=1)
    sdistance=distance**0.5
    sortDistance=sdistance.argsort()
    classCount={}
    for i in range(10):
        votelabel=y_train[sortDistance[i]]
        classCount[votelabel]=classCount.get(votelabel,0)+1
    sortClasscount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortClasscount[0][0]

# 對測試集資料進行分類並進行驗證
errorCount=0
for x in range(len(test_data)):
    m=test_data[x,:]
    y_pre=Classify(m,train_data,y_train)

    if y_pre!=y_test[x]:
        errorCount+=1.0
print('錯誤率是:%f'%(errorCount/float(len(test_data))))


sklearn 實現以上操作

from sklearn.neighbors import KNeighborsClassifier 
# k=5
knn=KNeighborsClassifier(n_neighbors=5) 
knn.fit(train_data,y_train)
knn.score(test_data,y_test,sample_weight=None)

k-近鄰演算法小結:
優點:
- 精度高,對異常值不敏感
缺點:
-計算複雜度高,空間複雜度高
適用資料範圍:
- 數值型,標稱型