手写数字识别
——一个非人工智能算法
引言
本文将介绍一个手写数字识别问题的非人工智能算法,这种算法准确率不高,仅供做参考
算法原理
1. 计算每个数字的平均灰度
设训练数据集中数字
1
1
的部分为
其中 n n 为数据量, 为每个数字相应位置上像素的灰度值(在Kaggle提供的数据里 m m 为784),则其平均灰度为
是一个 1 1 行 列的向量,其他数字类似
2. 根据欧氏距离进行预测
由上文得到的每个数字的平均灰度记为
Pi¯¯¯¯¯=(p[i]1,p[i]2,⋯,p[i]m),i=0,1,⋯,9
P
i
¯
=
(
p
1
[
i
]
,
p
2
[
i
]
,
⋯
,
p
m
[
i
]
)
,
i
=
0
,
1
,
⋯
,
9
设测试数据中某一数据为
A=(a1,a2,⋯,am)
A
=
(
a
1
,
a
2
,
⋯
,
a
m
)
计算 A A 与 的欧氏距离
Di=|A−Pi¯¯¯¯¯|=∑j=1m(aj−p[i]j)2,i=0,1,⋯,9
D
i
=
|
A
−
P
i
¯
|
=
∑
j
=
1
m
(
a
j
−
p
j
[
i
]
)
2
,
i
=
0
,
1
,
⋯
,
9
取最小的 Di D i 对应的 i i <script type="math/tex" id="MathJax-Element-51">i</script> 作为结果,通俗地讲“离谁近就算谁的”
算法实现
import numpy as np
import pandas as pd
# 加载训练数据集
train = pd.read_csv("train.csv")
images = train.iloc[:,1:].values
labels = train.iloc[:,0].values
# 计算每个数字的平均灰度
number = np.zeros([10, train.shape[1]-1])
number_sum = np.zeros([10])
for i in range(train.shape[0]):
number_sum[labels[i]] += 1
number[labels[i]][:] += images[i][:]
for num in range(10):
number[num][:] = np.multiply(number[num][:], 1/number_sum[num])
# 加载测试数据集
test = pd.read_csv("test.csv")
test_images = test.iloc[:,:].values
test_label = np.zeros([test_images.shape[0]], dtype=np.int64)
# 根据欧氏距离进行预测
for i in range(test_images.shape[0]):
if i%700==0:
print(str(i/test_images.shape[0]*100)+"% finished")
test_label[i]=0
minsum=1e10
for num in range(10):
sum1=0.0
for j in range(test_images.shape[1]):
sum1 += (test_images[i][j] - number[num][j])**2
if sum1<minsum:
minsum = sum1
test_label[i] = num
# 保存结果
ImageId = list(range(1,test_images.shape[0]+1))
save = pd.DataFrame({'ImageId':ImageId,'Label':test_label})
save.to_csv('submission2.csv',index=False,sep=',')
将结果提交到Kaggle上得到80.61%的准确率,与人工智能算法相比准确率低了很多