Machine Learning
[TOC]

简介

K-Nearest Neighbors 是一个监督学习算法,其中数据是用与其分类相符的数据点进行训练。测量不同特征值之间的距离或相似度的方法进行分类。

算法原理

为了预测给定数据点的分类,它考虑与其相邻最近的K个数据点的类别,并选择K个临近点大多数所属的类别作为预测分类。

输入与输出

  • 输入为训练样本集,训练样本集中对应的类别标签,没标签的新数据,K
  • 输出为没标签的新数据对应的分类标签

    算法决策过程

  • 将新数据的每个特征与样本集中数据对应的特征比较

  • 提取样本集中特征最相似(最近邻)的K(一般不大于20个)个数据的分类标签
  • 选择K个最相似数据中出现次数最多的分类标签,作为新数据的分类标签

    算法详细流程

    KNN算法是对未知类别的数据集中的每个数据点依次执行:

  • 计算已知类别数据集中的点与当前点之间的距离

  • 按照距离递增次序排序
  • 选取与当前点最相似的K个点
  • 确定前K个点所在类别的出现次数或频率
  • 返回前K个点出现次数或频率最高的类别作为当前点的预测分类

    算法关键点

  • 特征中有非数值类型,需将其量化为数值

  • 选择合理的计算距离或相似度的方法
  • K值的确定
  • 选择合理的决策规则

    使用scikit-learn实现KNN并预测实例

    在这里我们使用IBM提供的teleCust1000t数据集,可以预先下载好,也可以在notebook中使用wget进行下载

    1. !wget -O teleCust1000t.csv https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-ML0101EN-SkillsNetwork/labs/Module%203/data/teleCust1000t.csv

    加载数据

    1. import pandas as pd
    2. df = pd.read_csv('teleCust1000t.csv')

    查看数据基本信息

    1. # 可使用多种方式对数据基本信息进行查看
    2. df.head()
    3. # 对一列进行查看
    4. df['custcat'].value_counts()
    5. # 也可以使用DataFrame的hist方法将数据进行可视化查看
    6. df.hist(column = 'income', bins = 50)

    定义特征集和标签集

  • X: 特征集

  • y: 标签集
    1. X = df[['region', 'tenure','age', 'marital', 'address', 'income', 'ed', 'employ','retire', 'gender', 'reside']].values
    2. y = df[['custcat']].values

    数据标准化

    在一些类似KNN的基于数据点距离的算法中,通过给定数据零均值和单位方差来达到数据标准化,我们可以使用sklearn中的preprocessing可以快速实现此过程
    1. from sklearn import preprocessing
    2. X = preprocessing.StrandardScaler().fit(X).transform(X.astype(float))

    拆分训练与测试数据

    在上面算法关键点中我们提到KNN算法有一个关键点在于K值的确定,通常我们会使用交叉验证误差统计选择法,交叉验证简而言之就是将样本数据拆分为训练和测试数据,通过训练数据训练的模型,再利用测试数据测试其误差率,然后比较不同的K值时交叉验证平均误差率,从而选择较小的K值,因此这一步我们先将数据进行拆分
    1. from sklearn.model_selection import train_test_split
    2. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 4) # test size 0.2即将20%数据作为测试数据,剩下80%作为训练数据

    实现分类器

    下面我们通过sklearn提供的KNerghborsClassifier实现分类器 ```python from sklearn.neighbors import KNeighborsClassifier

初始化K为4

k = 4 neigh = KNeighborsClassifier(n_neighbors = k).fit(X_train, y_train)

通过我们的训练结果预测测试数据

yhat = neigh.predict(X_test)

  1. <a name="77FeC"></a>
  2. ### 查看结果
  3. 我们使用sklearn的metrics提供的accuracy_score方法查看预测的准确度,在多标签分类中,准确度分类得分(accuracy classification score)是一个计算子集准确度的方法
  4. ```python
  5. from sklearn import metrics
  6. print("Train set accuracy: ", metrics.accuracy_score(y_train, neigh.predict(X_train)))
  7. print("Test set accuracy: ", metrics.accuracy_score(y_test, yhat))

在上面的例子中我们简单的实现了一个KNN算法并用以预测一个给定的数据集,而对于KNN算法来说,K是一个需要检查的最近邻居数,由用户来指定,但我们能否找到最准确的K值呢。
通常的方式是保留一部分数据用于测试模型的准确性,然后选择K = 1,使用训练数据进行建模,然后计算预测整个测试数据的准确性。重复这个过程并增加K的值,从而找到对于模型最好的K

K = 10
mean_acc = np.zeros((K - 1))
std_acc = np.zeros((K - 1))

for i in range(1, K):
    # 重复上面的训练和预测过程
    neigh = KNeighborsClassifier(n_neighbors = i).fit(X_train, y_train)
    yhat = neigh.predict(X_test)
    mean_acc[n - 1] = metrics.accuracy_score(y_test, yhat)
    std_acc[n - 1] = np.std(yhat == y_test) / np.sqrt(yhat.shape[0])

print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)