tracy 2018-08-09
K-NN (k -最近邻)是最简单的机器学习算法之一,可以直观地理解。它既用于分类任务,又用于回归任务。
K-NN是一种非参数的、惰性的方法。
但它与K-means算法有何不同?
K-NN是用于分类和回归任务的监督学习算法,而K-means是用于聚类任务的非监督学习算法。
K-nearest neighbors with k=3
给定一个测试点' Xq ',我们需要确定类标签(如果是分类任务)或实际值(如果是回归任务)
如果几何上接近Xq的大多数点都是正的,那么类标签就会是正的。
但是如何找到几何上接近的点呢?
我们使用欧几里德, manhattan, minkowski, 余弦相似度等距离度量来找到K个最近邻。
距离度量的选择是主观的,欧几里得距离对于高维数据来说是一种维度诅咒。与wise一样,我们需要根据数据类型和使用情况选择距离度量。
让我们看看如何逐步实现K-NN。
没关系,但是如何执行回归任务?
而不是像在分类任务中那样进行多数投票。对于回归,我们需要对顶部K点的相应目标值取均值或中位数。
从这篇文章开始你就在谈论K个最近邻。我们如何选择“K”?
我们通常通过交叉验证来选择最优的K。
记住几点:
如果我取K=m(训练集中没有数据点)会发生什么??
不管测试数据点如何,它只对测试集中的所有点进行正或负预测。假设在我们的训练集中有m1正数据点和m2负数据点,其中m1+m2 = m。
如果您使用K- nn进行二元分类(2个类)或具有偶数个类(2、4、6、8…),那么最好选择带有奇数的K,以避免并列。同样的道理,如果有奇数个类(3 5 7 9…),选择K为偶数。
为什么会这样?
假设K = 1,假设我们的测试点附近有1个异常值,然后模型预测对应于异常值的标签。在同样的场景中,如果我们采用K = 7,则在测试点附近将有其他6个最近邻(不是异常值)和1个异常值,当我们采取多数投票时,我们倾向于基于6个最近邻居得到结果。
如果特征范围非常不同(如f1值范围在0-1000和f2值范围在0-1),则K-NN中存在比例影响。在构建模型之前,最好应用列标准化或归一化。
决策树和随机森林等算法与比例无关。
#Divide the data into X_train,Y_train and X_test,Y_test
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
#Using Grid search cv to find the optimal K(n_neighbors)
neigh = KNeighborsClassifier()
parameters = {'n_neighbors':(1,3,5,7,9,11)}
gs_clf = GridSearchCV(neigh, parameters, cv = 5)
gs_clf.fit(X_train,Y_train)
#To select optimal K
optimal_k = gs_clf.best_params_.get('n_neighbors')
print(optimal_k)
#Use the obtained optimal_k to train our model
knn_final = KNeighborsClassifier(n_neighbors = optimal_k)
knn_final.fit(X_train,Y_train)
predictions_test = knn_final.predict(X_test)
predictions_train = knn_final.predict(X_train)
#The test and train accuracy
test_acc = accuracy_score(Y_test, predictions_test)*100
train_acc = accuracy_score(Y_train, predictions_train)*100