您的位置:首页 > 其它

机器学习实战源码KNN

2016-05-18 18:01 330 查看
按照《机器学习实战》这书的内容来,稍微总结一下。

数据格式:

数据中的格式应该是 特征1 特征2
特征3 ...类别,中间是tab键分割

1.读文件。

将文件中的数据,特征读到numpy array数组之中,类似于矩阵。特征读到list当中。先读,然后每一行进行处理,处理包括用\t进行分割,然后加到特征数组

特征加到特征的list当中。

#读文件,将文件读到array里。返回一个属性的array[m,n]和一个标签的list
def file2matrix(filename):
fr=open(filename)
arrayOLines=fr.readlines()
numberOfLines=len(arrayOLines)
returnMat=zeros((numberOfLines,3))
classLabelVector=[]
index=0
for line in arrayOLines:
line=line.strip()
listFromLine=line.split('\t')
returnMat[index,:]=listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index+=1
return returnMat,classLabelVector


2.数据归一化。

先求得整个矩阵的数据每列的最小值和最大值,然后就可以将(每个元素-最小)/(最大元素-最小元素)得到一个0~1之间的数据。

#数据归一化
def autoNorm(dataSet):
#0代表是按列计算
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


3.KNN的核心算法。

将要预测的元素(假设是1*n)进行列向复制,得到m*n的矩阵,跟特征矩阵形状一样。然后减去特征矩阵,这样得到待预测项与每一个样本的差,然后对整个残差矩阵进行求和,得到一个m*1的一个矩阵,每个元素代表待预测数据向量与样本的距离。然后求根,再取最小的K个。得到了跟待测数据向量最相似的K个数据。最后统计这K个里面的标签值,哪个最多,就为预测值。

'''main coding of classify,select top k of similarity
intX代表要预测的输入向量,dataset是特征矩阵(array类型),labels是标签列表(list),k代表取前几个相似'''
def classify0(inX,dataSet,labels,k):
dataSetsize=dataSet.shape[0]
#比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,在这里是将向量intX列方向进行复制。
diffMat=tile(inX,(dataSetsize,1))-dataSet
sqDiffMat=diffMat**2
#求每一行的残差和
sqDistances=sqDiffMat.sum(axis=1)
distances=sqDistances**0.5
#求的索引的排序值。a=array([1,2,3,5,4,6])使用函数输出array([0, 1, 2, 4, 3, 5])
sortedDistIndicies=distances.argsort()
#字典的存储结果为  {类别:数量}
classCount={}
for i in range(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]


4.测试

读文件,进行归一化操作后,选取前面的numTestVecs个样本为测试集。对测试集中的数据,分别与训练集中的数据进行KNN算法的预测。

#算法的基本测试
def datingClassTest():
#测试集的比例
hoRatio=0.10
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
normMat,ranges,minVals=autoNorm(datingDataMat)
m=normMat.shape[0]
errorCount=0.0
numTestVecs=int(m*hoRatio)
for i in range(numTestVecs):
classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],\
datingLabels[numTestVecs:m],10)
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 errorrate is %f" % (errorCount/float(numTestVecs))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: