# -*- coding: utf-8 -*-
import numpy as np
import kNN
"""
函数说明:打开并解析文件,对数据进行分类:
1 代表不喜欢
2 代表魅力一般
3 代表极具魅力
Parameters:
filename 文件名
Return:
returnMat 特征矩阵
classLabelVector 分类Label向量
"""
def file2matrix(filename):
with open(filename, 'r') as fr:
arrayOfLines = fr.readlines()
#得到文件的行数
numberOfLines = len(arrayOfLines)
#返回的numpy矩阵,解析完成的数据:numberofLines行, 3列
returnMat = np.zeros((numberOfLines, 3))
#返回分类的标签向量
classLabelVector = []
#行的索引值
index = 0
for line in arrayOfLines:
#删除行头尾的空白,包括 ‘\n’,‘\t’,‘\r’,‘ ’
line = line.strip()
#提取前三列
listFromline = line.split('\t')
returnMat[index,:] = listFromline[0:3]
#根据文本中的喜欢程度进行标记:1:不喜欢,2:魅力一般, 3:极具魅力
if 'didntLike' == listFromline[-1]:
classLabelVector.append(1)
elif 'smallDoses' == listFromline[-1]:
classLabelVector.append(2)
elif 'largeDoses' == listFromline[-1]:
classLabelVector.append(3)
index += 1
return returnMat, classLabelVector
"""
在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化,
如将取值范围处理为0到1或者-1到1之间。
下面的公式可以将任意取值范围的特征值转化为0到1区间内的值:
newValue = (oldValue - min) / (max - min)
"""
"""
函授说明:对数据进行归一化
Parameters:
dataSet 特征矩阵
Returns:
normDataSet 归一化后的特征矩阵
ranges 数据范围
minVals 数据最小值
"""
def autoNorm(dataSet):
#获得数据的最小值和最大值
#min(0)返回该矩阵中每一列的最小值
#min(1)返回该矩阵中每一行的最小值
#max(0)返回该矩阵中每一列的最大值
#max(1)返回该矩阵中每一行的最大值
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
#最大值和最小值的差值
ranges = maxVals - minVals
#shape(dataSet)返回dataSet的行列数(m,n)
normDataSet = np.zeros(np.shape(dataSet))
#返回dataSet的行数
m = dataSet.shape[0]
#减去最小值
#tile(),把一个量复制,此处沿x轴复制1次,沿y轴复制m次
normDataSet = dataSet - np.tile(minVals, (m, 1))
normDataSet = normDataSet / np.tile(ranges, (m, 1))
return normDataSet, ranges, minVals
"""
机器学习算法一个很重要的工作就是评估算法的正确率,
通常我们只提供已有数据的90%作为训练样本来训练分类器,
而使用其余的10%数据去测试分类器,
需要注意的是,10%的测试数据应该是随机选择的,
由于海伦提供的数据并没有按照特定目的来排序,
所以我们可以随意选择10%数据而不影响其随机性。
"""
"""
函数说明:分类器测试函数
Parameters:
无
Returns:
无
"""
def datingCalssTest():
filename = 'datingTestSet.txt'
#返回特征矩阵和特征向量
datingDataMat, datingLabels = file2matrix(filename)
#取所有数据的10%
hoRatio = 0.1
#特征矩阵数据归一化
normMat, ranges, minVals = autoNorm(datingDataMat)
#获取特征矩阵的行数 m=1000
m = normMat.shape[0]
#10%的测试数据,即测试集 numTestVecs = 100
numTestVecs = int(m * hoRatio)
#分类错误计数
errorCount = 0.0
#range(n),从0至n-1
for x in range(numTestVecs):
#前numTestVecs的个数作为测试集,后m-numTestVecs的数据作为训练集
#Numpy 中多维数组的切片操作与 Python 中 list 的切片操作一样,
#同样由 start, stop, step 三个部分组成, 不同维度用 , 分开
classifierResult = kNN.classify(
normMat[x , :],
normMat[numTestVecs : m,:],
datingLabels[numTestVecs:m],
4)
print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[x]))
if classifierResult != datingLabels[x]:
errorCount += 1.0
print("错误率:%f%%" % ( errorCount / float(numTestVecs) * 100) )
"""
函数说明:通过输入一个人的特征,进行分类输出
Parameters:
无
Returns:
无
ranges, minVals 在这里用到了
"""
def classifyPerson():
resultList = ['讨厌', '有些喜欢', '非常喜欢']
flyMiles = float(input("每年飞行里程数:"))
gameTime = float(input("玩游戏时间所占百分比:"))
iceCream = float(input("每周吃的冰激凌升数:"))
filename = 'datingTestSet.txt'
#处理数据
datingDataMat, datingLabels = file2matrix(filename)
#归一化数据
normMat, ranges, minVals = autoNorm(datingDataMat)
#生成测试集
inX = np.array([flyMiles, gameTime, iceCream])
#测试集归一化
inX = (inX - minVals) / ranges
classifierResult = kNN.classify(inX, normMat, datingLabels, 3)
print("你可能%s这个人" % ( resultList[classifierResult - 1] ))
if __name__ == '__main__':
classifyPerson()
kNN ( 二 )
猜你喜欢
转载自blog.csdn.net/Lightlock/article/details/84451143
今日推荐
周排行