机器学习十大算法之kNN和python实现

knn算法简介

K-近邻算法( KNN ),又叫K最近邻分类算法,
也称懒惰学习,是数据挖掘分类技术中最简单的
方法之一。少应用在回归问题上,常用来做分类。所谓K最近邻就是K个最近的邻居的意思,即每个样本都可以用最接近它的K个邻居来投票表示。kNN算法作为机器学习入门的算法是很棒的。

knn怎么分类?

我们举个书里面通俗易懂的案例来讲一下knn是怎么进行分类的。我们用某电影发生打斗的场面和接吻的场面来确定该电影是动作片还是爱情片。现已有以下电影的统计,并给出未知电影的打斗镜头和接吻镜头的次数,用knn求这部未知电影的分类:
机器学习十大算法之kNN和python实现_第1张图片
我们有两个输出特征,做出二维图来观察:
机器学习十大算法之kNN和python实现_第2张图片
从这个二维关系图,我们可以猜测未知电影的类别应该是爱情片,可是怎么用数学表示出来呢?
我们先假定knn的k值取3,那么通过计算未知电影到已知电影的距离,来判断未知电影的类别。机器学习十大算法之kNN和python实现_第3张图片
k-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部 电影全是爱情片,因此我们判定未知电影是爱情片。这就是k-近邻算法干的活。

kNN的细节

思考问题:
1.k为什么取值3?
2.这个距离怎么计算的?
其实这两个问题就是kNN的关键。
解答:
k的取值:
1.k选择奇数(读者可以思考一下,如果是偶数会发生什么情况)
2.k较小,学习的估计误差会增大,易发生过拟合。
3.k较大,减少学习的估计误差,模型整体变简单。
4. k值一般选择样本总数的平方根。
距离度量问题:
机器学习十大算法之kNN和python实现_第4张图片
常用的距离有三种,分别为曼哈顿距离、欧式距离和闵可夫斯基距离。

kNN实战

采用著名案例,预测泰坦尼克号幸存者。

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
def read_dataset(fname):
    # 指定第一列作为行索引
    data = pd.read_csv(fname, index_col=0) 
    # 丢弃无用的数据
    data.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)
    # 处理性别数据
    data['Sex'] = (data['Sex'] == 'male').astype('int')   #如果等于male就变为1,否则则为0.  
    # 处理登船港口数据
    labels = data['Embarked'].unique().tolist() 
    #unique去除数组中的重复数字,并进行排序之后输出 tolist转换成列表
    data['Embarked'] = data['Embarked'].apply(lambda n: labels.index(n))   #将文本转换为数字
    # 处理缺失数据
    data = data.fillna(0)
    return data
#train = read_dataset('D:\scikit-learn\datasets\titanic\train.csv')
train = read_dataset("train.csv")
y = train.iloc[:,0]
X = train.iloc[:,1:]
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.2);    #拆分数据集为训练集和测试集
from sklearn.neighbors import KNeighborsClassifier, RadiusNeighborsClassifier
#构建三个模型
models = []
models.append(("KNN", KNeighborsClassifier(n_neighbors=2)))      #普通的knn
models.append(("KNN with weights", KNeighborsClassifier(
    n_neighbors=30, weights="distance")))                         #加权的knn,距离越近,权重越高
models.append(("Radius Neighbors", RadiusNeighborsClassifier(
    n_neighbors=30, radius=500.0)))                              #变种的knn,半径为500
    results = []
for name, model in models:
    model.fit(X_train, Y_train)
    results.append((name, model.score(X_test, Y_test)))
for i in range(len(results)):
    print("name: {}; score: {}".format(results[i][0],results[i][1]))

在这个案例采用kNN算法准确率并不高,特别说一下,kNN在识别手写数字表现很棒。

kNN的优缺点

优点:精度高、对异常值不敏感、无数据输入假定;训练时间复杂度比支持向量机之类的算法低,仅为O(n)。
缺点:计算复杂度高、空间复杂度高;相比决策树模型,KNN模型可解释性不强。
维度灾难:随着特征维数的增大,K近邻算法的效果会持续变差,这是因为高维空间过于巨大,高维空间内的点根本不会表现得彼此邻近。所以,如果打算在高维空间中使用K近邻算法,不妨先做一些降维的工作。

kNN的扩展

kNN在怎么搜索的它的k个邻居,这方面有很多方法,可以进一步研究,有kd树、 M树、VP树、MVP树等等

你可能感兴趣的:(机器学习,python,kNN)