K-NN(k-nearest neighbor)是一种基本分类与回归的方法,没有训练过程。
分类;
模型:利用训练数据集对特征向量空间进行划分
策略:惰性学习,应该是没有优化策略的
算法:略
k近邻的三个基本要素:k的选择,距离度量,分类决策规则(多数表决规则等价于经验风险最小)
优点:
简单好用,容易理解,精度高,理论成熟,既可以用来做分类也可以用来做回归;
可用于数值型数据和离散型数据;
训练时间复杂度为O(n);无数据输入假定;
对异常值不敏感。
缺点:
数据量大,特征维度大的计算复杂度会很高(kd树存储结构),计算复杂性高;空间复杂性高;
样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);
一般数值很大的时候不用这个,计算量太大。但是单个样本又不能太少,否则容易发生误分。
最大的缺点是无法给出数据的内在含义。
##K-NN实现
##使用欧氏距离,多数投票决策机制
from sklearn.datasets import load_iris
import random
import heapq
iris = load_iris()
import numpy as np
def Preprocessing():
testset=[]
test_labels=[]
trainset=[]
train_labels=[]
datas=iris.data[:,0:3]
label=iris.target
test_list=np.sort([random.randint(0,149) for _ in range(10)])
for i in range(150):
if i in test_list:
testset.append(datas[i])
test_labels.append(label[i])
else:
trainset.append(datas[i])
train_labels.append(label[i])
testset=np.mat(testset)
test_labels=np.mat(test_labels).transpose()
trainset = np.mat(trainset)
train_labels = np.mat(train_labels).transpose()
return testset, test_labels, trainset, train_labels
# def train(X_train,Y_train,k):
#
#
#
# # def distance(x1,x2):
# # m,n=np.shape(x1)
# # result=0
# # for i in range(n):
# # result+=(x1[i]-x2[i])**2
# # return result**0.5
def Predict(testset,trainset,train_labels,n):
predict=[]
k=n
for test_vec in testset:
dist_list=[]
knn_list=[]
for i in range(len(train_labels)):
label=train_labels[i]
train_vec=trainset[i]
print(train_vec-test_vec)
dist=np.linalg.norm(train_vec-test_vec)
dist_list.append((dist,label))
knn_list=heapq.nsmallest(k,dist_list,key=lambda x:x[0])
class_total=3
class_count=[0 for i in range(class_total)]
for dist,label in knn_list:
label=label.tolist()
class_count[label[0][0]]+=1
mmax=max(class_count)
for i in range(class_total):
if mmax==class_count[i]:
predict.append(i)
break
return predict
def main():
k=10
testset,test_labels,trainset,train_labels=Preprocessing()
predict=Predict(testset,trainset,train_labels,k)
test_labels=test_labels.tolist()
error_count=0
for i in range(10):
print("testset:", test_labels[i][0], "predict:", predict[i])
if test_labels[i][0] != predict[i]:
error_count += 1
print("error_count:", error_count)
if __name__ == '__main__':
main()