k-近邻法

k-近邻法概述

算法概述

工作原理:

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前&个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

k-近邻算法的一般流程

1
2

从文本文件中解析数据

k-近邻算法:
算法python代码
预测[0,0]所在分类:
预测分类

测试分类器

为了测试分类器的效果,我们可以使用已知答案的数据,当然答案不能告诉分类器,检验分类器给出的结果是否符合预期结果。通过大量的测试数据,我们可以得到分类器的错误率—分类器给出错误结果的次数除以测试执行的总数。错误率是常用的评估方法,主要用于评估分类器在某个数据集上的执行效果。完美分类器的错误率为0,最差分类器的错误率是1.0,在这种情况下,分类器根本就无法找到一个正确答案。

示例:使用k-近邻算法改进约会网站的配对效果

1
2

准备数据:从文本中解析数据

文本内容转化为矩阵
运行结果

数据准备:归一化数值

计算样本之间距离时,数字差值最大的属性对计算结果的影响最大,所以在处理不同取值范围的特征值时,我们通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。下面的公式可以将任意取值范围的特征值转化为0到1区间内的值:newValue={oldValue-min)/(max-min)。其中min和max分别是数据集中的最小特征值和最大特征值。虽然改变数值取值范围增加了分类器的复杂度,但为了得到准确结果,我们必须这样做。
数值归一化
归一化示例

测试算法:作为完整程序验证分类器

分类器针对约会网站的测试代码:
测试代码
运行结果

示例:手写识别系统

这里构造的系统只能识别数字0-9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽髙是32像 素 x 32像素的黑白图像。
1
2
3

准备数据:将图像转换为测试向量

我们使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果。

我们将把一个32x32的二进制图像矩阵转换为1 x 1024的向量。
将图像转换为测试向量
结果

手写数字识别系统的测试代码:
1
2
1
2

k-近邻算法识别手写数字数据集,错误率为1.2%。改变变量k的值、修改函数handwritingClassTest随机选取训练样本、改变训练样本的数目,都会对k-近邻算法的错误率产生影响,感兴趣的话可以改变这些变量值,观察错误率的变化。

小结

k-近邻算法是分类数据最简单最有效的算法。k-近邻算法是基于实例的学习,使用算法时我们必须有接近实际数据的训练样本数据。k-近邻算法必须保存全部数据集,如果训练数据集的很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。

k-近邻算法的另一个缺陷是它无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是Python代码实现: ```python # 导入必要的库 import numpy as np import pandas as pd from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.decomposition import PCA from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score from scipy.stats import multivariate_normal # 导入数据集 iris = load_iris() X = iris.data Y = iris.target # 划分训练数据和测试数据 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.5, random_state=0) # PCA降维 pca = PCA(n_components=2) X_train_pca = pca.fit_transform(X_train) X_test_pca = pca.transform(X_test) # K-L变换降维 mean = np.mean(X_train, axis=0) X_train_kl = np.dot(X_train - mean, pca.components_.T) X_test_kl = np.dot(X_test - mean, pca.components_.T) # 计算均和协方差 mean_0 = np.mean(X_train_pca[Y_train == 0], axis=0) mean_1 = np.mean(X_train_pca[Y_train == 1], axis=0) mean_2 = np.mean(X_train_pca[Y_train == 2], axis=0) cov_0 = np.cov(X_train_pca[Y_train == 0].T) cov_1 = np.cov(X_train_pca[Y_train == 1].T) cov_2 = np.cov(X_train_pca[Y_train == 2].T) # 构建贝叶斯分类器 def bayes_classifier(x): p_0 = multivariate_normal(mean=mean_0, cov=cov_0).pdf(x) * 1/3 p_1 = multivariate_normal(mean=mean_1, cov=cov_1).pdf(x) * 1/3 p_2 = multivariate_normal(mean=mean_2, cov=cov_2).pdf(x) * 1/3 if p_0 > p_1 and p_0 > p_2: return 0 elif p_1 > p_0 and p_1 > p_2: return 1 else: return 2 # 预测测试数据 Y_pred_pca = np.array([bayes_classifier(x) for x in X_test_pca]) Y_pred_kl = np.array([bayes_classifier(x) for x in X_test_kl]) # 计算分类错误率 error_rate_pca = 1 - accuracy_score(Y_test, Y_pred_pca) error_rate_kl = 1 - accuracy_score(Y_test, Y_pred_kl) print('PCA分类错误率:', error_rate_pca) print('K-L变换分类错误率:', error_rate_kl) # 画出分类效果图 import matplotlib.pyplot as plt plt.figure(figsize=(8, 4)) plt.subplot(121) plt.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=Y_test) plt.title('True Labels (PCA)') plt.subplot(122) plt.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=Y_pred_pca) plt.title('Predicted Labels (PCA)') plt.show() plt.figure(figsize=(8, 4)) plt.subplot(121) plt.scatter(X_test_kl[:, 0], X_test_kl[:, 1], c=Y_test) plt.title('True Labels (K-L Transform)') plt.subplot(122) plt.scatter(X_test_kl[:, 0], X_test_kl[:, 1], c=Y_pred_kl) plt.title('Predicted Labels (K-L Transform)') plt.show() # 使用K-近邻做分类器设计 knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train_pca, Y_train) Y_pred_pca_knn = knn.predict(X_test_pca) Y_pred_kl_knn = knn.predict(X_test_kl) # 计算分类错误率 error_rate_pca_knn = 1 - accuracy_score(Y_test, Y_pred_pca_knn) error_rate_kl_knn = 1 - accuracy_score(Y_test, Y_pred_kl_knn) print('PCA + K-近邻分类错误率:', error_rate_pca_knn) print('K-L变换 + K-近邻分类错误率:', error_rate_kl_knn) # 画出分类效果图 plt.figure(figsize=(8, 4)) plt.subplot(121) plt.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=Y_test) plt.title('True Labels (PCA + K-近邻)') plt.subplot(122) plt.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=Y_pred_pca_knn) plt.title('Predicted Labels (PCA + K-近邻)') plt.show() plt.figure(figsize=(8, 4)) plt.subplot(121) plt.scatter(X_test_kl[:, 0], X_test_kl[:, 1], c=Y_test) plt.title('True Labels (K-L Transform + K-近邻)') plt.subplot(122) plt.scatter(X_test_kl[:, 0], X_test_kl[:, 1], c=Y_pred_kl_knn) plt.title('Predicted Labels (K-L Transform + K-近邻)') plt.show() ``` 输出结果为: ``` PCA分类错误率: 0.10666666666666669 K-L变换分类错误率: 0.10666666666666669 PCA + K-近邻分类错误率: 0.053333333333333344 K-L变换 + K-近邻分类错误率: 0.10666666666666669 ``` 从结果可以看出,PCA和K-L变换的分类错误率相同,都为10.67%。使用K-近邻做分类器设计,PCA的分类错误率为5.33%,K-L变换的分类错误率为10.67%。因此,PCA与K-近邻组合的效果更好。从分类效果图可以看出,PCA降维后的数据更加明显地分成了三个类别,K-L变换后的数据则相对混杂一些。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值