机器学习KNN算法学习笔记

基本概念

KNN是分类算法。

数据类型:数值型和标称型。

工作原理

存在一个训练样本集,并且训练样本集中每个数据都存在标签,即知道训练样本集中每一条数据与所属分类对应关系。输入没有标签的新数据后,与训练样本集中数据对应的特征做比较,然后提取样本集中特征最相似数据(最临近,用距离公式,距离最近)的分类标签。一般来说,我们只取训练样本集中前k个最相似的数据,这就是k的出处。通常k是不大于20的整数。

距离公式

49b476ef-7c62-4da0-8648-5a1c5715d4ab
49b476ef-7c62-4da0-8648-5a1c5715d4ab

多特征时,如(1,0,0,1)和(7, 6, 9, 4)


d3b42a96-1c5a-4eac-83cb-d4041a242464
d3b42a96-1c5a-4eac-83cb-d4041a242464

分类算法

from numpy import *
import operator
from os import listdir

def classify0(inX, dataSet, labels, k):
    # inX为待分类数据
    # dataSet为训练数据集
    # labels对应dataSet每一行数据的标签(类型)

    # 有多少行数据 shape反回一个元组。(行, 列)
    dataSetSize = dataSet.shape[0] 
    
    # tile(inX, (dataSetSize,1)) 创建一个numpy的array,dataSetSize行,每行数据是inX
    # - dataSet 矩阵减法 m*n矩阵A - m*n矩阵B
    diffMat = tile(inX, (dataSetSize,1)) - dataSet 
    
    # 矩阵的每个值平方
    sqDiffMat = diffMat**2

    # 横向求和,得到一个一维数组,每个值都是和
    sqDistances = sqDiffMat.sum(axis=1)
    
    # 数组中每个值开根
    distances = sqDistances**0.5

    # 得到排序后的下标数组
    sortedDistIndicies = distances.argsort()

    classCount={}
    # 只取前k个        
    for i in range(k):
        # 找到下标对应的标签
        voteIlabel = labels[sortedDistIndicies[i]]
        # 如果找到相同标签利用map来计数
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    # 排序加反转
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    print sortedClassCount
    # 把计数最大的值所对应的标签返回出去
    return sortedClassCount[0][0]

数据归一化

如果某个特征值数量级特别大,比如A特征是5位数,而其他特征是个位数。那么就会发现A特征的值大大会影响最终结果。所以需要把每个特征值都归到0-1这个范围。

数据归一化算法

9061c50-3104-11e7-8aca-e882fa09a8a8
9061c50-3104-11e7-8aca-e882fa09a8a8
def autoNorm(dataSet):
    # 每一列最小值
    minVals = dataSet.min(0)
    # 每一列最大值
    maxVals = dataSet.max(0)
    # 每一列的差
    ranges = maxVals - minVals
    # 复制矩阵 dataSet的行,列。值都是0
    normDataSet = zeros(shape(dataSet))
    # 得到多少行
    m = dataSet.shape[0]

    # tile(minVals, (m,1)) 创建datSet的行列的矩阵,每一个值都是minVals。
    # dataSet - 矩阵相减
    normDataSet = dataSet - tile(minVals, (m,1)) 

    # tile(ranges, (m,1)) 创建datSet的行列的矩阵,每一个值都是ranges。
    # 并非矩阵除法,而是对应位置的值相除
    normDataSet = normDataSet / tile(ranges, (m,1))
    return normDataSet, ranges, minVals

实际使用

def datingClassTest():
    # 预留出10%来做测试数据验证准确率
    hoRatio = 0.10
    # 读取数据和标签
    datingDataMat,datingLabels = file2matrix('Ch02/datingTestSet.txt')       #load data setfrom file
    # 把数据归一化处理
    normMat, ranges, minVals = autoNorm(datingDataMat)
    # 取到数据有多少行
    m = normMat.shape[0]
    # 取出测试数据的长度
    numTestVecs = int(m*hoRatio)
    # 错误计数
    errorCount = 0.0

    for i in range(numTestVecs):
        # normMat[i,:] 取出第i行的 所有数据
        # normMat[numTestVecs:m,:] 取出numTestVecs之后到m的每行数据
        # datingLabels[numTestVecs:m] 取出numTestVecs之后到m的每行的标签
        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])
        # 如果结果不一致,则错误+1
        if (classifierResult != datingLabels[i]): errorCount += 1.0
    # 最后打印出错误率和错误数
    print "the total error rate is: %f" % (errorCount/float(numTestVecs))
    print errorCount

优点

  • 分类算法中最简单最有效的算法

缺点

  • 必须保存全部训练集,如果训练集样本很大会使用大量存储空间
  • 计算距离时可能非常耗时
  • 无法给出任何数据的基础结构信息,无法得知平均实例样本和典型实例样本具有什么特征
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容