K 近邻算法(二)

简介: K-近邻(KNN)算法是一种监督学习方法,用于分类和回归。关键步骤包括计算新样本与训练样本的距离,选择合适的邻近样本数K,基于K个邻居的多数类别或平均值做出预测。K值的选择影响模型性能:小K易受噪声影响(过拟合),大K可能导致模型过于简单(欠拟合)。评估模型通常使用测试集的预测准确率,如sklearn.metrics.accuracy_score。最优K值可通过交叉验证,如GridSearchCV,来确定,但它可能计算密集。KNN常用于手写数字识别等任务,如MNIST数据集。

K 近邻算法(一)+https://developer.aliyun.com/article/1544595?spm=a2c6h.13148508.setting.14.2a1e4f0enzfh9f




分类算法的评估


  • 利用训练好的模型使用测试集的特征值进行预测


  • 将预测结果和测试集的目标值比较,计算预测正确的百分比


from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
#加载鸢尾花数据集
X,y = datasets.load_iris(return_X_y = True)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
 
knn_clf = KNeighborsClassifier(n_neighbors=6)
 
knn_clf.fit(X_train,y_train)
y_predict = knn_clf.predict(X_test)
sum(y_predict==y_test)/y_test.shape[0]
# 0.8666666666666667


SKlearn中模型评估


  • sklearn.metrics包中的accuracy_score方法: 传入预测结果和测试集的标签, 返回预测准确率


from sklearn.metrics import accuracy_score
accuracy_score(y_test,y_predict)


如何确定合适的K值


K值过小:容易受到异常点的影响


k值过大:受到样本均衡的问题


我们可以采用交叉验证法来选择最优的K值。


GridSearchCV


GridSearchCV 是 scikit-learn 库中的一个类,用于进行参数网格搜索。它结合了交叉验证和网格搜索的功能,可以自动地对给定的模型和参数组合进行训练和评估,以找到最佳的参数设置。


from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
 
# 定义模型和参数网格
model = SVC()
param_grid = {'C': [0.1, 1, 10], 'kernel': ['linear', 'rbf']}
 
# 创建 GridSearchCV 对象并进行训练
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5)
grid_search.fit(X_train, y_train)
 
# 获取最佳参数和对应的评分
best_params = grid_search.best_params_
best_score = grid_search.best_score_
 
# 使用最佳参数重新训练模型
best_model = grid_search.best_estimator_
best_model.fit(X_train, y_train)
 
# 在测试集上进行预测
y_pred = best_model.predict(X_test)


GridSearchCV 会遍历所有可能的参数组合,并对每个组合进行交叉验证。这可能会消耗大量的计算资源和时间,特别是当参数空间较大时。因此,在使用 GridSearchCV 时,需要权衡参数网格的大小和计算资源的可用性。


from sklearn.model_selection import GridSearchCV
x, y = load_iris(return_X_y=True)
 
x_train, x_test, y_train, y_test = \
    train_test_split(x, y, test_size=0.2, stratify=y, random_state=0)
 
# 创建网格搜索对象
estimator = KNeighborsClassifier()
param_grid = {'n_neighbors': [1, 3, 5, 7]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5, verbose=0)
estimator.fit(x_train, y_train)
 
print('最优参数组合:', estimator.best_params_, '最好得分:', estimator.best_score_)
 
print('测试集准确率:', estimator.score(x_test, y_test))
 
# 最优参数组合: {'n_neighbors': 7} 最好得分: 0.9583333333333334
# 测试集准确率: 1.0


手写数字案例


数据集:可以从MNIST数据集或UCI欧文大学机器学习存储库中获取手写数字的数据。这些数据集包含了大量已经标注好的手写数字图片。


import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import joblib
from collections import Counter
 
def show_digit(idx):
    
    data = pd.read_csv('手写数字识别.csv')
    if idx < 0 or idx > len(data) - 1:
        return
    x = data.iloc[:, 1:]
    y = data.iloc[:,0]
    print('当前数字的标签为:',y[idx])    # 查看当前数字的数值
 
    
    data_ = x.iloc[idx].values
    # 将数据形状修改为 28*28
    data_ = data_.reshape(28, 28)     # 显示当前数字在数据集的图片
    
    # 显示图像
    plt.imshow(data_)
    plt.show()
 
def train_model():
 
    # 1. 加载手写数字数据集
    data = pd.read_csv('手写数字识别.csv')
    x = data.iloc[:, 1:] / 255
    y = data.iloc[:, 0]
 
    # 2. 打印数据基本信息
    print('数据基本信息:', x.shape)
    print('类别数据比例:', Counter(y))
 
    # 3. 分割数据集
    split_data = train_test_split(x, y, test_size=0.2, stratify=y, random_state=0)
    x_train, x_test, y_train, y_test = split_data
 
    # 4. 模型训练
    estimator = KNeighborsClassifier(n_neighbors=3)
    estimator.fit(x_train, y_train)
 
    # 5. 模型评估
    acc = estimator.score(x_test, y_test)
    print('测试集准确率: %.2f' % acc)
 
    # 6. 模型保存
    joblib.dump(estimator, 'knn.pth')
 
 
def test_model():
    # 读取图片数据
    import matplotlib.pyplot as plt
    import joblib
    img = plt.imread('demo.png') # 对于灰度图像,返回的是一个二维数组,其中每个元素是一个介于0和1之间的浮点数,表示该像素的灰度值
    plt.imshow(img)
    # 加载模型
    knn = joblib.load('knn.pth')
    y_pred = knn.predict(img.reshape(1, -1)) #首先将从图片中读取到的数据 (img) 重塑为一维数组形式,以便给 KNN 分类器进行预测。
    print('您绘制的数字是:', y_pred)
 
 
show_digit(1)
    # 训练模型
train_model()
    # 测试模型
test_model()





小结:


KNN(K-Nearest Neighbors)算法,即K最近邻算法,是一种监督学习算法,可以用于分类和回归问题。其基本思想是:给定一个训练数据集,对于新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类别,则该输入实例也属于这个类别。


KNN算法的主要步骤如下:


  1. 计算输入实例与训练数据集中的每个实例之间的距离。常用的距离度量方法有欧氏距离、曼哈顿距离等。


  1. 对计算出的距离进行排序,找出距离最近的K个邻居。


  1. 统计这K个邻居所属的类别,选择出现次数最多的类别作为输入实例的预测类别。


  1. 如果用于回归问题,则计算这K个邻居的平均值或加权平均值作为输入实例的预测值。


KNN算法的优点:


  1. 算法简单,易于理解。


  1. 适用于多分类问题。


  1. 对于一些非线性问题,KNN算法具有较好的性能。


KNN算法的缺点:


  1. 当训练数据集较大时,计算距离的时间复杂度较高。


  1. K值的选择对算法性能影响较大,但目前没有确定K值的通用方法。


  1. 对于不平衡数据集,KNN算法的性能较差。


相关文章
|
1月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
1月前
|
机器学习/深度学习 算法 API
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
|
3月前
|
机器学习/深度学习 存储 并行计算
C语言与机器学习:K-近邻算法实现
C语言与机器学习:K-近邻算法实现
62 0
|
4月前
|
存储 传感器 算法
「AIGC算法」近邻算法原理详解
**K近邻(KNN)算法概述:** KNN是一种基于实例的分类算法,依赖于训练数据的相似性。算法选择最近的K个邻居来决定新样本的类别,K值、距离度量和特征归一化影响性能。适用于非线性数据,但计算复杂度高,适合小数据集。应用广泛,如推荐系统、医疗诊断和图像识别。通过scikit-learn库可实现分类,代码示例展示了数据生成、模型训练和决策边界的可视化。
43 0
「AIGC算法」近邻算法原理详解
|
5月前
|
机器学习/深度学习 数据采集 算法
K 近邻算法(一)
本文介绍了KNN算法的基本概念、步骤、优缺点,以及在图像识别、文本分类、回归预测、医疗诊断和金融风控等领域的应用。重点讲解了数据预处理、模型训练、评估方法和参数选择策略,包括K值确定、交叉验证和GridSearchCV的使用。
|
5月前
|
算法
使用k-近邻算法构建手写识别系统(kNN)
使用k-近邻算法构建手写识别系统(kNN)
42 9
|
5月前
|
算法 Python
使用k-近邻算法改进约会网站的配对效果(kNN)
使用k-近邻算法改进约会网站的配对效果(kNN)
48 6
|
5月前
|
存储 算法 索引
k-近邻算法(kNN)
k-近邻算法(kNN)
50 5
|
4月前
|
存储 数据采集 算法
近邻算法的详细介绍
近邻算法的详细介绍
|
5月前
|
机器学习/深度学习 算法 搜索推荐
KNN算法(k近邻算法)原理及总结
KNN算法(k近邻算法)原理及总结