当前位置:   article > 正文

【机器学习】分类算法-KNN算法实践

【机器学习】分类算法-KNN算法实践

一、前言

    前面的一篇文章介绍了KNN算法的基本思想,接下来我们就根据B站UP主【abilityjh】老师的节奏,做一个关于KNN算法运用于“约会网站配对”的算法实现。当然,这个实践的代码是一样的,但是理解的话,我是用自己的话来阐述自己敲完这个算法后的理解,可能更多的是一些大白话,大家也可以去看这个老师的原视频,会有很多收获哦!

二、案例介绍

文本数据:

案例描述:我们需要通过这个DataText.txt文档中的数据来测试我们KNN的准确性,该文档有1000条数据,我们把其中一部分拿来做训练集,另一部分拿来做测试集,结合我们的KNN算法就可以来测试KNN算法的准确性。

三、KNN算法实践

(1)实践思路

如图所示:我们先用将我们txt中的文本数据,转化为对应信息的矩阵或者列表,然后我们通过txt中的数据发现“里程数”的数据比其他两项的数据大了很多,如果这样来求未知点和训练数据中点的距离的话,后两项数据太小基本,没有作用,所以这里我们通过0-1标准化对里程数据做归一化处理;然后我们把之前写的KNN算法封装成一个函数调用,再测试KNN准确性即可。(PS:虽然流程简单,但是代码实现过程中还是有很多坑!)

(2)代码实现

①实现文件数据读取

  1. def file2matrix(filename):
  2. fr = open(filename)
  3. numberOfLines = len(fr.readlines())
  4. # 定义一个numberOfLines行,3列的零矩阵
  5. # 一定要加两个括号
  6. returnMat = np.zeros((numberOfLines, 3))
  7. # 标签向量
  8. classLabelVector = []
  9. fr.close()
  10. fr = open(filename)
  11. index = 0
  12. for line in fr.readlines():
  13. # 去掉每一行的前后空格
  14. line = line.strip()
  15. # 根据tab将数据切割出来,listFromLine就成了一个字符串列表
  16. listFromLine = line.split("\t")
  17. # listFromLine[0:3]将listFromLine的前三列赋值给returnMat[]数组,因为returnMat有numberOfLines行,就会执行numberOfLines次操作
  18. returnMat[index, :] = listFromLine[0:3]
  19. # listFromLine[-1]表示最后一列
  20. if listFromLine[-1] == 'didntLike':
  21. classLabelVector.append(1)
  22. elif listFromLine[-1] == 'smallDoses':
  23. classLabelVector.append(2)
  24. elif listFromLine[-1] == 'largeDoses':
  25. classLabelVector.append(3)
  26. index += 1
  27. fr.close()
  28. return returnMat, classLabelVector
  29. datingDataMat, datingLabels = file2matrix("D:/python工具/素材处/KNN(二)/DataText.txt")
  30. print(datingDataMat)
  31. print(datingLabels)

在这段代码中,我觉得最重要的几个点就是:文件读取、对每行数据处理(确保能分割成矩阵或者列表!)。代码的理解,我都打上了注释,大家可以仔细看看。

效果:

②数据归一化处理

从上面的数据,可以看出里程数的数值是很大的,然后我们用0-1标椎化做处理,将里程数的每个数据缩小在0~1之间。

  1. # 数据归一化处理
  2. # 0-1标注化
  3. def autoNorm(dataSet):
  4. # min(0)按特征的列选取,min(1)按照特征的行选取
  5. minVals = dataSet.min(0)
  6. maxVals = dataSet.max(0)
  7. # shape记录了dataSet的行和列
  8. normDataSet = np.zeros(dataSet.shape)
  9. normDataSet = (dataSet - minVals) / (maxVals - minVals)
  10. return normDataSet
  11. dataSet = autoNorm(datingDataMat)
  12. print(dataSet)
  13. print(datingLabels)

效果:

③对KNN代码封装

代码原理上一篇博客已经介绍

  1. # inX输入数据,dataSet测试数据,labels标签,k最近的点的个数
  2. def knn(inX, dataSet, labels, k):
  3. dist = (((dataSet - inX) ** 2).sum(1)) ** 0.5
  4. sortdDist = dist.argsort()
  5. classCount = {}
  6. for i in range(k):
  7. voteLabel = labels[sortdDist[i]]
  8. classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
  9. maxType = 0
  10. maxCount = -1
  11. for key, value in classCount.items():
  12. if value > maxCount:
  13. maxType = key
  14. maxCount = value
  15. return maxType

④调用KNN算法进行测试

  1. m = 0.8
  2. # shape[0]表示行、shape[1]表示列
  3. dataSize = dataSet.shape[0]
  4. print("数据集的总行数:", dataSize)
  5. # 80%作为训练 20%作为测试
  6. trainSize = int(m * dataSize)
  7. testSize = int((1 - m) * dataSize)
  8. k = 5
  9. result = []
  10. error = 0
  11. # 调用封装好的KNN函数
  12. for i in range(testSize):
  13. # dataSet[trainSize + i - 1, :]表示dataSet矩阵中的第trainSize + i - 1行元素(包含对应的所有列)
  14. # dataSet[0:trainSize, :]表示一个从0~trainSize行,包含对应所有列的矩阵
  15. # datingLabels[0:trainSize]表示截取列表datingLabels中的0~trainSize个元素
  16. result = K.knn(dataSet[trainSize + i - 1, :], dataSet[0:trainSize, :], datingLabels[0:trainSize], k)
  17. # result != datingLabels[trainSize + i - 1]表示通过KNN算法得到的result是否与原来的datingLabels中对应下标为trainSize + i - 1是否相等
  18. if result != datingLabels[trainSize + i - 1]:
  19. error += 1
  20. print('错误率:', error / testSize)

这段代码中,我觉得对新手来说最不好理解的就是for循环中的dataSet矩阵的切片操作,我自己也是下来梳理了一下,才通顺起来,相应代码的注解放在代码中了,大家自己取用。

效果:

可见,我们1000条数据,用80%做训练集,20%做测试集,K选用为5用使用KNN算法的出错率,只有5.52%,其实还是可以的。(大家也可以改变数据,再测试一下)

PS:当然KNN算法的优缺点以及使用场景,就不止这些,大家可以下来好好探索一番,我这里就主要梳理一下代码啦!

四、总结

    博主作为一个新手,才开始学习机器学习而言,我觉得这篇关于KNN算法的实践,对自己帮助挺大的,让我学到了以下很多知识:

①关于文件数据的读取;

②数据的处理、归一化;

③函数的封装调用;

④矩阵和列表的一些切片操作;

最后,如果这篇文章对大家有所帮助,别忘了点赞、关注支持博主一波哦~,你们的助力,就是我持续更新的动力!

PS:如果有需要这个DataText.txt数据集的小伙伴,直接私信我,即可发送。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/827432
推荐阅读
相关标签
  

闽ICP备14008679号