纯为自己学习所用
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 04 17:56:28 2016

@author: aihid
"""


from numpy import *
import operator
from os import listdir
"""
创建一个基本的数据包

"""
def createDataSet():
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels

"""
k-近邻算法:

sum(axis=0)
将数组第一维相加
sum(axis=1)
将数组第二维相加
argsort()
将数组按从大到小排序,数值其在原数组中的序列号
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
计算某一类型的数量
sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
将集合排序,key=operator.itemgetter(1)根据第二个关键字;reverse=true按从大到小排序

"""
def classfy0(inX,dataSet,labels,k):
    dataSetSize=dataSet.shape[0]
    diffMat=tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat=diffMat**2
    sqDistances=sqDiffMat.sum(axis=1)
    distances=sqDistances**0.5
    sortedDistIndicies=distances.argsort()
    classCount={}
    for i in range(0,k):
        voteIlabel=labels[sortedDistIndicies[i]]
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

"""
从文本文件中解析数据
zeros((x,y))
生成一个x*y的一个数组
strip()
去除行头行末的空格
split('\t')
在Tab符方向切割
"""   
def file2matrix(filename):
    fr=open(filename)
    arrayOLines=fr.readlines()
    numberOfLines=len(arrayOLines)
    returnMat=zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    i=0
    for line in arrayOLines:
        line=line.strip()
        listFromLine=line.split('\t')
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index=index+1    
    return returnMat,classLabelVector

"""
分析数据
import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(r[:,1],r[:,2],15.0*array(c),15.0*array(c))
plt.show()
15.0是大小
绘图函数

""" 
"""
r,c=file2matrix('datingTestSet2.txt')
import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(r[:,1],r[:,2],15.0*array(c),15.0*array(c))
plt.show()
"""
"""
统一数据:归一数值

"""
def autoNorm(dataSet):
    minVals=dataSet.min(0)
    maxVals=dataSet.max(0)
    ranges=maxVals-minVals
    normDataSet=zeros(shape(dataSet))
    m=dataSet.shape[0]
    normDataSet=dataSet-tile(minVals,(m,1))
    normDataSet=normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minVals

"""
分类器针对约会网站的测试代码
normMat.shape[0]
normMat 第1(0+1)维元素个数
tile(minVals,(m,1))
对minVals变为第一维为m,第二维为1的数组
"""
def datingClassTest():
    hoRatio=0.10
    datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
    normMat,ranges,minVals=autoNorm(datingDataMat)
    m=normMat.shape[0]
    numTestVecs=int(m*hoRatio)
    errorCount=0.0
    for i in range (numTestVecs):
        classifierResult = classfy0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print 'the classifier came back with: %d, the real answer is: %d' %(classifierResult, datingLabels[i])
        if(classifierResult != datingLabels[i]): errorCount += 1.0
    print "the total error rate is : %f"%(errorCount/float(numTestVecs))
    print classifierResult

"""
约会预测函数略,和上个函数类似
"""
"""
将图矩阵转换为单行矩阵
readline()每次运行会自动读取下一行
"""
def img2vector(filename):
    returnVect=zeros((1,1024))
    fr=open(filename)
    for i in range(32):
        lineStr=fr.readline()
        for j in range(32):
            returnVect[0,i*32+j]=int(lineStr[j])
    return returnVect
"""
识别手写数字
"""
def handwritingClassTest():
    hwLabels=[]
    trainingFileList=listdir('trainingDigits')
    m=len(trainingFileList)
    trainingMat=zeros((m,1024))
    for i in range (m):
        fileNameStr=trainingFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr=int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i,:]=img2vector('trainingDigits/%s' % fileNameStr)
    testFileList=listdir('testDigits')
    errorCount=0.0
    mTest=len(testFileList)
    for i in range(mTest):
        fileNameStr=testFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr=int(fileStr.split('_')[0])
        VectorUnderTest=img2vector('testDigits/%s' % fileNameStr)
        classifierResult=classfy0(VectorUnderTest,trainingMat,hwLabels,3)
        print "the %s came back with: %d ,the real answer is :%d" % (fileNameStr,classifierResult,classNumStr)
        if(classifierResult!=classNumStr):
            errorCount+=1.0
            print fileNameStr
    print "\nhe total number of errors is :%d" % errorCount
    print "\nhe total error rate is :%f" % (errorCount/float(mTest))
handwritingClassTest()