【机器学习实战】kNN

一、概述

优点:精度高、对异常值不敏感、无数据输入限定

缺点:计算复杂度高、空间复杂度高

使用数据范围:数值型和标称型。

二、原理

存在一个样本数据集合(训练样本集合),并且样本集中每一个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据,将新数据的每个特征值与样本集中的数据对应的特征进行比较。然后算法提取样本集中特征最相似的分类标签。通常k不大于20的整数。

三、例子1:电影分类

分类爱情片和动作片。统计很多电影中打斗镜头和接吻镜头。

电影名称 打斗镜头接吻镜头电影类型

california man

3104爱情片
he's not really into dudes2100爱情片
beautiful woman181爱情片
kevin longblade10110动作片

robo slayer 3000

995动作片

amped II

982动作片
?1890?


电影名称 与未知电影距离

california man

20.5
he's not really into dudes18.7
beautiful woman19.2
kevin longblade115.3

robo slayer 3000

117.4

amped II

118.9

假定k=3 依次是california man,he's not really into dudes,beautiful woman ===> 判定为爱情片


四、例子2:约会网站的配对效果

玩视频游戏所耗时间百分比

每年获得飞行常客里程数每周消费的冰激凌公升数样本分类
0.84000.51
121340000.93
0200001.12


1.收集数据:提供文本文件

    ==>每个样本数据占据一行,总共1000行,包含3个特征

    a.每年获得飞行常客里程数

    b.玩视频游戏所耗时间百分比

    c.每周消费的冰激凌公升数    

2.准备数据:数据归一化

    kNN使用欧几里得距离公式

    [(0.8-12)^2 + (400 - 134000)^2 + (0.5 - 0.9)^2]^0.5

    ===> 容易看出,数值大的属性对计算结果的影响最大。也就是说“每年获得飞行常客里程数”的影响要远远大于其他属性的影响。我们需要等权重特征化。

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

$ cat datingTestSet2.txt | head -n 4
40920	8.326976	0.953952	3
14488	7.153469	1.673904	2
26052	1.441871	0.805124	1
75136	13.147394	0.428964	1


# 文本文件转换成数据矩阵
def file2matrix(filename):
    fr = open(filename)
    arrayOLines = fr.readlines()                        ==>读取文档有多少行,要构建矩阵
    numberOfLines = len(arrayOLines)
    returnMat = zeros((numberOfLines,3))                ==>初始0矩阵
    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
    
    
#数据归一化    
#newValue = (oldValue - min)/(max - min)
def autoNorm(dataSet):
    minVals = dataSet.min(0)                            ==>计算矩阵每一列最小值
    maxVals = dataSet.max(0)                            ==>计算矩阵每一列最大值
    ranges = maxVals - minVals                          ==>矩阵相减,即对应行向减
    m = dataSet.shape[0]                                ==>矩阵行数
    normDataSet = dataSet - tile(minVals, (m,1))        ==>tile(minVals, (m,1))构建行数相同的最小值矩阵
    normDataSet = normDataSet / tile(ranges, (m,1))     ==>tile(ranges, (m,1))构建行数相同的差值矩阵
    
    return normDataSet,ranges,minVals
   
   
   
def datingClassTest():
    hoRatio = 0.1                                     ==>切分样本,一部分作为训练样本,一部分作为测试样本
    datingDataMat,datingLabels = file2matrix('')      ==>加载文本文件,并转化为数据矩阵
    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))
    print errorCount


转载于:https://my.oschina.net/u/204498/blog/615403

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值