k-近邻算法笔记(1)

学习到的第一个机器学习算法是“k-近邻算法 (kNN) ”, 它的工作原理是:
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。 最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

准备工作:建立训练用样本集group和其标签集labels

import numpy as np
import operator
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def createDataSet():
    group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels

kNN算法实现函数:

def classify0(inX,dataSet,labels,k):
    dataSetSize=dataSet.shape[0]#查看训练集有多少行,即有多少个实例。
    diffMat=np.tile(inX,(dataSetSize,1))-dataSet
    #将测试数据也重复扩大成训练集一样的形式
    #tile函数详细:http://blog.csdn.net/april_newnew/article/details/44176059
    sqDiffMat=diffMat**2#平方运算
    sqDistances=sqDiffMat.sum(axis=1)
    distances=sqDistances**0.5#开根运算
    sortedDistIndicies=distances.argsort()#argsort返回升序排序后的索引值。
    #关于argsort详细:http://blog.csdn.net/maoersong/article/details/21875705
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]#将标签向量按排序索引存储于voteIlabel中
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#对前k个点所在类别进行出现次数统计。
        #关于get函数:http://www.runoob.com/python/att-dictionary-get.html
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    #iteritems()迭代输出字典的键值对,与item()类似,用法iter = dict.iteritems() iter.next()
    #itemgetter(1)表明按值排序,reverse=True表明降序排序。

函数的四个参数分别为:
inX:需要分类的测试数据。
dataSet:训练样本集
labels:训练样本集的标签集
k:需要取的最相近距离的个数。

两点间距离公式如下:


在约会网站数据上使用kNN算法

  1. 读取文件
def file2matrix(filename):#文件读取,提取特征和标签
    fr=open(filename)
    arrayOLines=fr.readlines()
    numberOfLines=len(arrayOLines)
    returnMat=np.zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    for line in arrayOLines:
        line=line.strip() #移除每行首尾指定字符。参数为空则移除空白符(如/d,/r,/n等)
        listFromLine=line.split('\t')
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index +=1
    return returnMat,classLabelVector
datingDataMat,datingLabels=file2matrix('文件路径')
  1. 准备数据:归一化数值
    归一化公式:newValue = {oldValue-min)/(max-min)
def autoNorm(dataSet):#归一化特征值函数
    minVals=dataSet.min(0) #axis=0,求每列中的最小值
    maxVals=dataSet.max(0)# 求每列中的最大值。详细参考:http://blog.csdn.net/qq_18433441/article/details/54743271
    ranges=maxVals-minVals
    normDataSet=np.zeros(np.shape(dataSet))
    m=dataSet.shape[0]#取dataSet的行数 详细参考:http://blog.csdn.net/u010758410/article/details/71554224
    normDataSet=dataSet-np.tile(minVals,(m,1))
    normDataSet=normDataSet/np.tile(ranges,(m,1))
    return normDataSet,ranges,minVals
normMat,ranges,minVals=autoNorm(datingDataMat)

3.测试算法:作为完整程序验证分类器

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],5)
        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))
  1. 使用算法构建完整可用系统:��
def classifyPersion():
    resultList=['not at all','in small doses','in large doses']
    persenTats=float(raw_input("percentage of time spent playing video games?"))
    ffMiles=float(raw_input("freguent flier miles earned per year?"))
    iceCream=float(raw_input("liters of ice cream consumed per year?"))
    datingDataMat,datingLabels=file2matrix('文件路径')
    normMat,ranges,minVals=autoNorm(datingDataMat)
    inArr=np.array([ffMiles,persenTats,iceCream])
    classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
    print "You will probably like this person:",resultList[classifierResult-1]

classifyPersion()

代码里自己总结的一些小疑问。

  1. shape[0]
    函数中,shape[0]用于查看训练样本集有多少行,即有多少实例。

  2. tile函数
    用np.tile函数将测试数据重复,扩大为和训练数据集一样的大小。用这个扩大后的测试数据集和训练样本集相减,即为diffMat。
    关于tile函数的具体使用参考:http://blog.csdn.net/april_newnew/article/details/44176059

  3. **2运算
    2为平方运算,0.5为开根运算

  4. .sum(axis=1)
    axis=1表示按行相加。axis=0表示按列相加。

  5. argsort()
    distances.argsort()返回升序排序后的索引值。
    关于argsort()详细用法参考:http://blog.csdn.net/maoersong/article/details/21875705

  6. get函数
    classCount.get(voteIlabel,0)返回计数字典里voteIlabel这个类别的出现次数。即键voteIlabel对应的值。还没被统计过,也就是不存在的话,返回默认值0
    关于get函数的详细用法参考:http://www.runoob.com/python/att-dictionary-get.html

  7. sorted函数
    sorted函数为用于列表或者iterator的排序函数,其直接返回一个排序后的新数据,而不是对原数据进行操作。
    四个参数:
    classCount.iteritems() :teritems()迭代输出字典的键值对,与item()类似
    key=operator.itemgetter(1):itemgetter(1)表明按值排序,0表明按键排序。
    reverse=True:表明降序排序
    itemgetter详细:http://blog.163.com/wjyydhs810@126/blog/static/162071754201411864324976/
    排序详解:https://www.douban.com/note/271284737/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容