创建一个简单的书写识别系统,使用KNN算法来识别手写数字。分别使用手写KNN算法和调用scikit-learn
库来实现。在数据处理过程中,将使用一个常见的手写数字数据集,如MNIST数据集。
数据集
我们将使用MNIST数据集,它包含60000个训练样本和10000个测试样本。每个样本是一个28x28像素的灰度图像,表示0-9之间的手写数字。
手写KNN算法
我们首先手写一个KNN算法来实现书写识别系统。
import numpy as np
from collections import Counter
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
# 加载MNIST数据集
mnist = fetch_openml('mnist_784')
X, y = mnist.data, mnist.target.astype(np.int)
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据归一化
X_train = X_train / 255.0
X_test = X_test / 255.0
# 计算欧氏距离
def euclidean_distance(point1, point2):
return math.sqrt(sum((x - y) ** 2 for x, y in zip(point1, point2)))
# KNN算法
def knn(X_train, y_train, X_test, k):
predictions = []
for test_point in X_test:
distances = [euclidean_distance(test_point, train_point) for train_point in X_train]
k_nearest_neighbors = np.argsort(distances)[:k]
k_labels = [y_train[i] for i in k_nearest_neighbors]
most_common_label = Counter(k_labels).most_common(1)[0][0]
predictions.append(most_common_label)
return predictions
# 使用KNN算法预测测试集
k = 3
y_pred = knn(X_train, y_train, X_test[:100], k) # 为了节约时间,这里只用100个测试样本
# 计算准确率
accuracy = np.mean(y_pred == y_test[:100])
print(f"手写KNN算法的预测准确率是: {accuracy}")
调用scikit-learn
库实现KNN算法
接下来,我们使用scikit-learn
库来实现相同的功能。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 创建KNN分类器
k = 3
knn = KNeighborsClassifier(n_neighbors=k)
# 用训练数据拟合模型
knn.fit(X_train, y_train)
# 使用模型预测测试集
y_pred = knn.predict(X_test[:100]) # 为了节约时间,这里只用100个测试样本
# 计算准确率
accuracy = accuracy_score(y_test[:100], y_pred)
print(f"调用scikit-learn库实现的KNN算法的预测准确率是: {accuracy}")
运行结果
运行上述代码,将分别输出:
手写KNN算法的预测准确率是: 0.96 # 预测准确率示例
调用scikit-learn库实现的KNN算法的预测准确率是: 0.96 # 预测准确率示例
解释
-
手写KNN算法:
- 数据加载和预处理:加载MNIST数据集,并将数据归一化到0到1之间。
- 计算距离:使用欧氏距离计算测试样本与每个训练样本之间的距离。
- 选择最近邻居:选择距离最近的K个邻居,并通过投票机制预测测试样本的标签。
- 计算准确率:比较预测结果与真实标签,计算准确率。
-
调用
scikit-learn
库:- 数据加载和预处理:加载MNIST数据集,并将数据归一化到0到1之间。
- 创建KNN分类器:使用
KNeighborsClassifier
创建KNN分类器,并设定K值为3。 - 训练和预测:用训练数据拟合模型,并预测测试样本的标签。
- 计算准确率:比较预测结果与真实标签,计算准确率。
通过以上两种方法,我们可以看到手写KNN算法和调用scikit-learn
库实现的KNN算法都能准确地识别手写数字。使用库函数使得代码更简洁、更容易维护,而手写算法有助于理解KNN的工作原理。