1.k-近邻分类器 k-近邻算法是一种最简单的数据挖掘算法,在平时使用中也很常见。k-近邻中的近邻指的是距离待预测数据的数据点,而k-近邻就指的是取前k近的数据点,例如3-近邻算法就是找到3个离待预测数据作为最近邻。k-近邻算法是一种监督学习的算法(即原本的数据集中是分类明确的)。 2.k-近邻分类器的原理 最近邻分类器把每个样例(训练数据、测试数据同时也有待预测的数据)当作是d维空间上的一个数据点,而d指的是样例的属性个数。而在d维空间上就有不同点之间的“距离”(距离有很多种,汉明距离,欧拉距离,闵科夫斯基距离等),依靠这些点之间的距离的差异,将有远近之分。那么k-近邻分类器就是把预测的原则定位取决与这些离它“最近”的k个数据点,若离它最近的数据点中A类多余B类,则认为它大概率是B类的数据点,完成分类。 3.k-近邻的自写代码
import numpy as np from math import sqrt from collections import Counter #传入参数分别为属性训练集,类别训练集,参数k,待预测的数据 def KNN_classify(x_train , y_train , k , predict): assert 1 <= k <= len(x_train) , 'The value of k is invalid.' assert len(x_train) == len(y_train) , 'The number of x is not equal to the number of y.' #这里点与点的距离取的是欧拉距离,如果是不止这么少的属性空间,那么就运用循环 distance = [sqrt( ((x[0] - predict[0]) ** 2)+((x[1] - predict[1]) ** 2) + ((x[2] - predict[2]) ** 2) +((x[3] - predict[3]) ** 2)) for x in x_train ] #top_index是将训练数据和待预测数据的距离按升序排序后的下标 top_index = np.argsort(distance) #取k个最近的数据在类别训练集中的下标 knn_index = [y_train[i] for i in top_index[:k]] #做一个投票机制 votes = Counter(knn_index) return votes.most_common(1)[0][0]4.运用scikit-learn封装的算法库: (1).scikit-learn.neighbors中的KNeighborClassifier类
KNeighborsClassifier( n_neighbors=5, #超参数k weights=’uniform’, #超参数weights = ['uniform' , 'distance'],当weights=‘uniform’时,各点都是按相同的权重,而当weights='distance'时,各点的权重将是取距离的倒数 algorithm=’auto’, leaf_size=30, p=2, #超参数p,看选择哪种距离计算,即当为1时距离为汉明距离,距离为2时为欧拉距离,其他的时问科夫斯基距离 metric=’minkowski’, metric_params=None, n_jobs=None, **kwargs)(2).scikit-learn中KNeighborClassifier的实际使用
from sklearn.neighbors import KNeighborsClassifier import numpy as np #模拟数据集 x = [[1. , 1.], [2. , 4.], [3. , 3.], [4. , 1.], [6., 3.], [7. , 4.], [8. , 4.]] y = [0 , 0 , 0,1,1,1,1] x_predict = np.array([[4.5 , 2.5]]) #实例化一个knn分类器,k取值为3 knn = KNeighborsClassifier(n_neighbors=3) #用训练集训练出knn分类器 knn.fit(x , y) #对待预测的数据进行预测 y_predict = knn.predict(x_predict) print(y_predict)5.k-近邻分类器的一些特征 (1).k-近邻算法基本上是机器学习里面最容易理解的算法之一,而且支撑的数学理论也浅显易懂,但是这种靠近邻分类的方法有时候就是没有什么保证,遇到某些数据集误差也比较大。 (2).k-近邻算法中,时间复杂度是一个很重要的考虑点。若数据集少或者属性值少,那么k-近邻算法将是很高效的。若是一个庞大的数据集,对单单一个数据就会产生O(n*m)的时间复杂度,那么将是很低效的。
