采用 K 近邻执行手写数字识别任务
以下 Python 代码是“人工智能与计算科学”课程的配套示例。程序将手写数字图像转换为文本向量,并采用 K 近邻(KNN)模型识别数字。数据集为 data.zip(点击下载)。
# Convert an image to a text file
import os
from PIL import Image
def imgtotext(imgfile,txtfile,size=(32,32)):
# Resize the image to 32x32 and convert it to text
image_file = Image.open(imgfile)
image_file = image_file.resize(size,Image.LANCZOS)
image_file=image_file.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):
pixel = image_file.getpixel((j,i))
pix_char+=ascii_char[int(pixel/128)]
pix_char+='\n'
f.write(pix_char)
f.close()
imgtotext(r'test.jpg', r'test.txt')
from os import listdir
from numpy import *
import numpy as np
import operator
def KNN(test_data,train_data,train_label,k):
# Number of training samples
dataSetSize = train_data.shape[0]
# Tile the input vector and compute the distances
all_distances = np.sqrt(np.sum(np.square(tile(test_data,(dataSetSize,1))-train_data),axis=1))
print("All distances:", all_distances)
# Sort by distance
sort_distance_index = all_distances.argsort()
# Select the k nearest samples
classCount = {}
for i in range(k):
voteIlabel = train_label[sort_distance_index[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
return sortedClassCount[0][0]
# Convert 32x32 text to a 1x1024 vector
def img2vector(filename):
returnVect = []
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect.append(int(lineStr[j]))
return returnVect
# Read the class label from the filename
def classnumCut(fileName):
# Example filename: 0_3.txt
fileStr = fileName.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
return classNumStr
# Load the training set
def trainingDataSet():
train_label = []
trainingFileList = listdir('data/trainingDigits')
m = len(trainingFileList)
train_data = zeros((m,1024))
# Read the label
for i in range(m):
fileNameStr = trainingFileList[i]
train_label.append(classnumCut(fileNameStr))
train_data[i,:] = img2vector('data/trainingDigits/%s' % fileNameStr)
return train_label,train_data
# Set the number of neighbors and run the test
Nearest_Neighbor_number = 3
train_label,train_data = trainingDataSet()
test_data = img2vector('test.txt')
# Predict
classifierResult = KNN(test_data, train_data, train_label, Nearest_Neighbor_number)
print("Recognition result:", classifierResult)下图为待识别的手写数字:

KNN 的识别结果为:
识别结果为:6