机器学习实战:k-临近算法(二)

海伦一直在使用在线约会网站寻找合适自己的约会对象,经过一番总结,海伦整理了以下数据,希望我们的分类软件可以更好地帮助她将匹配对象划分到确切的分类中

1、收集数据

40920	8.326976	0.953952	largeDoses
14488	7.153469	1.673904	smallDoses
26052	1.441871	0.805124	didntLike
75136	13.147394	0.428964	didntLike
38344	1.669788	0.134296	didntLike
72993	10.141740	1.032955	didntLike
35948	6.830792	1.213192	largeDoses
42666	13.276369	0.543880	largeDoses
67497	8.631577	0.749278	didntLike
35483	12.273169	1.508053	largeDoses
50242	3.723498	0.831917	didntLike
63275	8.385879	1.669485	didntLike
5569	4.875435	0.728658	smallDoses
51052	4.680098	0.625224	didntLike
77372	15.299570	0.331351	didntLike
43673	1.889461	0.191283	didntLike
61364	7.516754	1.269164	didntLike
69673	14.239195	0.261333	didntLike
......

第一列:每年获得的飞行常客里程数

第二列:玩视频游戏所耗时间百分比

第三列:每周消费的冰淇淋公升数

第四列:海伦对数据的分类

largeDoses表示对海伦极具魅力的人

smallDoses表示对海伦魅力一般的人

didntlike表示海伦不喜欢的人


2、准备数据

(1)首先将分类的标签转为数字

largeDoses:用3表示

smallDoses:用2表示

didntlike:用1表示

新的数据如下:

40920	8.326976	0.953952	3
14488	7.153469	1.673904	2
26052	1.441871	0.805124	1
75136	13.147394	0.428964	1
38344	1.669788	0.134296	1
72993	10.141740	1.032955	1
35948	6.830792	1.213192	3
42666	13.276369	0.543880	3
67497	8.631577	0.749278	1
35483	12.273169	1.508053	3
50242	3.723498	0.831917	1
63275	8.385879	1.669485	1
5569	4.875435	0.728658	2
51052	4.680098	0.625224	1
77372	15.299570	0.331351	1
43673	1.889461	0.191283	1
61364	7.516754	1.269164	1
69673	14.239195	0.261333	1
......

(2)用Python读取文件,将文件中的内容转为矩阵

#将文件转为矩阵
def file2matrix(filename):
	fr=open(filename)#打开文件
	arrayOLines=fr.readlines()#读取整个文件,分析成一个行的列表
	numberOfLines=len(arrayOLines)#文件行数
	returnMat=zeros((numberOfLines,3))#创建len行3列的矩阵
	classLabelVector=[]#定义存储标签的对象
	index=0
	#遍历文件每一行
	for line in arrayOLines:
		line=line.strip()#截取掉回车字符
		listFromLine=line.split('\t')#根据\t tab将一行的内容分割
		returnMat[index,:] = listFromLine[0:3]#选取分割后的前三个元素,returnMat[index,:]表示取得第index行的所有元素
		classLabelVector.append(int(listFromLine[-1]))#向标签列表中添加该条数据对应的分类
		index += 1
	return returnMat,classLabelVector

data,label=file2matrix('datingTestSet2.txt')
print(data)
print(label)
测试:

[[  4.09200000e+04   8.32697600e+00   9.53952000e-01]
 [  1.44880000e+04   7.15346900e+00   1.67390400e+00]
 [  2.60520000e+04   1.44187100e+00   8.05124000e-01]
 ..., 
 [  2.65750000e+04   1.06501020e+01   8.66627000e-01]
 [  4.81110000e+04   9.13452800e+00   7.28045000e-01]
 [  4.37570000e+04   7.88260100e+00   1.33244600e+00]]
[3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 2, 1, 2, 3, 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, 2, 1, 1, 2, 3, 3, 1, 2, 3, 3, 3, 1, 1, 1, 1, 2, 2, 1, 3, 2, 2, 2, 2, 3, 1, 2, 1, 2, 2, 2, 2, 2, 3, 2, 3, 1, 2, 3, 2, 2, 1, 3, 1, 1, 3, 3, 1, 2, 3, 1, 3, 1, 2, 2, 1, 1, 3, 3, 1, 2, 1, 3, 3, 2, 1, 1, 3, 1, 2, 3, 3, 2, 3, 3, 1, 2, 3, 2, 1, 3, 1, 2, 1, 1, 2, 3, 2, 3, 2, 3, 2, 1, 3, 3, 3, 1, 3, 2, 2, 3, 1, 3, 3, 3, 1, 3, 1, 1, 3, 3, 2, 3, 3, 1, 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 1, 1, 3, 2, 3, 3, 1, 2, 1, 3, 1, 2, 3, 2, 3, 1, 1, 1, 3, 2, 3, 1, 3, 2, 1, 3, 2, 2, 3, 2, 3, 2, 1, 1, 3, 1, 3, 2, 2, 2, 3, 2, 2, 1, 2, 2, 3, 1, 3, 3, 2, 1, 1, 1, 2, 1, 3, 3, 3, 3, 2, 1, 1, 1, 2, 3, 2, 1, 3, 1, 3, 2, 2, 3, 1, 3, 1, 1, 2, 1, 2, 2, 1, 3, 1, 3, 2, 3, 1, 2, 3, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 2, 1, 1, 1, 3, 3, 2, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 3, 2, 3, 3, 3, 3, 1, 2, 3, 1, 1, 1, 3, 1, 3, 2, 2, 1, 3, 1, 3, 2, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 3, 3, 2, 3, 3, 2, 3, 1, 3, 1, 3, 3, 1, 3, 2, 1, 3, 1, 3, 2, 1, 2, 2, 1, 3, 1, 1, 3, 3, 2, 2, 3, 1, 2, 3, 3, 2, 2, 1, 1, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 3, 3, 2, 3, 2, 1, 1, 1, 1, 1, 3, 2, 2, 1, 2, 1, 3, 2, 1, 3, 2, 1, 3, 1, 1, 3, 3, 3, 3, 2, 1, 1, 2, 1, 3, 3, 2, 1, 2, 3, 2, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 3, 1, 1, 2, 2, 1, 2, 2, 2, 3, 1, 1, 1, 3, 1, 3, 1, 3, 3, 1, 1, 1, 3, 2, 3, 3, 2, 2, 1, 1, 1, 2, 1, 2, 2, 3, 3, 3, 1, 1, 3, 3, 2, 3, 3, 2, 3, 3, 3, 2, 3, 3, 1, 2, 3, 2, 1, 1, 1, 1, 3, 3, 3, 3, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 2, 3, 2, 1, 2, 2, 2, 3, 2, 1, 3, 2, 3, 2, 3, 2, 1, 1, 2, 3, 1, 3, 3, 3, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 3, 2, 1, 3, 3, 2, 2, 2, 3, 1, 2, 1, 1, 3, 2, 3, 2, 3, 2, 3, 3, 2, 2, 1, 3, 1, 2, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 2, 2, 1, 3, 1, 1, 3, 2, 3, 1, 1, 3, 1, 3, 3, 1, 2, 3, 1, 3, 1, 1, 2, 1, 3, 1, 1, 1, 1, 2, 1, 3, 1, 2, 1, 3, 1, 3, 1, 1, 2, 2, 2, 3, 2, 2, 1, 2, 3, 3, 2, 3, 3, 3, 2, 3, 3, 1, 3, 2, 3, 2, 1, 2, 1, 1, 1, 2, 3, 2, 2, 1, 2, 2, 1, 3, 1, 3, 3, 3, 2, 2, 3, 3, 1, 2, 2, 2, 3, 1, 2, 1, 3, 1, 2, 3, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 3, 1, 2, 3, 2, 2, 3, 1, 2, 3, 2, 3, 1, 2, 2, 3, 1, 1, 1, 2, 2, 1, 1, 2, 1, 2, 1, 2, 3, 2, 1, 3, 3, 3, 1, 1, 3, 1, 2, 3, 3, 2, 2, 2, 1, 2, 3, 2, 2, 3, 2, 2, 2, 3, 3, 2, 1, 3, 2, 1, 3, 3, 1, 2, 3, 2, 1, 3, 3, 3, 1, 2, 2, 2, 3, 2, 3, 3, 1, 2, 1, 1, 2, 1, 3, 1, 2, 2, 1, 3, 2, 1, 3, 3, 2, 2, 2, 1, 2, 2, 1, 3, 1, 3, 1, 3, 3, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 3, 2, 2, 1, 3, 1, 2, 3, 1, 3, 1, 3, 1, 1, 3, 2, 3, 1, 1, 3, 3, 3, 3, 1, 3, 2, 2, 1, 1, 3, 3, 2, 2, 2, 1, 2, 1, 2, 1, 3, 2, 1, 2, 2, 3, 1, 2, 2, 2, 3, 2, 1, 2, 1, 2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 3, 1, 1, 3, 2, 1, 2, 1, 2, 2, 3, 2, 2, 2, 3, 1, 2, 1, 2, 2, 1, 1, 2, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 2, 3, 3, 2, 2, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 2, 1, 2, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 3, 2, 2, 1, 3, 1, 2, 3, 1, 2, 2, 2, 2, 3, 2, 3, 3, 1, 2, 1, 2, 3, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 3, 3]


3、分析数据

(1)使用Matplotlib创建散点图

         导入matplotlib

# -*- coding:utf-8 -*-
from numpy import *
import operator
import matplotlib
import matplotlib.pyplot as plt

#将文件转为矩阵
def file2matrix(filename):
	fr=open(filename)#打开文件
	arrayOLines=fr.readlines()#读取整个文件,分析成一个行的列表
	numberOfLines=len(arrayOLines)#文件行数
	returnMat=zeros((numberOfLines,3))#创建len行3列的矩阵
	classLabelVector=[]#定义存储标签的对象
	index=0
	#遍历文件每一行
	for line in arrayOLines:
		line=line.strip()#截取掉回车字符
		listFromLine=line.split('\t')#根据\t tab将一行的内容分割
		returnMat[index,:] = listFromLine[0:3]#选取分割后的前三个元素,returnMat[index,:]表示取得第index行的所有元素
		classLabelVector.append(int(listFromLine[-1]))#向标签列表中添加该条数据对应的分类
		index += 1
	return returnMat,classLabelVector

data,label=file2matrix('datingTestSet2.txt')

#画散点图
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(data[:,1],data[:,2])#选择数据集的第二列(玩游戏所占时间比)的值作为x轴,第三列(冰淇淋公升数)的值作为y轴
plt.show()#显示散点图



从散点图上看不出什么有用的信息,所以我们来改一下程序:

#第一个参数:选择数据集的第二列(玩游戏所占时间比)的值作为x轴
#第二个参数:第三列(冰淇淋公升数)的值作为y轴
#第三个参数和第四个参数:代表颜色和大小同时放大15倍,这时,同一类标签颜色和大小相同
ax.scatter(data[:,1],data[:,2],15.0*array(label),15.0*array(label))
参考: http://blog.csdn.net/abcjennifer/article/details/19848269

此时散点图:

从图中可以看出数据已经和对应的分类标签挂钩,基本上可以看到数据点所属三个样本分类的区域轮廓,绿色、黄色、重紫色(就这么叫吧)分别代表了不同的分类,同一分类下的点大小和颜色都相同。

下面将飞行常客旅行数作为x轴数据,玩视频游戏所耗时间百分比作为y轴数据来看一下散点图的情况:

此图清晰的标识了三个不同的样本分类区域,更容易区分数据点从属的类别。


4、归一化数值

(1)取一些样本数据

假如想计算样本三和样本4之间的距离,需要使用如下的方法:

从方程中很容易发现,数字差值最大的属性对计算结果影响最大,也就是飞行常客里程数对于计算结果的影响将远远大于玩视频游戏所占时间比和每周消费冰淇淋公升数这两个特征,原因是飞行常客旅程数的数值远大于其他特征值的值,但是海伦认为这三种特征是同等重要的,飞行常客里程数不应该如此严重的影响到计算结果。

处理这种不同取值范围的特征值时,通常采用的办法是将数值归一化,比如将数值的范围处理为0到1之间的值。下面的公式可以将取值范围转换到0和1之间:

newValue=(oldValue-min)/(max-min)

max:数据集中最大特征值

min:数据集中最小特征值

下面定义一个函数,对数据进行归一化处理:

#归一化
def autoNorm(dataSet):
	minVals=dataSet.min(0)#获取每一列的最小值
	maxVals=dataSet.max(0)#获取每一列的最大值
	ranges=maxVals-minVals#max-min差值
	normDataSet=zeros(shape(dataSet))#zeros函数用来创建给定的矩阵类型,并初始化为0
	m=dataSet.shape[0]#获取数据集行数
	normDataSet=dataSet-tile(minVals,(m,1))#将minVals为变为m行的矩阵(oldValue-min)
	normDataSet=normDataSet/tile(ranges,(m,1))#将ranges变为m行的矩阵(oldValue-min)/(max-min)
	return normDataSet,ranges,minVals

每一列的最小值:minVals=[ 0.        0.        0.001156] 

每一列的最大值:maxVals=[  9.12730000e+04   2.09193490e+01   1.69551700e+00]

max-min对应的是ranges

由于minVals是一行三列的矩阵,为了便于相减,使用tile函数将minVals变为m行三列的矩阵,m为数据集的行数

同样的办法将ranges变为m行三列的矩阵,便于相除



机器学习实战代码下载:http://vdisk.weibo.com/s/uEZesAafcjQgx

来自:机器学习实战

Python知识参考:

http://blog.csdn.net/werm520/article/details/6898473


你可能感兴趣的:(机器学习)