1.KNN简介.
KNN(K-最近邻)算法是一种常用的基于实例的监督学习算法,用于分类和回归任务。在统计学习方法中,KNN算法属于一类称为“基于实例的学习”或“懒惰学习”(lazy learning)的算法。这种算法不需要显式地训练模型,而是在预测阶段根据训练数据进行实时计算。
KNN算法的基本思想是:对于一个新的输入样本,找到训练数据中与该样本最相似的k个邻居(通常使用欧氏距离或其他距离度量方法来衡量相似性),然后根据这k个邻居的标签来进行分类(对于分类问题)或回归(对于回归问题)。
KNN算法的模型策略如下:
1. 输入:训练样本集D = {(x1, y1), (x2, y2), ..., (xn, yn)},其中xi为样本特征,yi为样本标签;待预测样本x。
2. 计算输入样本x与训练样本集中所有样本xi之间的距离(通常使用欧氏距离等)。
3. 根据距离找到与输入样本x最近的k个训练样本,这些样本构成了x的k近邻。
4. 对于分类任务:根据k个近邻的标签,通过投票或权重投票的方式来确定输入样本x的类别。
对于回归任务:根据k个近邻的标签,通过平均或加权平均的方式来确定输入样本x的输出值。
5. 返回预测结果。
KNN算法的特点:
- 优点:简单易懂,易于实现,对于训练数据没有显式训练过程,适用于多分类和回归任务。
- 缺点:对于大规模数据集,计算复杂度较高,预测速度可能较慢。在特征空间维度较高的情况下,可能出现维度灾难,影响算法效果。对于不平衡的数据集和噪声较多的数据集,可能会导致预测结果不稳定。
在实际应用中,KNN算法可以通过调整k值来控制近邻的数量,从而影响算法的预测结果。较小的k值可以使模型更加灵敏,但容易受到噪声的影响;较大的k值可以降低噪声的影响,但可能忽略了样本之间的局部特征。
总结来说,KNN算法是一种简单而直观的分类和回归方法,适用于一些简单的问题或作为其他更复杂算法的基准。在实践中,我们通常使用距离加权KNN(distance-weighted KNN)或改进的KNN算法来提高算法性能,并结合特征选择、距离度量优化等技术来处理实际问题。
2.KNN1(Python).
代码实现的主要思想:
1. 计算测试集到训练集样本的距离;
2. 找出前k个点的多数y即作为该测试集的预测值.
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split
""" KNN """
class KNN():
def __init__(self, X_train, y_train, X_test, k):
self.X_train = X_train
self.y_train = y_train
self.X_test = X_test
self.k = k
def euclidean_distance(self, point1, point2):
return np.sqrt(np.sum((point1 - point2) ** 2))
def predict(self):
y_pred = []
for test_point in X_test:
distances = [self.euclidean_distance(test_point, train_point) for train_point in self.X_train]
k_nearest_indices = np.argsort(distances)[:self.k]
k_nearest_labels = [self.y_train[i] for i in k_nearest_indices]
counts = np.bincount(k_nearest_labels)
predicted_label = np.argmax(counts)
y_pred.append(predicted_label)
return y_pred
def score(self, y_pred, y_test):
return 1 - np.count_nonzero(y_test-y_pred)/len(y_test)
if __name__ == '__main__':
# 数据集.
X, y = datasets.load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# KNN.
knn = KNN(X_train, y_train, X_test, k=3)
y_pred = knn.predict()
print('Predict Values:', y_pred)
pred_score = knn.score(y_pred, y_test)
print("Predict Score:", pred_score)
3.KNN2(Python).
第一个代码更加简洁, 第二个代码主要参考以下文章,里面还加了kd树的实现, 感兴趣的可以去看他的代码,kd树概念不了解的同学可以去看学生视频-KD树_哔哩哔哩_bilibili这个视频讲的非常清楚K近邻(KNN)算法及python实现(含Kd树实现)_rosefunR的博客-优快云博客
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split
X, y = datasets.load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# my k-NN
class KNN():
def __init__(self,data,K=3):
self.X = data[0]
self.y = data[1]
self.K = K
def fit(self, X_test):
diffX = np.repeat(X_test, len(self.X), axis=0) - np.tile(self.X,(len(X_test),1))
square_diffX = (diffX**2).sum(axis=1).reshape(len(X_test),len(self.X))
sorted_index = square_diffX.argsort()
predict = [0 for _ in range(len(X_test))]
for i in range(len(X_test)):
class_count={}
for j in range(self.K):
vote_label = self.y[sorted_index[i][j]]
class_count[vote_label] = class_count.get(vote_label,0) + 1
sorted_count = sorted(class_count.items(), key=lambda x: x[1],reverse=True)
predict[i] = sorted_count[0][0]
return predict
def predict(self, X_test):
return self.fit(X_test)
def score(self,X,y):
y_pred = self.predict(X)
return 1 - np.count_nonzero(y-y_pred)/len(y)
knn = KNN((X_train,y_train), K=3)
print('KNN1准确率: ', knn.score(X_test,y_test))
4.结果展示.
两种方法的准确率相同.