classKNN:def__init__(self,k):"""初始化 """
self.k=k
deffit(self,X,y):"""训练方法
X:类数组类型(二维) 待训练的样本特征(属性)
y:(一维) 样本的目标值(标签)"""
self.X=np.asarray(X)#转化为ndarray数组类型
self.y=np.asarray(y)defpredict(self,X):
X=np.asarray(X)
result=[]for x in X:#对于测试集中的每一个样本,依次与训练集中的所有样本求距离
dis=np.sqrt(np.sum((x-self.X)**2,axis=1))#返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
index=dis.argsort()#只取前K个
index=index[:self.k]#返回数组中每个元素出现的次数。元素必须是非负整数。
count=np.bincount(self.y[index])#返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
result.append(count.argmax())return np.asarray(result)defpredict2(self,X):#考虑权重,权重为距离的倒数。
X=np.asarray(X)
result=[]for x in X:#对于测试集中的每一个样本,依次与训练集中的所有样本求距离
dis=np.sqrt(np.sum((x-self.X)**2,axis=1))#返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
index=dis.argsort()#只取前K个
index=index[:self.k]#返回数组中每个元素出现的次数。元素必须是非负整数。
count=np.bincount(self.y[index],weights=1/dis[index])#返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
result.append(count.argmax())return np.asarray(result)
2. KNN回归
classKNN:"""该算法用于回归预测,用数据集的前三个特征属性,寻找最近的K个邻居,
然后再根据k个邻居的第四个特征属性,去预测当前样本的第四个特征属性"""def__init__(self,k):
self.k=k
deffit(self,X,y):
self.X=np.asarray(X)
self.y=np.asarray(y)defpredict(self,X):
X=np.asarray(X)
result=[]for x in X:#计算与训练集中每个X的距离
dis=np.sqrt(np.sum((x-self.X)**2,axis=1))#取前k个
index=dis.argsort()
index=index[:self.k]#计算前k个的值,取均值返回到结果列表中
result.append(np.mean(self.y[index]))return np.array(result)defpredict2(self,X):#考虑权重:权重=(1/每个邻居的距离)/所有的距离倒数之和
X=np.asarray(X)
result=[]for x in X:#计算与训练集中每个X的距离
dis=np.sqrt(np.sum((x-self.X)**2,axis=1))#取前k个
index=dis.argsort()
index=index[:self.k]#计算所有邻居节点的距离倒数之和。注意:加上0.0001是为了防止距离为0使得分母为0
s=np.sum(1/(dis[index]+0.0001))#求权重:每个距离的倒数/倒数之和
weight=(1/(dis[index]+0.0001))/s
#使用邻居节点的标签值*权重,然后进行累加求和,得到预测值
result.append(np.sum(self.y[index]*weight))return np.array(result)
3. 对比之前写的KNN算法
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from collections import Counter
from math import sqrt
classKNNClassfier:def__init__(self,k):""""初始化KNN分类器"""assert k>=1,"k must be valid"
self.k=k
self._x_train=None
self._y_train=Nonedeffit(self,x_train,y_train):assert x_train.shape[0]==y_train.shape[0],"the size must equal"assert self.k<=x_train.shape[0]
self._x_train=x_train
self._y_train=y_train
return self
defpredict(self,x_predict):assert self._x_train isnotNoneand self._y_train isnotNone,"must fit before predict!"assert x_predict.shape[1]==self._x_train.shape[1],"the size must equal"
y_predict=[self._predict(x)for x in x_predict]return np.array(y_predict)def_predict(self,x):assert x.shape[0]==self._x_train.shape[1],"must equal!"
distances =[sqrt(np.sum((x_train - x)**2))for x_train in self._x_train]
nearest = np.argsort(distances)
topK_y =[self._y_train[i]for i in nearest[:self.k]]
votes = Counter(topK_y)
predict_y = votes.most_common(1)[0][0]return predict_y