【实现】利用KNN约会分类

作者: 七八音 | 来源:发表于2018-01-10 20:27 被阅读67次

代码来自于《机器学习实战》

问题背景

小红经常在约会网站寻找适合自己的约会对象。经过自己的总结,发现曾经交往过三种类型的人:

不喜欢的人

魅力一般的人

极具魅力的人

发现了上述规律,小红还是无法将约会网站推荐的匹配对象归到恰当的类别。她希望在周一到周五约会那些魅力一般的人,周末想那些极具魅力的人为伴(世界一直围绕着小红在转啊转......)。我们怎么帮助她?

1. 数据处理

数据保存在datingTestSet2.txt中,每个样本占据一行,共有1000行(哇,人才)。样本主要包含以下3个特征:

每月工资

玩游戏所消耗时间百分比

每周消费的冰淇淋公升数

些许样例示意图

A 处理数据:将文本中的数据变成分类器能接受的格式。

导入需要的工具包

from numpy import *

定义函数file2Matrix:将文本数据转换成矩阵形式

def file2Matrix(filename):

    fr= open(filename)

    arrayOLines= fr.readlines()#直接将数据全部读取进来,形成列表,每一行为一个元素

    numberOfLines= len(arrayOLines)#行数

    returnMatrix= zeros((numberOfLines,3))

    classLabelVector= []

    index= 0

    for linein arrayOLines:

        line= line.strip()

        listFromLine= line.split('\t')

        returnMatrix[index,:] = listFromLine[0:3]#赋值方式很厉害!

        classLabelVector.append(listFromLine[-1])

        index+= 1

    return returnMatrix,classLabelVector

B 数据归一化处理

数据中特征“每月工资”,取值范围太大,计算距离时,产生的影响过大。但我们认为3个特征的重要性是一样的。所以,有必要进行数据归一化处理。将数据归一化到 0~1 之间。

公式

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

定义归一化函数autoNorm;返回归一化的数据,每个特征的最小值以及范围(方便对新数据进行归一化处理)。

def autoNorm(dataSet):

    minVals= dataSet.min(0)#a.min() :全部的最小值;;a.min(axis=0):每列中的最小值;a.min(axis=1):每行中的最小值

    maxVals= dataSet.max(0)

    ranges= maxVals- minVals

    m= dataSet.shape[0]#行数

    normDataSet= dataSet- tile(minVals,(m,1))#(m,n)重复次数:行方向上重复m次,列方向上重复1次

    normDataSet= normDataSet/tile(ranges,(m,1))

    return normDataSet,ranges, minVals

其中,调用的函数

dataSet.min(0)

dataSet:python numpy array类型

array.min():求数组中的最小值

array.min(axis=0):对数组中的每列求最小值

array.min(axis=1):对数组中的每行求最小值

numpy.tile(A, reps):

Construct an array by repeating A the number of times given by reps.通过重复A ,reps次构建一个新的数组。

tile(minVals, (m, 1)):重复minVals 构造一个m*1的copy

2. 分类算法KNN

伪代码:

对未知类别属性的数据集中的每个点依次执行以下操作:

(1)计算已知类别数据集中的点与当前点之间的距离;

(2)按照距离递增次序排序;

(3)选取与当前点距离最近的k个点;

(4)确定前k个点所在类别的出现频率;

(5)返回前k个点出现频率最高的类别作为当前点的预测分类。

其实是计算两个数据的相似性:有距离相似性度量和角度相似性度量【knn算法介绍】。

这里采用距离相似性度量,欧式距离。

欧式距离计算公式

分类器算法实现:

def classify0(inX, dataSet, labels, k):

    dataSetSize= dataSet.shape[0]

    diffMat= tile(inX,(dataSetSize,1)) - dataSet

    sqDiffMat= diffMat** 2

    sqDiffMat= sqDiffMat.sum(axis=1)#按列求和

    distances= sqDiffMat** 0.5

    sortedDistIndicies= distances.argsort()#argsort函数返回的是数组值从小到大的索引值

    classCount= {}

    for iin range(k):

        voteLabel= labels[sortedDistIndicies[i]]

        classCount[voteLabel] = classCount.get(voteLabel,0) + 1#在字典classCount中通过 键 查找相应的值,如果字典中没有键,值为0;有获取其值;最后加1

    sortedClassCount= sorted(classCount.items(),key=lambda a:a[1],reverse=True)#根据出现次数排序,降序排序

    return sortedClassCount[0][0]#返回概率最大(出现次数最多的键,即类别)

其中,调用函数:

numpy.argsort:

Returns the indices that would sort an array. 返回数组排序后的下标(默认升序排序)。

eg:[10, 1, 51]

调用函数,返回的是:[1, 0, 2]  ;1是数据1的下标。

3. 测试算法

数据指标:误分率。

计算方法: 错误分类的记录数/测试数据的总数;

def datingClassTest():

    """

    使用测试数据测试分类器效果

    :return: 误分率"""

    hoRatio= 0.10#测试数据所占的比例---将数据集按照1:9的比例划分,1是测试集;9是训练集

    datingDataMat,datingLabels= file2Matrix('datingTestSet2.txt')

    normMat,ranges,minVals= autoNorm(datingDataMat)

    m= normMat.shape[0]#数据集总数

    numTestVecs= int(m*hoRatio)#测试集数目

    errorCount= 0

    for i  in range(numTestVecs):

        classifierResult= classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)

        print ("the classifier came back with: %s,the real answer is: %s"  % (classifierResult, datingLabels[i]))

        if (classifierResult!= datingLabels[i]):

            errorCount+= 1

    print ("the total error rate is: %f" %(errorCount/float(numTestVecs)))

运行结果:

测试算法运行结果

错误率:5%

4. 使用算法

重头戏:使用knn分类算法,方便小红约会哦!

def classifyPerson1():

    resultList= ["不喜欢","魅力一般","极具魅力(韩国欧巴)"]

    percentTats= float(raw_input(\

"花费在游戏、视频上的时间百分比?"))#raw_input:读取控制台输入数据,赋值给变量,等效于C++里的cin>>a;

    ffMiles= float(raw_input("每月工资有多少?"))

    iceCream= float(raw_input("每年消耗的冰淇淋有多少升?"))

    datingDataMat,datingLabels= file2Matrix("datingTestSet2.txt")

    normMat,ranges,minVals= autoNorm(datingDataMat)

    inArr= array([ffMiles,percentTats,iceCream])

    classifierResult= classify0((inArr-minVals)/ranges,normMat,datingLabels,k=3)#对输入数据进行归一化,然后再分类

    print ("你将约会的人很可能是: %s" % resultList[int(classifierResult)-1])

应用:

小红将约会韩国欧巴(安排在周末) 小红遇到不喜欢的类型(pass)

5. 小结

A。 矩阵运算----能加快运算速度;

B。knn算法分类数据简单有效,不用进行训练,是基于实例的学习,使用的数据必须接近实际数据的训练样本数据;必须保存所有数据,如果数据集过大,需要耗费巨大的存储空间;必须对数据中的所有样例点进行计算距离值,非常耗时(即使使用矩阵进行运算)。

C。人生苦短,我用Python!

完整代码及数据集:github

相关文章

  • 【实现】利用KNN约会分类

    代码来自于《机器学习实战》 问题背景 小红经常在约会网站寻找适合自己的约会对象。经过自己的总结,发现曾经交往过三种...

  • 利用Python进行数字识别

    思路 通过Python实现KNN算法。而KNN算法就是K最近邻(k-Nearest Neighbor,KNN)分类...

  • Python实现KNN与KDTree

    KNN算法: KNN的基本思想以及数据预处理等步骤就不介绍了,网上挑了两个写的比较完整有源码的博客。利用KNN约会...

  • 2020-08-10--KNN01

    KNN算法的原理介绍KNN算法的一个简单实现(肿瘤分类)将KNN算法封装成函数机器学习套路使用scikit-lea...

  • KNN算法实现及其交叉验证

    KNN算法 用NumPy库实现K-nearest neighbors回归或分类。 knn 邻近算法,或者说K最近邻...

  • KNN算法实现及其交叉验证

    KNN算法 用NumPy库实现K-nearest neighbors回归或分类。 邻近算法,或者说K最近邻(kNN...

  • 机器学习 Day 10 | KNN算法的简单实现(3)

    机器学习第十天 KNN算法的简单实现(3) 七夕来啦啦啦,用KNN实现一个优化约会网站的配对效果的案例 用mark...

  • k-邻近算法

    使用Python实现kNN分类为算法 计算距离函数classify0()如下: 输入参数:用于分类的输入向量inX...

  • 机器学习

    1.KNN 一个小栗子 实现sklearn中的knn 将数据分为测试数据和训练数据 iris的分类: 数据归一化:...

  • 机器学习笔记汇总

    kNN算法:K最近邻(kNN,k-NearestNeighbor)分类算法

网友评论

    本文标题:【实现】利用KNN约会分类

    本文链接:https://www.haomeiwen.com/subject/ydqanxtx.html