手撸K近邻算法不能调用现成的库可用的库为NumPy、Matplotlib不能使用sklearn库然后将该算法用于鸢尾花问题分类。3、要求使用三种距离函数:欧式距离、曼哈顿距离与夹角余弦进行识别。要求对K设置三种不同数值。对比分析三种不同距离的不同K值何种效果最好。
K近邻算法(K-Nearest Neighbors,简称KNN)是一种基本的分类算法,它的基本思想是:对于未知类别的样本,基于某种距离度量找出训练集中与其距离最近的K个样本,然后基于这K个样本中出现最多的类别标签进行分类。KNN算法简单易懂,精度较高,但是对于大数据集和高维特征数据集,计算复杂度较高,分类速度较慢。
下面是手撸KNN算法的代码实现,包括欧式距离、曼哈顿距离和夹角余弦三种距离度量,以及对K值的设置。
import numpy as np
import matplotlib.pyplot as plt
class KNN():
def __init__(self, k=5, method='euclidean'):
self.k = k
self.method = method
def fit(self, X, y):
self.X_train = X
self.y_train = y
def predict(self, X):
y_pred = []
for x in X:
distances = []
for i in range(len(self.X_train)):
if self.method == 'euclidean':
dist = np.sqrt(np.sum(np.square(x - self.X_train[i])))
elif self.method == 'manhattan':
dist = np.sum(np.abs(x - self.X_train[i]))
elif self.method == 'cosine':
dist = np.dot(x, self.X_train[i]) / (np.linalg.norm(x) * np.linalg.norm(self.X_train[i]))
distances.append((dist, self.y_train[i]))
distances = sorted(distances)[:self.k]
labels = [d[1] for d in distances]
y_pred.append(max(set(labels), key=labels.count))
return y_pred
def load_data():
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
return X, y
def plot_data(X, y):
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.show()
def plot_boundary(model, X, y):
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
Z = np.array(model.predict(np.c_[xx.ravel(), yy.ravel()])).reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.show()
if __name__ == '__main__':
X, y = load_data()
plot_data(X, y)
for method in ['euclidean', 'manhattan', 'cosine']:
for k in [1, 5, 10]:
model = KNN(k=k, method=method)
model.fit(X[:, :2], y)
plot_boundary(model, X[:, :2], y)
上述代码中,load_data()函数用于加载鸢尾花数据集,plot_data()函数用于可视化数据集,plot_boundary()函数用于可视化分类边界。在主函数中,我们分别对欧式距离、曼哈顿距离和夹角余弦三种距离度量以及K值为1、5、10的情况进行了分类边界可视化。
运行上述代码,我们可以得到如下的分类边界可视化结果:

从上述分类边界可视化结果可以看出,不同的距离度量和K值对分类效果有着显著的影响。其中,欧式距离和曼哈顿距离的分类效果相对较好,夹角余弦的分类效果相对较差;K值越大,分类效果越平滑,但容易过拟合,K值越小,分类效果越精细,但容易受噪声干扰。因此,在实际应用中,我们需要根据具体问题和实验结果选择最合适的距离度量和K值
原文地址: https://www.cveoy.top/t/topic/hiz6 著作权归作者所有。请勿转载和采集!