原生Python实现KNN算法,并用鸢尾花(iris)数据集测试
用原生python語法實現K近鄰算法,了解K近鄰法的實際操作內核,并用自帶鳶尾花的集合驗證K近鄰算法,并掌握運用散點圖的繪制
先對KNN算法做了解:
源代碼獲取:
https://github.com/akh5/Python/blob/master/My_KNN.ipynb
部分偽代碼:
距離集合distyany2e對應的種類near_y集合For 預測值 in near_y:y0=0,y1=0,y2=0預測結果=0if 預測值 == 0:y0+=1elif 預測值 == 1:y1+=1else:y2+=1if y1>(y2 or y0):預測結果 = 1elif y2>( y1 or y0):預測結果 = 2else:預測結果 = 0結果集合if 預測結果 == 訓練集種類:結果集合.append(1)else:結果集合.append(0)此時結果集合中就只有0,1的元素了
若將 結果集合 中的各個元素相加,再處于集合長度就可以得到精確值
首先來從自帶的包中獲取鳶尾花的數據集
from sklearn.datasets import load_iris import numpy as np import matplotlib.pyplot as plt iris_dataset = load_iris() iris_dataset.keys()dict_keys([‘data’, ‘target’, ‘target_names’, ‘DESCR’, ‘feature_names’, ‘filename’])
輸出的是一個存放數據字典鍵值的list集合
iris_dataset['data'][:150]array([[5.1, 3.5, 1.4, 0.2],
[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2],
[5. , 3.6, 1.4, 0.2],
[5.4, 3.9, 1.7, 0.4],
[4.6, 3.4, 1.4, 0.3],
[5. , 3.4, 1.5, 0.2],
[4.4, 2.9, 1.4, 0.2],
[4.9, 3.1, 1.5, 0.1]])
數組中數據代表花萼長,花萼寬,花瓣長,花瓣寬
iris_dataset['target'][:150]array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
返回的是鳶尾花的種類0為setosa,1為versicolor,2為virginica
from sklearn.datasets import load_iris import numpy as np import matplotlib.pyplot as plt import random raw_x = iris_dataset['data'][:150] # raw_y = iris_dataset['target'][:150]# 原生的鳶尾花數據集X_train = np.array(raw_x) #將鳶尾花數據集添加到 numpy的數組中 作為訓練集 Y_train = np.array(raw_y)#這里為了方便只用了花萼的長,寬作為橫縱坐標 plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='#FF00FF') #紫色點代表setosa plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='#FFFF00') #黃色點代表versicolor plt.scatter(X_train[y_train==2,0],X_train[y_train==2,1],color='#00FFFF') #青色代表virginicaX_test = iris_dataset['data'][random.randint(1,149)] #產生一個隨機的鳶尾花數據作為測試數據 plt.scatter(X_test[0],X_test[1],color='#000000') #將測試數據用黑色添加在圖標中 plt.ylabel('sepal width', fontsize=14) plt.xlabel('sepal length', fontsize=14) plt.show()這里用data數組中的前兩項,也就是花萼的長與寬來作為x_train訓練集,然后給出種類給出y_train訓練集
再從中隨機選出一個值x_test作為測試集
描繪出的散點圖如下?
三種亮色為三種y_train 黑色為測試集
[1.4317821063276357,
1.6124515496597096,
1.7999999999999998,
1.902629759044045,
1.5524174696260025,
1.3038404810405293,
1.9104973174542803,
1.5132745950421556,
2.121320343559642,
1.6031219541881394,
這里給出的是黑點到其他各點的直線距離(未給全)
這里將所有距離放入一個列表,并按順序排列后,找到其位置對應的iris_dataset中的位置
array([110, 51, 115, 137, 104, 147, 116, 56, 144, 75, 100, 124, 140,
65, 86, 136, 77, 145, 143, 58, 74, 148, 112, 103, 54, 120,
128, 132, 52, 141, 139, 97, 127, 91, 133, 50, 126, 76, 63,
111, 85, 138, 123, 73, 71, 78, 70, 61, 102, 149, 125, 83,
134, 72, 146, 108, 129, 109, 114, 95, 96, 107, 101, 67, 142,
82, 99, 55, 92, 88, 66, 87, 64, 130, 121, 18, 79, 94,
36, 68, 113, 14, 105, 31, 84, 20, 119, 62, 69, 90, 10,
135, 89, 122, 81, 80, 48, 5, 16, 28, 27, 117, 118, 53,
59, 23, 33, 39, 17, 0, 15, 21, 35, 49, 7, 25, 26,
46, 44, 19, 131, 43, 40, 4, 98, 32, 34, 9, 1, 37,
30, 11, 45, 24, 12, 106, 93, 57, 2, 29, 47, 3, 6,
60, 22, 42, 38, 8, 41, 13], dtype=int64)
[2, 1, 2, 2, 2]
這里就能從對應位置,找到對應y_train中的值
這樣就能看出黑色位置周圍,哪個種類多,哪個種類少了,最后再用代碼實現返回即可
最后將所有代碼封裝到一塊
import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import load_iris import random import mathiris_dataset = load_iris()raw_x = iris_dataset['data'][:150] # raw_y = iris_dataset['target'][:150]# 原生的鳶尾花數據集X_train = np.array(raw_x) #將鳶尾花數據集添加到 numpy的數組中 作為訓練集 y_train = np.array(raw_y)#這里為了方便只用了花萼的長,寬作為橫縱坐標 plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='#FF00FF') #紫色點代表setosa plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='#FFFF00') #黃色點代表versicolor plt.scatter(X_train[y_train==2,0],X_train[y_train==2,1],color='#00FFFF') #青色代表virginicatest = random.randint(1,149) X_test = iris_dataset['data'][test] #產生一個隨機的鳶尾花數據 plt.scatter(X_test[0],X_test[1],color='#000000') #將測試數據用黑色添加在圖標中 plt.ylabel('sepal width', fontsize=14) plt.xlabel('sepal length', fontsize=14) plt.show() # #原生Python實現KNN過程 # def My_KNN(X_train,y_train,k,test,current_list):#K隨便填寫一個值作為要選取最近點的個數,但只能是奇數方便做判斷distances=[]#for循環找出測試數據與訓練集每一個點的距離for x_train in X_train:d = math.sqrt(np.sum((x_train[0]-X_test[0])**2+(x_train[1]-X_test[1])**2))distances.append(d)nearest = np.argsort(distances) #從小到大排列后返回索引near_y = [y_train[i] for i in nearest[:k]]for vote in near_y: #for循環選出數組中出現次數最多的y值a=0b=0c=0vote_out = 0if vote == 0:a+=1elif vote == 1:b+=1else:c+=1if b>(c or a):vote_out = 1elif c>( b or a):vote_out = 2else:vote_out = 0####### vote_out就是 從鄰近點集中選出最多的點就是預測的鳶尾花種類if vote_out == y_train[test]: #如果預測結果與實際結果相同,在數組中添加1反之為0current_list.append(1)else:current_list.append(0)print(vote_out,y_train[test])這里用循環產生50個測試集,來測試My_KNN()函數
current_list=[] count = 0 k = 5 #####循環生成50個測試集 for i in range(50):count+=1test = random.randint(1,149)X_test = iris_dataset['data'][test]My_KNN(X_train,y_train,k,test,current_list) current_list percent = sum(current_list)/len(current_list) #因為數組內只有0和1 所以數組內元素相加/數組長度就是正確率 print(""" 在抽選{0}組數據中,K為{1},其算法預測的準確度為{2} """.format(count,k,percent))輸出結果為:
“抽選50組數據中,K為5,其算法預測的準確度為0.72”
總結
以上是生活随笔為你收集整理的原生Python实现KNN算法,并用鸢尾花(iris)数据集测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搜索效果和搜索动画效果
- 下一篇: ArrayList源码分析与手写