KNN_识别图片数字

1.实验过程省略灰度化处理过程,用已经处理好的txt数据进行训练

3.jpg

复制代码
from PIL import Image
def imgtotxt(imgfile,txtfile,size = (32,32)):
    image_file = Image.open(imgfile).resize(size,Image.LANCZOS).convert('L')
    width,height = image_file.size
    f = open(txtfile,'w')
    ascii_char = '10'
    for i in range(height):
        pix_char = ''
        for j in range(width):
            pixe1 = image_file.getpixel((j,i))
            pix_char += ascii_char[int(pixe1/128)]
        pix_char += '\n'
        f.write(pix_char)
    f.close()
imgtotxt('3.jpg','3_0.txt')
'''
3_0.txt
00000000000000000000000000000000
00000000000001111100000000000000
00000000111111111111111100000000
00000111111111111111111111000000
00011111111100000111111111100000
00011111000000000000111111110000
00011000000000000000001111111000
00000000000000000000000111111000
00000000000000000000000111111000
00000000000000000000000111111000
00000000000000000000000111111000
00000000000000000000001111110000
00000000000000000000011111110000
00000000000000000000111111100000
00000000000000000111111110000000
00000001111111111111100000000000
00000001111111111111110000000000
00000000111111111111111111000000
00000000000000000000111111110000
00000000000000000000000111111100
00000000000000000000000011111100
00000000000000000000000001111110
00000000000000000000000001111110
00000000000000000000000000111110
00000000000000000000000001111110
00000000000000000000000001111110
00000000000000000000000011111100
00111000000000000000000111111100
00111111100000000000111111111000
00111111111111111111111111100000
00001111111111111111111110000000
00000000011111111111100000000000
'''

2.数据预处理:txt2arry 函数将文本文件转换为 NumPy 数组,每个文件代表一个手写数字的图像,图像大小为 32x32 像素。

3.数据集构建:convert2dataset 函数从指定文件夹中读取所有文件,转换为数据集和标签。数据集中的每个样本都是一个 1x1024 的数组,标签是从文件名中提取的第一个字符。

4.模型训练:使用 KNeighborsClassifier 类训练 KNN 模型。模型参数 n_neighbors=43 表示考虑 43 个最近邻,weights='distance' 表示在投票时考虑距离的权重,p=2 表示使用欧氏距离。

5.模型评估:计算训练集上的准确率,并使用 classification_report 打印测试集的分类报告。

6.错误分析:找到第一个标签为 8 的样本,检查其预测结果,并打印出预测错误的样本。

7.混淆矩阵:使用 confusion_matrix 和 pd.crosstab 打印混淆矩阵,以评估模型的性能。

8.参数调优:测试不同的 k 值(奇数)对模型性能的影响,并绘制训练集和测试集准确率随 k 值变化的图表。

复制代码
import os
import numpy as np
#将文本文件转换为 NumPy 数组。
def txt2arry(filename):
    #创建了一个形状为 (1, 1024) 的全零数组,用于存储转换后的数据
    x = np.zeros((1,1024))
    f = open(filename)
    for i in range(32):
        lineStr = f.readline()
        for j in range(32):
            #将每个字符转换为整数,并存储在数组 x 的相应位置
            x[0,32*i+j] = int(lineStr[j])
    return x
#从指定文件夹中读取所有文件,转换为数据集和标签。
def convert2dataset(file_path):
    #获取指定文件夹中的所有文件名
    list_file = os.listdir(file_path)
    '''
    m 是文件的数量。
    datas 是一个形状为 (m, 1024) 
    的全零数组,用于存储转换后的数据。
    labels 是一个空列表,用于存储标签
    '''
    m = len(list_file)
    datas = np.zeros((m,1024))
    labels = []
    for i in range(m):
        #num = int(list_file[i][0]) 从文件名
        #中提取第一个字符并转换为整数,作为标签
        num = int(list_file[i][0])
        labels.append(num)
        #调用 txt2arry 函数将文件内容转换为数组,
        #并存储在 datas 的相应行中
        datas[i,:] = txt2arry(file_path+'\\'+list_file[i])
    return datas,labels

x_train,y_train = convert2dataset('trainingDigits')
x_test,y_test = convert2dataset('testDigits')
from sklearn.neighbors import KNeighborsClassifier

#使用 KNeighborsClassifier 训练模型。

knn = KNeighborsClassifier(n_neighbors=43,weights='distance',p=2)
knn.fit(x_train,y_train)

#计算训练集上的准确率。

score = (knn.score(x_train,y_train))
print('pricise = ',score)

#使用 classification_report 打印测试集的分类报告

from sklearn.metrics import classification_report
y_pred = knn.predict(x_test)
print(classification_report(y_test,y_pred))

#找到第一个标签为 8 的样本,检查其预测结果

i = y_test.index(8)
for j in range(91):
    if(y_test[i+j] != y_pred[i+j]):
        #打印出预测错误的样本
        print('{}[{}]->{}'.format(y_test[i+j],j,y_pred[i+j]))

#使用 confusion_matrix 和 pd.crosstab 打印混淆矩阵

import pandas as pd
from sklearn.metrics import confusion_matrix
y_test = np.array(y_test)
cm = confusion_matrix(y_test,y_pred)
cm_df = pd.crosstab(y_test,y_pred,rownames=['真实值'],colnames=['预测值'],margins=True)
print(cm,cm_df,sep='\n')

#测试不同的 k 值(奇数)对模型性能的影响。
#绘制训练集和测试集准确率随 k 值变化的图表

neighbors = []
for i in range(13,45):
    if i%2 == 1:
        neighbors.append(i)
train_accuracy = np.empty(len(neighbors))
test_accuracy = np.empty(len(neighbors))
for i,k in enumerate(neighbors):
    knn = KNeighborsClassifier(n_neighbors=k,weights='distance',p=2)
    knn.fit(x_train,y_train)
    train_accuracy[i] = round(knn.score(x_train,y_train),2)
    test_accuracy[i] = round(knn.score(x_test,y_test),2)

from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title('k值的变化对准确率的影响')
plt.plot(neighbors,train_accuracy,label='训练样本的准确率')
plt.plot(neighbors,test_accuracy,label='测试样本的准确率')
plt.legend()
plt.xlabel('最近邻k字值')
plt.ylabel('准确率值')
plt.show()
#后期可以遍历找出acc最值时k值
#k 代表的是在进行分类决策时考虑的最近邻的数量
'''
E:\平常学习代码包\mechine_learning\knn_num\.venv\Scripts\python.exe E:\平常学习代码包\mechine_learning\knn_num\knn_Num.py 
pricise =  1.0
              precision    recall  f1-score   support

           0       0.99      1.00      0.99        87
           1       0.88      0.97      0.92        97
           2       0.95      0.96      0.95        92
           3       0.95      0.94      0.95        85
           4       1.00      0.93      0.96       114
           5       1.00      0.94      0.97       108
           6       0.97      1.00      0.98        87
           7       0.92      1.00      0.96        96
           8       0.96      0.86      0.91        91
           9       0.91      0.93      0.92        89

    accuracy                           0.95       946
   macro avg       0.95      0.95      0.95       946
weighted avg       0.95      0.95      0.95       946

8[1]->3
8[3]->6
8[13]->2
8[28]->6
8[29]->1
8[30]->1
8[31]->1
8[33]->1
8[40]->1
8[47]->6
8[59]->1
8[62]->1
8[79]->1
[[ 87   0   0   0   0   0   0   0   0   0]
 [  0  94   2   0   0   0   0   1   0   0]
 [  0   1  88   0   0   0   0   2   0   1]
 [  0   0   2  80   0   0   0   0   2   1]
 [  1   2   0   0 106   0   0   3   1   1]
 [  0   0   0   1   0 102   0   0   0   5]
 [  0   0   0   0   0   0  87   0   0   0]
 [  0   0   0   0   0   0   0  96   0   0]
 [  0   8   1   1   0   0   3   0  78   0]
 [  0   2   0   2   0   0   0   2   0  83]]
预测值   0    1   2   3    4    5   6    7   8   9  All
真实值                                                 
0    87    0   0   0    0    0   0    0   0   0   87
1     0   94   2   0    0    0   0    1   0   0   97
2     0    1  88   0    0    0   0    2   0   1   92
3     0    0   2  80    0    0   0    0   2   1   85
4     1    2   0   0  106    0   0    3   1   1  114
5     0    0   0   1    0  102   0    0   0   5  108
6     0    0   0   0    0    0  87    0   0   0   87
7     0    0   0   0    0    0   0   96   0   0   96
8     0    8   1   1    0    0   3    0  78   0   91
9     0    2   0   2    0    0   0    2   0  83   89
All  88  107  93  84  106  102  90  104  81  91  946
'''
相关推荐
智码看视界20 小时前
小米表格数据基础模型-Xiaomi-TabLDM 部署测评,70M表格基础模型开源,一套配置通吃分类回归
开源·scikit-learn·回归预测·开源大模型·自动化机器学习·表格基础模型
leihefeng8 天前
手写数字识别:KNN vs 逻辑回归实战
python·算法·机器学习·逻辑回归·scikit-learn
2601_962077989 天前
机器学习及其Python实践
pytorch·python·机器学习·tensorflow·scikit-learn
“AI国潮设计-小江”9 天前
《Python实战 | 用SDXL大模型生成“潮汕英歌舞”国潮IP头像,已申请外观专利,附Prompt思路!》
人工智能·python·prompt·aigc·scikit-learn
AR-26710-9 天前
机器学习复习收官Day12
人工智能·python·机器学习·scikit-learn
AR-26710-14 天前
机器学习复习Day8——异常检测
人工智能·python·机器学习·scikit-learn
muddjsv15 天前
Python 神经网络入门:用 scikit-learn 完成 MLP 分类与回归
python·神经网络·scikit-learn
智购科技无人售货机厂家19 天前
2026自动售货机远程运维平台设计:从设备诊断到预测性维护的工程实践~YH
运维·python·物联网·架构·django·scikit-learn
智购科技自动售货机工厂19 天前
2026自动售货机电机驱动芯片选型:从L298N到DRV8870的工程实践~YH
大数据·开发语言·数据库·人工智能·单片机·嵌入式硬件·scikit-learn
databook1 个月前
如何快速构建一个数据科学应用?从零到上线
python·机器学习·scikit-learn