数据包在上一篇,这里不贴了。
from numpy import * # 导入科学计算包
import operator # 导入运算符模块
"""打开文件"""
def file2matrix(filename):
fr = open(filename) # 打开文件
arrarOLines = fr.readlines() # 读取内容
numberOfLines = len(arrarOLines) # 解析有多少行
returnMat = zeros((numberOfLines, 3)) # 创建行数*3的矩阵,以0填充
classLabelVector = []
index = 0
for line in arrarOLines:
line = line.strip() # 删除空白字符
listFromLine = line.split('\t') # 以空格来分割
returnMat[index, :] = listFromLine[0:3] # 前三位放入矩阵
classLabelVector.append(listFromLine[-1]) # 最后一位存入标签
index += 1
return returnMat, classLabelVector
"""分类函数"""
def classfy0(inX, dataSet, labels, k): # 参数分别为测试样本,训练样本,训练样本标签,近邻个数
dataSetSize = dataSet.shape[0] # 返回行列数,0为行,列为1
diffMat = tile(inX, (dataSetSize, 1)) - dataSet # tile是按照某个方向复制元素,行方向复制四行,列方向复制一行,然后减去每个训练样本值
sqDiffMat = diffMat ** 2 # 乘方运算
sqDistances = sqDiffMat.sum(axis=1) # 轴为1的方向(横向)求和
distances = sqDistances ** 0.5 # 乘方运算,等同于开根号
sortedDistIndicies = distances.argsort() # 返回从小到大排序的索引值(原数组不动)
classCount = {} # 字典(键值对)
for i in range(k): # for-each循环,统计前k个每个分类有多少个
voteIlabel = labels[sortedDistIndicies[i]] # 记录每个的标签
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 取出该标签的值+1(原先没有默认为0)
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1),
reverse=True) # operator.itemgetter(1)表示用键值对中的值排序,为0表示用键排序,一开始升序,reverse=True后降序
return sortedClassCount[0][0] # 返回第一个标签
"""归一化特征值"""
def autoNorm(dataSet):
minVals = dataSet.min(0) # 返回每一列的最小值
maxVals = dataSet.max(0) # 返回每一列的最大值
ranges = maxVals - minVals # 求范围
normDataSet = zeros(shape(dataSet)) # 创建一个原矩阵大小的矩阵,用0填充
m = dataSet.shape[0] # 返回行数
normDataSet = dataSet - tile(minVals, (m, 1)) # 最小值在行方向复制m行,列方向复制1行
normDataSet = normDataSet / tile(ranges, (m, 1)) # 根据公式生成新矩阵
return normDataSet, ranges, minVals
"""计算错误率"""
def datingClassTest():
hoRatio = 0.1 # 总数据的十分之一作为测试数据,十分之九作为训练数据
datingDataMat, datingLabels = file2matrix('datingTestSet.txt') # 打开文件存储数据
normMat, ranges, minVals = autoNorm(datingDataMat) # 归一化特征值
m = normMat.shape[0] # 求行数
numTestVecs = int(m * hoRatio) # 求测试个数
errorCount = 0.0
for i in range(numTestVecs): # 以该例子为例,前100个位测试数据
classifierResult = classfy0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) # 进行分类
print("the classifier came back with:%s,the real answer is:%s" % (
classifierResult, datingLabels[i])) # 输出测试答案和正确答案
if (classifierResult != datingLabels[i]):
errorCount += 1.0
print("the total error rate is:%f%%" % (errorCount / float(numTestVecs) * 100)) # 输出错误率
if __name__ == '__main__':
datingClassTest()