使用Python实现基于KNN算法的手写数字识别

03-07 5阅读

手写数字识别是计算机视觉和机器学习领域中的一个经典问题。它涉及到从图像中提取特征,并根据这些特征对数字进行分类。在本文中,我们将使用Python语言和K-近邻(KNN)算法来构建一个简单但有效的手写数字识别系统。

KNN算法简介

K-近邻(K-Nearest Neighbors, KNN)是一种监督学习算法,其核心思想是:对于一个新的样本点,找到训练集中与其最近的k个邻居,然后根据这k个邻居的类别来进行投票,选择票数最多的类别作为新样本点的预测类别。

算法步骤

计算距离:对于每个测试样本,计算它与所有训练样本之间的距离。选择最近的k个邻居:根据距离从小到大排序,选取前k个最近的样本。多数表决:统计这k个样本中各个类别的出现次数,选择出现次数最多的类别作为预测结果。

数据集介绍

我们将使用MNIST数据集,这是一个非常流行的手写数字数据集,包含60,000张训练图像和10,000张测试图像,每张图像是28x28像素的灰度图像,对应于一个0-9的数字。

加载数据集

我们可以使用sklearn.datasets模块中的fetch_openml函数来加载MNIST数据集:

from sklearn.datasets import fetch_openmlimport numpy as np# 加载MNIST数据集mnist = fetch_openml('mnist_784', version=1)X, y = mnist["data"], mnist["target"]# 将标签转换为整数类型y = y.astype(np.int8)# 打乱数据集shuffle_index = np.random.permutation(70000)X, y = X[shuffle_index], y[shuffle_index]# 划分训练集和测试集X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]

KNN模型的实现

我们将使用scikit-learn库中的KNeighborsClassifier类来实现KNN算法。首先,我们需要导入必要的库并初始化模型:

from sklearn.neighbors import KNeighborsClassifier# 初始化KNN分类器,设置k=3knn_clf = KNeighborsClassifier(n_neighbors=3)# 训练模型knn_clf.fit(X_train, y_train)

模型评估

为了评估模型的性能,我们可以使用交叉验证方法。cross_val_score函数可以帮助我们快速完成这一任务:

from sklearn.model_selection import cross_val_score# 使用交叉验证评估模型性能scores = cross_val_score(knn_clf, X_train, y_train, cv=3, scoring="accuracy")print("Cross-validation accuracy: {:.2f}%".format(scores.mean() * 100))

提升模型性能

虽然KNN算法简单易用,但在处理大规模数据集时可能会遇到性能瓶颈。为了提升模型的性能,我们可以尝试以下几种方法:

特征缩放

由于KNN算法依赖于距离度量,因此不同特征之间的尺度差异可能会影响模型的表现。我们可以使用StandardScaler对特征进行标准化处理:

from sklearn.preprocessing import StandardScaler# 初始化标准化器scaler = StandardScaler()# 对训练集和测试集进行标准化X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))X_test_scaled = scaler.transform(X_test.astype(np.float64))# 使用标准化后的数据重新训练模型knn_clf.fit(X_train_scaled, y_train)# 再次评估模型性能scores = cross_val_score(knn_clf, X_train_scaled, y_train, cv=3, scoring="accuracy")print("Cross-validation accuracy after scaling: {:.2f}%".format(scores.mean() * 100))

调整超参数

KNN算法的关键超参数是n_neighbors,即邻居的数量。通过调整这个参数,可以进一步优化模型的性能。我们可以使用网格搜索(Grid Search)来自动寻找最佳的超参数组合:

from sklearn.model_selection import GridSearchCV# 定义参数网格param_grid = [{'weights': ['uniform', 'distance'], 'n_neighbors': [3, 4, 5]}]# 初始化网格搜索grid_search = GridSearchCV(knn_clf, param_grid, cv=5, scoring='accuracy')# 执行网格搜索grid_search.fit(X_train_scaled, y_train)# 输出最佳参数print("Best parameters:", grid_search.best_params_)print("Best cross-validation accuracy: {:.2f}%".format(grid_search.best_score_ * 100))# 使用最佳参数重新训练模型final_knn_clf = grid_search.best_estimator_

测试模型

最后,我们可以使用测试集来评估最终模型的性能:

from sklearn.metrics import accuracy_score# 预测测试集y_pred = final_knn_clf.predict(X_test_scaled)# 计算准确率test_accuracy = accuracy_score(y_test, y_pred)print("Test set accuracy: {:.2f}%".format(test_accuracy * 100))

总结

通过本文,我们详细介绍了如何使用Python和KNN算法实现手写数字识别。我们从数据集的加载、模型的训练、性能评估到模型优化,一步步展示了整个过程。尽管KNN算法相对简单,但它在许多实际应用中仍然表现出色。通过特征缩放和超参数调优,我们可以显著提升模型的性能。希望这篇文章能够帮助读者更好地理解和应用KNN算法。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第1名访客 今日有22篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!