十大数据挖掘算法之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)

你可能感兴趣的:(十大数据挖掘算法之KNN算法)