kNN(上)

Posted favor-dfn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kNN(上)相关的知识,希望对你有一定的参考价值。

本篇文章是机器学习小组第一周kNN学习的总结,主要参考资料为:

机器学习的敲门砖:kNN算法(上)

https://mp.weixin.qq.com/s?__biz=MzUyMjI4MzE0MQ==&mid=2247484679&idx=1&sn=aec5259ee503b9b127b79e2a9661205d&chksm=f9cf74edceb8fdfb43e5dcd3279347e99fa6fb7523de2aaf301418eda6b4b14e17c24d671cd8&scene=21#wechat_redirect

机器学习的敲门砖:kNN算法(中)

https://mp.weixin.qq.com/s/vvCM0vWH5kmRfrRWxqXT8Q

 

kNN算法的应用场景

kNN:k-NearestNeighbor,即寻找离样本最近的k个邻居。寻找这k个邻居的目的,是认为可以通过最相近的k个邻居中出现次数最多的标签来作为样本自身的标签。因为k个邻居本身存在多个分类,所以kNN不仅是一个分类算法,而且是一个天生的多分类算法。

kNN算法的原理

kNN算法的原理如下:

技术图片

 

kNN算法的使用(sklearn)

 1 from sklearn import datasets
 2 from sklearn.model_selection import train_test_split, GridSearchCV
 3 from sklearn.neighbors import KNeighborsClassifier
 4 import numpy as np
 5 
 6 iris = datasets.load_iris()
 7 X = iris.data
 8 y = iris.target
 9 print(X.size, y.size)
10 
11 # random_state是一个seed;也可以设置test_size=0.3,随机70%训练,30%测试
12 # 千万注意不要写错了返回值
13 X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4798)
14 kNN_clf = KNeighborsClassifier(n_neighbors=3)
15 kNN_clf.fit(X_train, y_train)
16 
17 """
18 这部分的代码主要用来做预测以及计算准确率。
19 计算准确率的逻辑也很简单,就是判断预测和实际值有多少是相等的。
20 如果相等则算预测正确,否则预测失败。
21 """
22 correct = np.count_nonzero((kNN_clf.predict(X_test) == y_test) == True)
23 print("Accuracy is:%.3f" % (correct / len(X_test)))

 

kNN算法学习收获

  • 训练样本和测试样本数据的组织

当我们按照一定比例将训练集和测试集拆分后,得到的数据集的结果有可能是顺序的。在《机器学习的敲门砖:kNN算法(中)》中提到了两种方式来打散数据集.

    • 通过numpy的concatenate函数将X,y合并为矩阵并进行shuffle,再将shuffle后的数据按比例切分.
def train_test_split_by_concatenate(X, y, split_ratio):
    ‘‘‘
    将X,y合并为矩阵并进行shuffle,再将shuffle后的数据按比例切分为测试集和训练集
    :param X:特征数据
    :param y:标签数据
    :param split_ratio:数据切分比例
    :return:特征训练数据集,特征测试数据集,标签训练数据集,便签测试数据集
    ‘‘‘
    tempConcat = np.concatenate((X, y.reshape(-1, 1)), axis=1)
    np.random.shuffle(tempConcat)
    shuffle_X, shuffle_y = np.split(tempConcat, [4], axis=1)
    test_size = int(len(X) * split_ratio)
    X_train = shuffle_X[test_size:]
    y_train = shuffle_y[test_size:]
    X_test = shuffle_X[:test_size]
    y_test = shuffle_y[:test_size]
    return X_train, X_test, y_train, y_test
    • 通过numpy.random.permutation方法得到一个随机索引的数组(< len(X)),通过对该数组按比例切分得到对应的索引,根据索引找到X,y相应的数据.
def train_test_split_by_shuffle_index(X, y, split_ratio):
    ‘‘‘
    生成一个随机数数组(随机数小于特征数据长度),通过对该数组按比例切分得到对应的索引,根据索引找到X,y相应的数据
    :param X:特征数据
    :param y:标签数据
    :param split_ratio:数据切分比例
    :return:特征训练数据集,特征测试数据集,标签训练数据集,便签测试数据集
    ‘‘‘
    shuffle_index = np.random.permutation(len(X))
    test_size = int(len(X) * split_ratio)
    test_index = shuffle_index[:test_size]
    train_index = shuffle_index[test_size:]
    X_train = X[train_index]
    X_test = X[test_index]
    y_train = y[train_index]
    y_test = y[test_index]
    return X_train, X_test, y_train, y_test

数据集打散的方式可以应用到更多的场景。

超参数和模型参数的理解以及GridSearch的使用

超参数:类似于sklearn对kNN算法的封装,k是算法需要传入的参数。这种参数被称为超参数。类似最近在学习的SparkALS,可以通过指定rank参数、maxIter参数的多个值来获得不同的ALS模型,根据测试集在不同模型上的RMSE结果来选择最好的模型。

sklearn中通过GridSearch来实现多个超参数的网格搜索。


from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.neighbors import KNeighborsClassifier

#
首先是一个数组;数组的每个元素是一个字典。即{"weights": ["uniform"], "n_neighbors": [i for i in range(1, 11)]} # 是一个字典 param_search = [ {"weights": ["uniform"], "n_neighbors": [i for i in range(1, 11)] }, {"weights": ["distance"], "n_neighbors": [i for i in range(1, 11)], "p": [i for i in range(1, 6)] } ]
knn_clf = KNeighborsClassifier()

grid_search = GridSearchCV(kNN_clf, param_search)
best_kNN_clf = grid_search.estimator

‘‘‘
输出:
KNeighborsClassifier(algorithm=‘auto‘, leaf_size=30, metric=‘minkowski‘,
metric_params=None, n_jobs=None, n_neighbors=5, p=2,
weights=‘uniform‘)
‘‘‘

 

以上是关于kNN(上)的主要内容,如果未能解决你的问题,请参考以下文章

KNN算法的实现

R语言-KNN算法

机器学习算法_knn(福利)

如何实现100k行的KNN?

knn算法如何选择一个最佳k值

kNN(上)