数据以及代码参考来源:<机器学习实战>
若需要数据请自行搜索获取
0.引入必要的库
from numpy import *
from KNN import classify0 #这里存的是我写在KNN.py中的分类器代码
import matplotlib
import matplotlib.pyplot as plt
1.获得数据:从文本中读取数据
注意:笔者在这里对此函数进行了修改,主要是添加了第二个参数,使得函数方法的普适性增加,这一步的处理主要是涉及到文件的打开以及读取操作。
适用任何文本数据,以tab为分割(可自己修改),以回车为行分界的数据。可自动读取成numpy矩阵
# 程序2中的读取约会文本数据的程序
# 也是一个通用的,读取文本数据的程序(与数据格式相类似的)
# 输入:文件名或者文件的路径;col:需要从文本数据中读取的列数
# 文件读取两次的问题需要注意应该是由于操作对当前游标的位置问题,具体代码中有解释
def file2matrix(filename,col):
fr = open(filename)
numberOfLines = len(fr.readlines()) #获取实例的长度/数量
returnMat = zeros((numberOfLines,col)) #准备一个矩阵,用于存放数据
classLabelVector = [] #一个用于存放标签的列表
index = 0
fr=open(filename) #这里貌似是因为,len文件的长度后,光标就已经到文本的末尾了,再继续按行读取就无法读取到任何数据
for line in fr.readlines(): #按行读取
#strip()方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
line = line.strip()
listFromLine = line.split('\t') #按照每遇到一个tab键进行分割
returnMat[index,:] = listFromLine[0:col] #将对应的值放入矩阵
classLabelVector.append(int(listFromLine[-1])) #对应的标签放去矩阵
index += 1 #矩阵索引+1
return returnMat,classLabelVector
2.分析数据:通过图像来观察数据的结构
注意:程序中的x,y为上文读取数据后返回的数据,在本代码段用#注释掉了
#x,y=file2matrix("C:\\Users\\70956\\Desktop\\Data Science\\Algorithm\\machinelearninginaction\\Ch02\\datingTestSet2.txt",3)
#使用matplotlib绘制散点图
fig = plt.figure() #创建一个图
#111”表示“1×1网格,第一子图”,“234”表示“2×3网格,第四子图”。
ax = fig.add_subplot(111)
#绘制散点图的函数scatter()
#这个地方我建议大家不要省略参数标识,就是比如这种写法
#这里表示点的颜色和大小都根据标签来,这样在图上就有三种颜色和大小的点
#ax.scatter(x[:,1],x[:,2],15.0*array(y),15.0*array(y))
ax.scatter(x[:,0],x[:,1],s=15.0*array(y),c=15.0*array(y))
plt.show()
3.数据分析:归一化处理
主要是消除各个特征由于单位的不统一,或者一些原因造成的某一特征的变化对距离测算时的不正常,不正确的影响。引用书中的一段原话:
数字差值最大的属性对计算结果的影响最大,也就是说,每年 获取的飞行常客里程数对于计算结果的影响将远远大于表2-3中其他两个特征——玩视频游戏的 和每周消费冰淇淋公升数——的影响。而产生这种现象的唯一原因,仅仅是因为飞行常客里程数
远大于其他特征值。但海伦认为这三种特征是同等重要的,因此作为三个等权重的特征之一
此方法函数可以用来对任意需要进行归一化操作的矩阵进行归一化。公式如下:
归
一
化
值
=
(
原
值
−
m
i
n
)
/
(
M
a
x
−
M
i
n
)
归一化值=(原值-min)/(Max-Min)
归一化值=(原值−min)/(Max−Min)
归一化
def autoNorm(dataSet):
minVals = dataSet.min(0) #每列的最小值,返回一个数组。数组的行列操作中,一般都是行=1,列=0
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet)) #创建归一化后的数组
m = dataSet.shape[0] #获取一共有多少条记录
normDataSet = dataSet - tile(minVals, (m,1)) #又用到了tile函数,现在是存的一个差值矩阵,m行
normDataSet = normDataSet/tile(ranges, (m,1)) #除法,求出归一化的值
return normDataSet, ranges, minVals
4.实例测试实现
将上述的算法细节进行代码实现以后,就可以通过调用函数的形式进行算法的验证了。
严格按照以下步骤进行:(复习一遍kNN)
- 获取数据,进行测试集/训练集划分
- 测试数据传递至分类器,通过kNN算法(计算距离,判定类别)得到判定类别
- 与真实类别进行对比
- 统计错误数量,进行错误率计算。
#本地测试分类器代码
def datingClassTest():
hoRatio = 0.03 #hold out 10%
datingDataMat,datingLabels = file2matrix('C:\\Users\\70956\\Desktop\\Data Science\\Algorithm\\machinelearninginaction\\Ch02\\datingTestSet2.txt',3) #load data setfrom file
normMat, ranges, minVals = autoNorm(datingDataMat) #归一化
m = normMat.shape[0] #实例数量
numTestVecs = int(m*hoRatio) #测试集数量
errorCount = 0.0
train=normMat[numTestVecs:m,:] #本人添加,方便理解,就是测试集之外的就是用于计算距离的参考集合
train_labels=datingLabels[numTestVecs:m] #本人添加,方便理解,就是测试标签之外的就是用于计算距离的参考集合
for i in range(numTestVecs): #测试个数
classifierResult = classify0(normMat[i,:],train,train_labels,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(errorCount)
5.总结
通过此例,我们能够清楚的了解到使用KNN算法解决一个经典机器学习算法的步骤,流程非常经典:获取数据,查看数据,数据分析,得出分类器的效果。