# 实验题目:KNN实验——手写数字识别
## 实验目的:
### 实验内容:
1. 实现最基本的KNN算法,使用trainingDigits文件夹下的数据,对testDigits中的数据进行预测。(K赋值为1,使用欧氏距离,多数投票决定分类结果)
2. 改变K的值,并观察对正确率的影响。
3. 更改距离度量方式,更改投票方式(距离加权),分析错误率。
### 实验要求:
1. 要求给出代码,以及运行窗口截图。
2. 对正确率的影响,最好用表格或作图说明,并做简要分析。
3. 实验内容3为选做,不做统一要求。
## 实验步骤与内容:
### 代码来源
代码是在参考开源代码的基础上做出的改进
KNN分类算法实现手写数字识别 CSDN博客
```c++
http://www.cnblogs.com/ahu-lichang/p/7152539.html
```
### 算法设计说明
**实验环境**:
1. 硬件环境 个人笔记本电脑
2. 软件环境 Python Eclipse Pydev插件
**所用语言**:Python
**实验数据分析**:
把来自UCI数据库的手写数据集简化成32像素x32像素的黑白图像,并且以01矩阵的方式存储在txt文件中。大约有训练样本2000个,测试样本900个。
digits 目录下有两个文件夹,分别是:
1. trainingDigits:训练数据,1934个文件,每个数字大约200个文件。
2. testDigits:测试数据,946个文件,每个数字大约100个文件。
每个文件中存储一个手写的数字,文件的命名类似0_7.txt,第一个数字0表示文件中的手写数字是0,后面的7是个序号。
我们使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果。两组数据没有重叠。
**算法设计**:
1.**思路**
1. KNN的主要思想是找到与待测样本最接近的k个样本,然后把这k个样本出现次数最多的类别作为待测样本的类别。
2. 下载实验要求中给的数据集digits文件夹,用trainingDigits作训练集,用testDigits作为测试集
3. 将每个样本的txt文件转换为对应的一个向量
4. 以欧氏距离作为度量进行KNN算法,分析样本之间的相似度
2.**具体实现**
a.加载数据loadDataSet():
从digits文件夹中读取训练数据和测试数据
以训练数据为例
```c++
dataSetDir = './digits/'
trainingFileList = os.listdir(dataSetDir + 'trainingDigits')
```
加载同目录下/digits/trainingDigits中的训练数据文件
```c++
numSamples = len(trainingFileList)
train_x = zeros((numSamples, 1024))
train_y = []
```
train_x用来储存txt文件转换成的向量
train_y用来储存该文件实际代表的数字
```c++
for i in xrange(numSamples):
filename = trainingFileList[i]
对每个训练数据文件进行处理
# get train_x
train_x[i, :] = img2vector(dataSetDir + 'trainingDigits/%s' % filename)
调用img2vector方法将txt文件转换为对应的一个向量
# get label from file name such as "1_18.txt"
label = int(filename.split('_')[0]) # return 1
train_y.append(label)
记录该文件实际代表的数字
```
加载测试集数据的过程同理,用test_x,test_y表示
b.将图片转换为向量img2vector(filename):
```python
def img2vector(filename):
rows = 32
cols = 32
```
数据的行列都是32
```c++
imgVector = zeros((1, rows * cols))
fileIn = open(filename)
```
对每个训练数据文件进行处理
```c++
for row in xrange(rows):
lineStr = fileIn.readline()
for col in xrange(cols):
imgVector[0, row * 32 + col] = int(lineStr[col])
return imgVector
```
转换为向量
c.KNN分类核心方法 kNNClassify(newInput, dataSet, labels, k):
newInput为待测试数据,dataSet是训练集,labels是分类合集
```python
def kNNClassify(newInput, dataSet, labels, k):
numSamples = dataSet.shape[0] # shape[0]代表行数
```
已知分类的数据集(训练集)的行数
先tile函数将输入点拓展成与训练集相同维数的矩阵,再计算欧氏距离
```python
# # step 1: 计算欧式距离
# tile(A, reps): 将A重复reps次来构造一个矩阵
# the following copy numSamples rows for dataSet
diff = tile(newInput, (numSamples, 1)) - dataSet # Subtract element-wise
样本与训练集的差值矩阵
squaredDiff = diff ** 2 # squared for the subtract
差值矩阵平方
squaredDist = sum(squaredDiff, axis = 1) # sum is performed by row
计算每一行上元素的和
distance = squaredDist ** 0.5
开方得到欧拉距离矩阵
# # step 2: 对距离排序
# argsort()返回排序后的索引
sortedDistIndices = argsort(distance)
按distances中元素进行升序排序后得到的对应下标的列表
classCount = {} # 定义一个空的字典
for i in xrange(k):
# # step 3: 选择k个最小距离
voteLabel = labels[sortedDistIndices[i]]
# # step 4: 计算类别的出现次数
# when the key voteLabel is not in dictionary classCount, get()
# will return 0
classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
选择距离最小的k个点
# # step 5: 返回出现次数最多的类别作为分类结果
maxCount = 0
for key, value in classCount.items():
if value > maxCount:
maxCount = value
maxIndex = key
return maxIndex
返回出现次数最多的类别作为分类结果
```
d.计算预测准确率
```c++
# # step 3: 测试
print "step 3: testing..."
numTestSamples = test_x.shape[0]
matchCount = 0
声明总待测数据和预测正确数
for i in xrange(numTestSamples):
predict = kNNClassify(test_x[i], train_x, train_y, 1)
if predict == test_y[i]:
matchCount += 1
对每一个测试样本进行测试,正确则计入
accuracy = float(matchCount) / numTestSamples
计算正确率
```
3.改进
由于使用了开源代码,所以需要对程序的输出方法进行修改。
原程序运行结果仅输出几个步骤提示,界面停滞几分钟后便直接输出准确率的结果,未免有些不到位,所以应该加入更加细致的算法运行结果的显示。
需要添加:
对每个测试样本进行KNN分类算法后的结果
与该样本实际类别的比较
```c++
print "分类结果为: %d, 实际类别为: %d" % (predict, test_y)
总测试数量
print "总测试样本数: %d" % numTestSamples
测试准确数
print "测试正确样本数: %d" % matchCount
分类准确率
print '分类正确率: %.2f%%' % (accuracy * 100)
```
**实验结果**:
要求:改变K的值,并观察对正确率的影响。
| K值 | 正确率 |
| ---- | ------ |
| 1 | 98.63% |
| 2 | 98.63% |
| 3 | 98.84% |
| 4 | 98.52% |
| 5 | 98.20% |
**实验结果分析:**
![](https://www.writebug.com/myres/static/uploads/2022/5/26/17825276aa8a2e8409649d6ff8bd8473.writebug)
根据上方的图表,可以看出K的取值可以影响分类的准确率
K=1时准确率就已经高达98.63%;K=2时准确率保持不变,仍是98.63%;在K=3的时候准确率最高,上升到了98.84%;在K=4时又开始降低到98.52%;K=5时准确率仍然在降低,为98.20%
之后增加K的值,如K=6,K=7,可以看到准确率继续降低
结论是,为了保证较高的准确率,应该把K的值设得小一些。
## 实验结果截图
K=1
![](https://www.writebug.com/myres/static/uploads/2022/5/26/54f8302028d33d76ac7d9c57c6d59143.writebug)
K=2
结果同K=1
K=3
![](https://www.writebug.com/myres/static/uploads/2022/5/26/cde16c52026de8ab5d1c5b66317d29a2.writebug)
K=4
![](https://www.writebug.com/myres/static/uploads/2022/5/26/41c2cbded78d2075bc1b07b084f62fef.writebug)
K=5
![](https://www.writebug.com/myres/static/uploads/2022/5/26/2d3ffdacce05fa6543fada2b151dba23.writebug)
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
资源包含文件:课程报告word+源码及数据 软件环境 Python Eclipse Pydev插件 大约有训练样本2000个,测试样本900个。详细介绍参考:https://blog.csdn.net/newlw/article/details/124992698
资源推荐
资源详情
资源评论
收起资源包目录
基于Python的KNN实验手写数字识别.zip (2886个子文件)
KNN实验报告.docx 69KB
实验二:KNN实验.docx 22KB
README.md 8KB
KNN.py 4KB
参考开源代码.py 4KB
__init__.py 0B
5_69.txt 1KB
6_41.txt 1KB
8_40.txt 1KB
0_40.txt 1KB
8_44.txt 1KB
3_26.txt 1KB
8_33.txt 1KB
7_45.txt 1KB
8_72.txt 1KB
8_54.txt 1KB
7_55.txt 1KB
0_55.txt 1KB
8_18.txt 1KB
8_46.txt 1KB
2_61.txt 1KB
1_46.txt 1KB
7_68.txt 1KB
9_19.txt 1KB
4_74.txt 1KB
2_40.txt 1KB
3_11.txt 1KB
5_39.txt 1KB
6_43.txt 1KB
1_52.txt 1KB
8_70.txt 1KB
6_6.txt 1KB
7_76.txt 1KB
0_76.txt 1KB
2_48.txt 1KB
8_6.txt 1KB
6_72.txt 1KB
9_18.txt 1KB
0_24.txt 1KB
6_63.txt 1KB
1_29.txt 1KB
6_82.txt 1KB
4_68.txt 1KB
2_59.txt 1KB
7_0.txt 1KB
3_50.txt 1KB
6_35.txt 1KB
3_72.txt 1KB
8_39.txt 1KB
8_84.txt 1KB
3_80.txt 1KB
7_60.txt 1KB
7_27.txt 1KB
1_9.txt 1KB
6_16.txt 1KB
0_9.txt 1KB
4_52.txt 1KB
1_16.txt 1KB
6_56.txt 1KB
9_86.txt 1KB
4_23.txt 1KB
6_10.txt 1KB
7_54.txt 1KB
3_44.txt 1KB
7_82.txt 1KB
6_42.txt 1KB
9_23.txt 1KB
3_53.txt 1KB
9_0.txt 1KB
0_48.txt 1KB
5_105.txt 1KB
2_22.txt 1KB
4_80.txt 1KB
1_4.txt 1KB
8_75.txt 1KB
7_58.txt 1KB
2_69.txt 1KB
9_77.txt 1KB
3_54.txt 1KB
1_15.txt 1KB
8_85.txt 1KB
2_14.txt 1KB
5_43.txt 1KB
1_91.txt 1KB
6_28.txt 1KB
5_67.txt 1KB
4_24.txt 1KB
2_68.txt 1KB
2_32.txt 1KB
7_40.txt 1KB
9_79.txt 1KB
5_15.txt 1KB
0_74.txt 1KB
4_84.txt 1KB
6_68.txt 1KB
7_9.txt 1KB
5_100.txt 1KB
5_60.txt 1KB
5_89.txt 1KB
8_66.txt 1KB
共 2886 条
- 1
- 2
- 3
- 4
- 5
- 6
- 29
资源评论
- zhangxianhui012023-06-20资源值得借鉴的内容很多,那就浅学一下吧,值得下载!
- pythonnumberone12023-01-15资源值得借鉴的内容很多,那就浅学一下吧,值得下载!
shejizuopin
- 粉丝: 1w+
- 资源: 1300
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功