
提示:机器学习第一次作业。
提示:以下是本篇文章正文内容,下面案例可供参考
1.1算法介绍
KNN的全称是K Nearest Neighbors,意思是K个最近的邻居。K个最近邻居,毫无疑问,K的取值肯定是至关重要的。KNN的原理就是当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别。
图中绿色的点就是我们要预测的那个点,假设K=3。那么KNN算法就会找到与它距离最近的三个点(这里用圆圈把它圈起来了),看看哪种类别多一些,比如这个例子中是蓝色三角形多一些,新来的绿色点就归类到蓝三角了。当k=5时,判定结果就不一样了,这次变成红圆多一些,所以新来的绿点被归类成红圆。从这个例子中,我们就能看得出K的取值是很重要的。
1.2K值的选取和点距离的计算
二维平面两点间的距离:A(x1,y1),B(x2,y2)
若扩展到多维:
如何确定K取多少值好呢?答案是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的方差,最终找到一个比较合适的K值。
1.在约会网站上使用k-近邻算法的步骤
(1) 收集数据:提供文本文件。
(2) 准备数据:使用Python解析文本文件。
(3) 分析数据:使用Matplotlib画二维扩散图。
(4) 训练算法:此步骤不适用于k-近邻算法。
(5) 测试算法:使用海伦提供的部分数据作为测试样本。测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
(6) 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
在kNN.py中创建名为file2matrix的函数,以此类处理输入格式问题。该函数的输入为文件名字符串,输出为训练样本矩阵和类标签向量。代码如下:
#输入为文件名字符串,输出为训练样本矩阵和类标签向量
def file2matrix(filename):
'''
函数作用:从文件中读入训练数据,并且存储为矩阵
:param filename:文件名字符串
:return:训练样本矩阵和类标签向量
'''
fr = open(filename) #打开文件
arrayOLines = fr.readlines() #读取文件内容
numberOflines = len(arrayOLines) #得到文件行数
returnMat = zeros((numberOflines,3)) #返回解析后的数据
classLabelVector = [] #定义类标签向量
index = 0
for line in arrayOLines:
line = line.strip() #截取掉所有的回车字符
listFromLine = line.split('t') #用‘t’将行数据分割成元素列表
returnMat[index,:] = listFromLine[0:3] #选取前三个数据将他们存储到特征矩阵中
classLabelVector.append(int(listFromLine[-1])) #把该样本对应的标签放置标签向量,顺序与样本集对应
index += 1
return returnMat,classLabelVector
2.分析数据:使用Matplotlib创建散点图
(1)原始数据的散点图
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
'''
散点图使用datingDataMat矩阵的第二,第三列数据,分别表示特征值“玩视频游戏所耗时间百分比”
和“每周所消费的冰淇凌公升数”
'''
#无样本类别标签的约会数据散点图
ax.scatter(datingDataMat[:,1],datingDataMat[:,2])
#加入这两行可以避免plt画图报找不到字体的错误,这样就可以输出中文字体
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.xlabel('玩视频游戏所耗时间百分比')
plt.ylabel('每周消费的冰淇淋公升数')
plt.show()
原始数据散点图难以辨识图中的点究竟属于哪个分类
(2)带有分类标签的约会数据散点图
#带有分类标签的约会数据散点图
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
(3)改进带有分类标签散点图
import numpy as np
dating_data_mat, dating_labels = kNN.file2matrix('datingTestSet2.txt')
fig = plt.figure()
ax = fig.add_subplot(111)
dating_labels = np.array(dating_labels)
idx_1 = np.where(dating_labels == 1)
p1 = ax.scatter(dating_data_mat[idx_1, 0], dating_data_mat[idx_1, 1], marker='o', color='r', label='不喜欢', s=30)
idx_2 = np.where(dating_labels == 2)
p2 = ax.scatter(dating_data_mat[idx_2, 0], dating_data_mat[idx_2, 1], marker='o', color='g', label='魅力一般', s=45)
idx_3 = np.where(dating_labels == 3)
p3 = ax.scatter(dating_data_mat[idx_3, 0], dating_data_mat[idx_3, 1], marker='o', color='b', label='极具魅力', s=60)
plt.legend(loc='upper left')
plt.xlabel("每年获取的飞行常客历程数")
plt.ylabel("玩游戏所耗时间百分比")
plt.show()
3.准备数据:归一化数值
在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。
#归一化特征值,将数字特征值转化为0到1的区间
def autonorm(dataSet):
minVals = dataSet.min(0) #存放每列最小值
maxVals = dataSet.max(0) #存放每列最大值
ranges = maxVals - minVals #最大值与最小值的差值
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals,(m,1))
normDataSet = normDataSet/tile(ranges,(m,1))
return normDataSet,ranges,minVals
4.测试算法:作为完整程序验证分类器
#分类器针对约会网站的测试代码
def datingClassTest():
hoRatio = 0.50 #hold out 10%
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file
normMat, ranges, minVals = autonorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],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)))
5.使用算法:构建完整可用系统
def classifyPerson():
#类标签列表
resultlist = ['讨厌', '一般喜欢', '非常喜欢']
#用户输入不同特征值
precentTats = float(input("玩视频游戏所占时间百分比?"))
ffMiles = float(input("每年获得的飞行常客里程数?"))
iceCream = float(input("每周消费的冰淇淋公升数?"))
#打开文件并处理数据
datingDataMat,datingLabels = kNN.file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autonorm(datingDataMat) #归一化训练集
inArr = np.array([precentTats, ffMiles, iceCream]) #创建测试集数组
norm_in_arr = (inArr - minVals) / ranges #归一化测试集
# 返回分类结果
classifierResult = classify0(norm_in_arr, normMat, datingLabels, 3) #返回分类结果
#输出结果
print("你对这个人的感觉可能是: ", resultList[classifierResult - 1])
实现结果:
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
注:以上代码均来自机器学习实战。