# -*- coding: UTF-8 -*-
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
""" 產生高斯隨機數據作爲樣本數據集
Parameters
----------
mean : 高斯均值
sigma : 高斯函數方差
count: 要產生的數據個數
----------
return : 產生的數據列表
"""
def GaussNum(mean,sigma,count):
res = [0] * count
for i in range(count):
res[i] = random.gauss(mean,sigma)
return res
""" 計算點與點之間的距離,這裏裏二維數據爲例
Parameters
----------
inX : 測試樣本,數組
x : x
y: y
----------
return : 測試樣本與(x,y)的距離
"""
def Distance_for_dot(inX,x,y):
size = len(inX)
sum = 0
for i in range(size):
sum += ((inX[0] - x) ** 2 + (inX[1] - y) ** 2)
return sum ** 0.5
""" knn分類
Parameters
----------
inX : 測試樣本,數組
x : x
y: y
labels: 數據樣本標籤
k: knn中k值,爲選取最近點的數量
----------
return : inX被判定的劃分類
"""
def knn_Classify(inX,x,y,labels,k):
# 計算樣本數據的個數
dataSetSize = len(x)
# 建立數組,用來存放測試數據與每個樣本數據的距離
distances_for_eachSample = [0] * dataSetSize
# print(type(distances_for_eachSample))
# 數據與標籤dict,key值爲距離,value值爲該樣本數據的類別,這裏假設所有距離都不相等
data_and_label = {}
# 對於樣本數據集,一次求距離,並且與自己的類別合併,存入data_and_label
for i in range(dataSetSize):
distances_for_eachSample[i] = Distance_for_dot(inX,x[i],y[i])
data_and_label[distances_for_eachSample[i]] = labels[i]
# 這裏排序完成後,data_and_labels變爲list型
# 按鍵值對(key)排序
data_and_label = sorted(data_and_label.items(),key = lambda d:d[0])
print(len(data_and_label))
# print((data_and_label))
# res 保持最近K個樣本數據,按照類別進行個數統計。key值爲類別,value值爲此類別個數統計
res = {}
for i in range(k):
if (res.__contains__(data_and_label[i][1])):
# print(data_and_label[i][1])
res[data_and_label[i][1]] += 1
else:
res[data_and_label[i][1]] = 1
# 對res 按照value值排序
res = sorted(res.items(),key = lambda d:d[1],reverse = True)
print(res)
draw_point(inX,res[0][0])
print("the result is : %s" %res[0][0])
def draw_point(inX,color):
plt.scatter(inX[0],inX[1],c=color,marker='*',s=400,alpha=0.8)
# 產生訓練數據集,在數據集中自動分爲三類,並且畫出圖
def data_generate():
x1 = GaussNum(15,7,200)
y1 = GaussNum(20,7,200)
x2 = GaussNum(30,7,200)
y2 = GaussNum(50,8,200)
x3 = GaussNum(5,7,200)
y3 = GaussNum(40,7,200)
plt.scatter(x1,y1,c='b',marker='s',s=50,alpha=0.8)
plt.scatter(x2,y2,c='k',marker='^',s=50,alpha=0.8)
plt.scatter(x3,y3,c='r',marker='o',s=50,alpha=0.8)
# 這裏list可以直接用 + 合併
x = x1 + x2 + x3
y = y1 + y2 + y3
labels = ["blue"]*200+["black"]*200+["red"]*200
return x,y,labels
if __name__ == '__main__':
x,y,labels = data_generate()
for i in range(3):
knn_Classify([20 - (i-1) * 10,40 - (i-1) * 10 ],x,y,labels,20)
plt.show()
運行結果: