ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kNN(上)

2019-11-09 21:01:05  阅读:377  来源: 互联网

标签:kNN shuffle train split test size


本篇文章是机器学习小组第一周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,shuffle,train,split,test,size
来源: https://www.cnblogs.com/favor-dfn/p/11827661.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有