新手学习PYTHON中KNN算法的手写识别出现问题 求助

Python013

新手学习PYTHON中KNN算法的手写识别出现问题 求助,第1张

参考了其他博主的代码 想试着运行 然后去理解。结果一直报错,希望大神帮帮忙。

import numpy as np

import os

import kNN

def img2vector(filename):

"""函数将以文本格式出现的32*32的0-1图片,转变成一维特征数组,返回一维数组

Keyword argument:

filename -- 文本格式的图片文件

"""

imgvect = np.zeros((1, 1024))

fr = open(filename)

for i in range(32):

linestr = fr.readline()

for j in range(32):

imgvect[0, 32*i + j] = int(linestr[j])

return imgvect

def handwriteClassfiy(testfile, trainfile, k):

"""函数将trainfile中的文本图片转换成样本特征集和样本类型集,用testfile中的测试样本测试,无返回值

Keyword argument:

testfile -- 测试图片目录

trainfile -- 样本图片目录

"""

trainFileList = os.listdir(trainfile)

trainFileSize = len(trainFileList)

labels = []

trainDataSet = np.zeros((trainFileSize, 1024))

for i in range(trainFileSize):

filenameStr = trainFileList[i]

digitnameStr = filenameStr.split('.')[0]

digitLabels = digitnameStr.split('_')[0]

labels.append(digitLabels)

trainDataSet[i, :] = img2vector(trainfile + '/' + filenameStr)

testFileList = os.listdir(testfile)

testNumber = len(testFileList)

errorcount = 0.0

for testname in testFileList:

testdigit = img2vector(testfile + '/' + testname)

classifyresult = kNN.classfiy(testdigit, trainDataSet, labels, k)

testStr = testname.split('.')[0]

testDigitLabel = testStr.split('_')[0]

if classifyresult != testDigitLabel:

errorcount += 1.0

#print('this test real digit is:%s, and the result is: %s' % (testDigitLabel, classifyresult))

print('k = %d, errorRatio is: %f' % (k, errorcount/float(testNumber)))

return

if __name__ == '__main__':

filename = 'C:/Users/lx/Desktop/MachineLearning-master/kNN/use Python and NumPy/testDigits/0_1.txt'

traindir= 'C:/Users/lx/Desktop/MachineLearning-master/kNN/use Python and NumPy/trainingDigits'

testdir = 'C:/Users/lx/Desktop/MachineLearning-master/kNN/use Python and NumPy/testDigits'

handwriteClassfiy(testdir, traindir, 3)

错误提示Traceback (most recent call last):

File "kNN.py", line 56, in <module>

handwriteClassfiy(testdir, traindir, 3)

File "kNN.py", line 43, in handwriteClassfiy

classifyresult = kNN.classfiy(testdigit, trainDataSet, labels, k)

AttributeError: module 'kNN' has no attribute 'classfiy'

你这个文件是不是就叫 kNN.py ?如果是的话那你这个里面根本就没有 classfiy 这个属性,当然会报错。

另外,import kNN 是 import 自己?

上文借用了numpy和pandas等模块自编了k-近邻算法 python之k-近邻算法(非sklearn版) ,这次借用sklearn轮子来实现一下

数据还是用上篇文章的数据来 https://pan.baidu.com/s/1zIGz6GtEU20UeT6hemP4MQ

上篇文章我们是利用KNN.py中的自编函数panduan在读取数据的过程中来实现的,而这种转变在sklearn中已经有轮子调用了

这里再补充一点:对于类别数据(对于特征值也是适用的),可以分为 标称特征(nominal feature) 有序特征(ordinal feature) .

对于我们这里的数据largeDoses,smallDoses,didntLike应该是对应着有序特征

如果在这里'喜欢的类别'本身不带有有序的含义的话,即largeDoses,smallDoses,didntLike三个类别没有序别之分,可以借用sklearn里的功能

可以看到借用sklearn是比较方便的

但是。。。。。但是。。。。以上的0,1,2在算法看来依然是有顺序的,所以我们可以利用 独热编码(one-hot encoding) ,即创建一个新的虚拟特征(dummy feature)

也可以利用pandas里的功能

————————————————————————————————————

特征缩放(feature scaling)对于除了决策树和随机森林两个算法没用以外,对其他算法和优化算法来讲都是必不可少的

即上篇文章所涉及到的

对于线性模型来讲,标准化更加好,一是符合线性模型对权重的处理,二是保留了异常值的信息

———————————————————————————————————

上篇文章对于此类问题的处理见 datingClassTest 函数

K-近邻算法被称之为 惰性算法 ,和其他机器学习算法不一样,因为他仅仅是对训练数据集有记忆功能,而不是从训练集中通过学习得到一个判别函数,即不需要训练,看过上篇文章的小伙伴应该会有体会。 缺点是计算复杂度会随着样本数量的增长而呈线性增长,除非数据集中特征数量有限