十大数据挖掘算法之KNN算法

一、KNN算法概述

KNN(k-Nearest Neighbor)算法,又称K近邻算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。简单来说,k近邻算法采用测量不同特征值之间的距离方法进行分类。

  • 优点:精度高、对异常值不敏感、无数据输入假定;
  • 缺点:计算复杂度高、空间复杂度高;
  • 适用数据范围:数值型和标称型。

工作原理

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

缺点

  • 该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的 K 个邻居中大容量类的样本占多数。因此可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
  • 该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的 K 个最近邻点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。

二、算法的Python实现

from numpy import *
import operator

# 创建数据
def createDataSet():
    group = 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):
    '''
    参数inX是用于分类的输入向量
    参数dataSet是输入的训练样本集
    参数labels是标签向量
    参数k是用于选择最近邻居的数目
    '''
    dataSetSize = dataSet.shape[0]
    # 使用距离公式计算距离
    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]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    # 返回前k个点出现频率最高的类别作为当前点的预测分类
    return sortedClassCount[0][0]

group,labels = createDataSet()
classify0([0,0],group,labels,3)

三、使用sklearn中的kNN方法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import neighbors,datasets
# 导入sklearn中的neighbors

#加载鸢尾花数据
iris = datasets.load_iris()
data = pd.DataFrame(iris.data,columns=iris.feature_names)
data['target'] = iris.target

tmp = pd.DataFrame({'target':[0,1,2],
                   'target_name':iris.target_names})

data = pd.merge(data,tmp,on = 'target')

# 创建knn模型并训练
knn = neighbors.KNeighborsClassifier()
knn.fit(iris.data,data['target_name'])

#预测
predict_data = knn.predict([[0.2,0.1,0.3,0.4]])

四、案例:使用KNN算法改进约会网站的配对效果

《机器学习实战》中的案例有点麻烦,所以这里直接调用sklearn模块。
相关数据“dataTestingSet2.txt”来自《机器学习实战》

import pandas as pd
from sklearn import neighbors

#使用pandas导入数据
datingTest = pd.read_table("datingTestSet2.txt",sep='\t',header=None)
datingTest.columns = ['飞行里程','游戏时间百分比','每周消费冰淇淋公升数','target']
#不知道DataFrame怎么直接映射,所以写了个for循环
tmp = []
for i in datingTest['target']:
    if i == 1:
        tmp.append("dislike")
    elif i == 2:
        tmp.append("goodfeeling")
    else:
        tmp.append("like")
datingTest['target_name'] = tmp
datingTrain = datingTest.iloc[:,0:3]

#创建模型并训练
knn = neighbors.KNeighborsClassifier()
knn.fit(datingTrain,datingTest['target_name'])

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

推荐阅读更多精彩内容