本系列教程为《机器学习实战》的读书笔记。首先,讲讲写本系列教程的原因:第一,《机器学习实战》的代码由Python2编写,有些代码在Python3上运行已会报错,本教程基于Python3进行代码的修订;第二:之前看了一些机器学习的书籍,没有进行记录,很快就忘记掉了,通过编写教程也是一种复习的过程;第三,机器学习相对于爬虫和数据分析而言,学习难度更大,希望通过本系列文字教程,让读者在学习机器学习的路上少走弯路。
这里海伦收集了1000行数据,有三个特征:每年获得的飞行常客里程数;玩视频游戏所耗时间百分比;每周消费的冰淇淋公升数。以及对象的类型标签,如图所示。
import numpy as np
import operator
def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines()
numberOflines = len(arrayOLines)
returnMat = np.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 = index + 1
return returnMat, classLabelVector
定义解析数据的函数:4-9行:读取文件,并获取文件行数,创建一个文件行数(1000行)和3列的Numpy全0数组,创建用于存放类标签的classLabelVector列表。
10-17行:对文件进行循环遍历,对前三列数据存放到returnMat数组中,最后一列存放到classLabelVector列表中。结果如图所示。
上面的代码为书中所写,其实用pandas读取数据后再出来是很方便了,代码如下:
import numpy as np
import operator
import pandas as pd
def file2matrix(filename):
data = pd.read_table(open(filename), sep='\t', header=None)
returnMat = data[[0,1,2]].values
classLabelVector = data[3].values
return returnMat, classLabelVector
由于特征间的数值差别太大,在计算距离时,数值大的属性会对结果产生更大的影响,这里需要对数据进行归一化:new = (old-min)/(max-min)。代码如下:
def autoNorm(dataSet):
minval = dataSet.min(0)
maxval = dataSet.max(0)
ranges = maxval - minval
normDataSet = np.zeros(np.shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - np.tile(minval, (m,1))
normDataSet = normDataSet/np.tile(ranges, (m,1))
return normDataSet, ranges, minval
传入的参数为测试数据(就是returnMat);首先按0轴(也就是按列)进行min和max的计算,如图所示进行简单的示例;然后构造和数据(normDataSet)一样大小的0矩阵;
tile函数的用法读者可以自行百度,这里看下使用后的案例,作用就是让一维数组重复m行,如图所示,这样就可以进行数据归一化的计算。
这里使用的距离为欧式距离,公式为:
def classify(inX, dataSet, labels, k):
dataSize = dataSet.shape[0]
diffMat = np.tile(inX, (dataSize,1)) -dataSet
sqdiffMat = diffMat ** 2
sqDistance = sqdiffMat.sum(axis = 1)
distances = sqDistance ** 0.5
sortedDist = distances.argsort()
classCount ={}
for i in range(k):
voteIlable = labels[sortedDist[i]]
classCount[voteIlable] = classCount.get(voteIlable, 0) + 1
sortedClassCount = sorted(classCount.items(),
key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
inX为训练数据;dataSet为测试数据,labels为类别标签;k为取值;
2-6行:计算欧式距离
7-最后:对计算的距离进行索引排序(argsort),然后对字典进行排序,获取值最多的分类。
这里选择前10%数据做为测试样本,进行分类器的测试。
def test():
r = 0.1
X, y = file2matrix('数据/datingTestSet2.txt')
new_X, ranges, minval = autoNorm(X)
m = new_X.shape[0]
numTestVecs = int(m*r)
error = 0.0
for i in range(numTestVecs):
result = classify(new_X[i, :],new_X[numTestVecs:m, :], y[numTestVecs:m], 3)
print('分类结果: %d, 真实数据: %d' %(result, y[i]))
if (result != y[i]):
error = error + 1.0
print('错误率: %f' % (error/float(numTestVecs)))
最后,编写一个简单的测试系统,该代码通过人为的输入三个属性特征,可以自动得到该约会对象的分类标签。
def system():
style = ['不喜欢', '一般', '喜欢']
ffmile = float(input('飞行里程'))
game = float(input('游戏'))
ice = float(input('冰淇淋'))
X, y = file2matrix('数据/datingTestSet2.txt')
new_X, ranges, minval = autoNorm(X)
inArr = np.array([ffmile, game, ice])
result = classify((inArr - minval)/ranges, new_X, y, 3)
print('这个人', style[result - 1])
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。