约会网站实列(k近邻算法)
什么是k近邻算法
K近邻(K-Nearest Neighbors, KNN)算法是一种常用的监督学习算法,用于解决分类和回归问题。KNN算法基于数据实例之间的相似性度量来进行预测。其核心思想是:如果一个样本在特征空间中的k个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别。
KNN算法的基本原理:
1.计算样本之间的距离:KNN算法通过计算样本之间的距离来度量它们的相似性。常用的距离度量方法包括欧氏距离、曼哈顿距离、闵可夫斯基距离等。
2.确定邻居数K:选择一个合适的邻居数K,表示在预测时将考虑最近的K个邻居的类别。那么该如何确定K取多少值好呢?答案是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的方差,最终找到一个比较合适的K值。
3.确定类别:找出与待预测样本距离最近的K个训练样本,根据它们的类别决定待预测样本的类别。对于分类问题,通常采用多数表决的方式确定类别;对于回归问题,通常取K个最近邻样本的平均值作为预测输出。
KNN算法的特点
优点:
简单易实现:KNN算法的原理简单,易于理解和实现,无需训练过程。
适用于多分类问题:KNN算法可以应用于多分类问题,并且对样本分布的假设较少。
对异常值不敏感:KNN算法对异常值不敏感,因为它是通过距离计算来确定最近邻样本,即使某 个样本是异常值,也不会对整体结果产生很大影响。
缺点:
计算复杂度高:KNN算法需要计算测试样本与所有训练样本之间的距离,计算复杂度较高,尤其 是在大规模数据集上。
高度数据相关:KNN算法依赖于特征空间中的距离度量,如果特征空间中的距离度量不合理或者 特征权重不准确,可能会导致预测性能下降。
决策边界不规则:KNN算法的决策边界通常是不规则的,因为它只考虑了局部样本的信息,而没 有对全局进行建模。
对内存要求较高,因为该算法存储了所有训练数据。预测阶段可能很慢。
正式实验
实验目的:
评估KNN算法在约会网站数据集上的性能,以预测个人对约会对象的喜好程度。
实验数据集:
使用约会网站数据集,包含每个人的三个特征值:玩视频游戏的时间百分比、每周消费的冰淇淋公升数、每周出去约会的次数,以及对约会对象的喜好程度标签(不喜欢的人、魅力一般的人、极具魅力的人)。
实验步骤:
数据预处理:对特征值进行标准化处理,确保它们具有相同的量级。
划分数据集:将数据集分为训练集和测试集,通常采用交叉验证的方式。
模型训练:使用训练集训练KNN分类器,选择合适的K值。
模型评估:使用测试集评估模型性能,通常使用准确率等指标。
实验数据:
一.读文件生成矩阵
def file2matrix(filename):
fr = open(filename)
arrayOLines = fr.readlines() #注意需要加s
numberOfLines = len(arrayOLines)
returnMat = zeros((numberOfLines,3))
classLabelVector = []
index = 0
for line in arrayOLines:
line = line.strip()
listFormLine = line.split('\t')
for x in range(0,3):
returnMat[index,x] = float(listFormLine[x])
classLabelVector.append(int(listFormLine[-1])) # -1 为最后一个元素
index += 1
return returnMat,classLabelVector代码片
二. 分析数据:使用Matplotlib创建散点图
三.归一化数值
特征值的大小不同,所以就会对结果的影响程度不同。这就需要我们归一化特征值,把每个特征值的大小固定在[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)) #element wise divide
return normDataSet, ranges, minVals
四.测试算法:完整程序验证分类器
def datingClassTest():
filename = "datingTestSet.txt"
datingDataMat, datingLabels = file2matrix(filename)
hoRatio = 0.10
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m * hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
# 前numTestVecs个数据作为测试集,后m-numTestVecs个数据作为训练集
classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 4)
print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[i]))
if classifierResult != datingLabels[i]:
errorCount += 1.0
print("错误率:%f%%" % (errorCount / float(numTestVecs) * 100))
五.使用算法:构建完整可用系统
根据问题提示输出相应的信息,判断出是否喜欢这个人
#约会网站测试函数
def classifyperson():
resultList=['讨厌', '喜欢', '非常喜欢']
percentTats=float(input("玩视频游戏所占时间百分比?"))
ffMiles=float(input("每年获得的飞行常客里程数?"))
iceCream=float(input("每周消费的冰淇淋公升数?"))
datingDatMat,datingLabels=file2matrix('datingTestSet.txt')
normMat,ranges,minVals=autoNorm(datingDatMat)
inArr=np.array([ffMiles,percentTats,iceCream])
classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
print("你喜欢这个人的程度可能是:",resultList[classifierResult-1])
实验心得
一.实验总结:
1.KNN算法是一种简单而有效的分类算法,适用于小型数据集和具有简单决策边界的问题。
2.在实验中,数据预处理对KNN算法的性能至关重要,特别是对特征值的标准化处理。
3.选择合适的K值对KNN算法的性能影响较大,需要通过交叉验证等方法进行调优。
二.进一步研究方向:
1.考虑尝试其他分类算法,比较它们在约会网站数据集上的性能。
2.探索更复杂的特征工程方法,提高模型的泛化能力。
3.对不同K值下的模型性能进行详细分析,寻找最佳的K值设置。
注:实验数据来自于多名博主。