zoukankan      html  css  js  c++  java
  • 【2】KNN:约会对象分类器

    前言

    这是一个KNN算法的应用实例,参考《机器学习实战》中的datingTestSet2.txt的数据集。
    可以通过对不同约会对象的特征进行分析然后自动得出以下三种结论:
    • 不喜欢的
    • 有点魅力的
    • 很有魅力的

    准备数据

    这个数据集中针对每一个约会对象收集了三种具有代表性的特征,分别是:
    • 每年获得的飞行常客里程数
    • 玩网游所消耗的时间比
    • 每年消耗的冰淇淋公升数
    然后对每个约会对象的三种结论进行打分,对应的分数分别为1、2、3。

    数据展示:



    这样的数据需要处理成分类器可以接受的格式,所以我们创建了file2matrix函数用与完成这个功能。
    代码如下 :

    1. # ==========================
    2. # 读入文本记录,转换为NumPy,便于其他函数使用
    3. # 输入:文本记录的路径
    4. # ==========================
    5. def file2matrix(filename):
    6. fr = open(filename)
    7. arrayOLines = fr.readlines()
    8. numberOfLines = len(arrayOLines)
    9. returnMat = zeros((numberOfLines, 3))
    10. classLabelVector = []
    11. index = 0
    12. for line in arrayOLines:
    13. line = line.strip() # 删除字符串首尾的空白符(包括' ', ' ', ' ', ' ')
    14. listFromLines = line.split(" ")
    15. returnMat[index, :] = listFromLines[0:3]
    16. classLabelVector.append(int(listFromLines[-1]))
    17. index += 1
    18. return returnMat, classLabelVector
    可视化分析数据:
    我们用matplotlib制作原始数据的散点图,用于分析并找出三个特征中的哪两个特征可以得到更好的分类效果。
    绘图代码:
    1. def plotSca(datingDataMat, datingLabels):
    2. import matplotlib.pyplot as plt
    3. fig = plt.figure()
    4. ax1 = fig.add_subplot(121)
    5. # 玩网游所消耗的时间比(横轴)与每年消耗的冰淇淋公升数(纵轴)的散点图
    6. ax1.scatter(datingDataMat[:,1], datingDataMat[:, 2], 15.0*array(datingLabels), 5.0*array(datingLabels))
    7. ax2 = fig.add_subplot(122)
    8. # 每年获得的飞行常客里程数(横轴)与 玩网游所消耗的时间比(纵轴)的散点图
    9. ax2.scatter(datingDataMat[:,0], datingDataMat[:, 1], 15.0*array(datingLabels), 5.0*array(datingLabels))
    10. plt.show()
    绘图效果:
    从图中可以看出,显然图二中展示的两个特征更容易区分数据点从属的类别。

    归一化数值:
    从展示数据中我们可以很明显的看出,不同特征值量级相差太大。
    而他们在模型中占的权重又并不比其他特征大,这个时候就需要对特征值进行归一化,
    也就是将取值范围处理为0到1或者-1到1之间
    这里用autoNorm()函数实现这个功能

    1. # =====================================
    2. # 如果不同特征值量级相差太大,
    3. # 而他们在模型中占的权重又并不比其他特征大,
    4. # 这个时候就需要对特征值进行归一化,
    5. # 也就是将取值范围处理为0到1或者-1到1之间
    6. # 本函数就是对数据集归一化特征值
    7. # dataset: 输入数据集
    8. # =====================================
    9. def autoNorm(dataset):
    10. minVals = dataset.min(0)
    11. maxVals = dataset.max(0)
    12. ranges = maxVals - minVals
    13. normDataset = zeros(shape(dataset))
    14. m = dataset.shape[0]
    15. normDataset = dataset - tile(minVals, (m, 1))
    16. normDataset = normDataset/tile(ranges, (m, 1)) # 矩阵中对应数值相除
    17. return normDataset, ranges, minVals
    测试算法:
    通过上面的准备工作,再加上上一节的classify0分类函数就可以构成一个完整的分类器,用于对约会对象快速分类打分。
    测试的时候一个很重要的工作就是评估算法的正确率。
    通常我们会把整个数据集按9:1的比例分成训练集和测试集。
    测试集就是用来检测分类器的正确率。
    需要注意的是,在选择测试集的时候需要保持数据的随机性。
    测试分类代码如下:

    1. '''
    2. 分类器针对约会网站的测试代码
    3. '''
    4. def datingClassTest():
    5. hoRatio = 0.10 # 数据集中用于测试的比例
    6. filePath = "E:mlmachinelearninginactionCh02datingTestSet2.txt"
    7. datingDataMat, datingLabels = file2matrix(filePath)
    8. # plotSca(datingDataMat, datingLabels)
    9. normMat, ranges, minVals = autoNorm(datingDataMat)
    10. m = normMat.shape[0]
    11. numTestVecs = int(hoRatio*m)
    12. errcounter = 0.0
    13. for i in range(numTestVecs):
    14. classifierResult = classify0(normMat[i, :],
    15. normMat[numTestVecs:m, :],
    16. datingLabels[numTestVecs:m], 3)
    17. print "the classifier came back with: %d, the real answer is: %d" %
    18. (classifierResult, datingLabels[i])
    19. if (classifierResult !=datingLabels[i]): errcounter +=1.0
    20. print "the total error rate is: %f" % (errcounter/float(numTestVecs))
    21. print errcounter

    输出效果如图所示:
    输出表示错误率为5%,且显示了算法的运行时间(通过import time,然后用time.clock - time.start实现)

    小结

    从运行效果看,算法的优点是精度高。而且算法对异常值不敏感,不需要事先训练。
    但是从算法步骤上看,在对每一个新数据进行分类的时候都要和训练集中的每一个已知数据进行比较和相似度计算
    可以预见的是,一旦数据集很大的时候,算法所要求的时间复杂度和空间复杂度就会迅速提高



  • 相关阅读:
    使用 yo 命令行向导给 SAP UI5 应用添加一个新的视图
    SAP Fiori Elements 应用的 manifest.json 文件运行时如何被解析的
    SAP UI5 标准应用的多语言支持
    微软 Excel 365 里如何设置下拉菜单和自动高亮成指定颜色
    SAP Fiori Elements 应用里的 Title 显示的内容是从哪里来的
    本地开发好的 SAP Fiori Elements 应用,如何部署到 ABAP 服务器上?
    如何在 Cypress 测试代码中屏蔽(Suppress)来自应用代码报出的错误消息
    教你一招:让集群慢节点无处可藏
    应用架构步入“无服务器”时代 Serverless技术迎来新发展
    MySQL数据库事务隔离性的实现
  • 原文地址:https://www.cnblogs.com/mooba/p/5412592.html
Copyright © 2011-2022 走看看