今天了解了机器学习中的监督学习,学习了监督学习算法下的K近邻算法。现在来总结一下

监督学习一些定义什么的这里不多说.

一.K近邻的分类

        k-NN 算法最简单的版本只考虑一个最近邻,也就是与我们想要预测的数据点最近的训练
数据点。预测结果就是这个训练数据点的已知输出。
        这里我们直接在foge数据集上进行应用(foge数据集不需要多了解,只需要知道forge数据集用于二分类问题和分类算法的决策边界)。
这个数据集包含了26个数据点和两个特征值。
import mglearn
import matplotlib.pyplot as plt
import numpy as np
mglearn.discrete_scatter(X[:,0],X[:, 1],y)
plt.legend(["Class 0","Class 1"],loc = 4)
plt.xlabel("First feature")
plt.ylabel("Second feature")
print("X.shape: {}".format(X.shape))

这个是将此数据集的所有数据点可视化(图像以第一个特征为 x 轴,第二个特征为 y 轴)。

这里我们可以做一个k近邻的可视化。来看一下是什么样的

除了仅考虑最近邻,我还可以考虑任意个(k 个)邻居,在考虑多于一个邻居的情况时,我们用“投票法”(voting)来指定标签。也就是说,对于每个测试点,我们数一数多少个邻居属于类别 0,多少个邻居属于类别 1。然后将出现次数更多的类别(也就是 k 个近邻中占多数的类别)作为预测结果。

mglearn.plots.plot_knn_classification(n_neighbors=1)#一个邻居
mglearn.plots.plot_knn_classification(n_neighbors=3)#三个邻居

现在我们对forge数据集通过scikit-learn来应用k近邻分类算法。

#依然先划分数据集
from sklearn.model_selection import train_test_split
X,y = mglearn.datasets.make_forge()
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
clf = KNeighborsClassifier(n_neighbors=3)#这里将邻居设置为三个
clf.fit(X_train,y_train)#使用fit()函数
#调用predict()来对测试的数据进行预测
print("Test set predictions: {}".format(clf.predict(X_test)))
#使用score进行精准度估算
print("Test set accuracy: {:.2f}".format(clf.score(X_test,y_test)))

2. 分析KNeighborsClassifier(分类器)

对于1个邻居,3个邻居,9个邻居三种情况的决策边界可视化
我们根据平面中每个点所属的类别对平面进行着色。这样可以查看决策边界,即算法对类别 0 和类别 1 的分界线。

fig,axes = plt.subplots(1, 3, figsize=(10,3))

for n_neighbors,ax in zip([1,3,9],axes):
    clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X,y)
    mglearn.plots.plot_2d_separator(clf,X,fill=True,eps=0.5,ax=ax,alpha=.4)
    mglearn.discrete_scatter(X[:,0],X[:,1],y,ax=ax)
    ax.set_title("{} neighbor(s)".format(n_neighbors))
    ax.set_xlabel("feature 0")
    ax.set_ylabel("feature 1")
axes[0].legend(loc=3)

可以发现使用单一邻居绘制的决策边界紧跟着训练数据。

着邻居个数越来越多,决策边界也越来越平滑。

二.k近邻回归

还是先从单一的邻居开始,使用 wave 数据集(wave数据集人工合成数据集,主要用来解决回归问题)
X,y = mglearn.datasets.make_wave(n_samples = 40)
plt.plot(X,y,"o")
plt.ylim(-3,3)
plt.xlabel("Feature")
plt.ylabel("Target")
mglearn.plots.plot_knn_regression(n_neighbors = 1)

我们添 加了 3 个测试数据点,在 x 轴上用绿色五角星表示。利用单一邻居的预测结果就是最近邻
的目标值。也可以使用多个近邻进行回归。在使用多个近邻时,预测结果为这些邻居的平均值
mglearn.plots.plot_knn_regression(n_neighbors = 3)

用于回归的K近邻算法在scikit-learn 的KNeighborsRegressos类中实现的。其用法与作用与KNeighborsClassifier类似:这里依然对wave数据集通过scikit-learn来应用k近邻回归算法。

#用于回归的 k 近邻算法在 scikit-learn 的 KNeighborsRegressor 类中实现。
#其用法与KNeighborsClassifier 类似.
from sklearn.neighbors import KNeighborsRegressor
X,y = mglearn.datasets.make_wave(n_samples=40)#n_samplesz指定样本的生成数量
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
reg = KNeighborsRegressor(n_neighbors=3)
reg.fit(X_train,y_train)
#使用
print("Test set predictions: \n{}".format(reg.predict(X_test)))
#使用score函数进行预测
print("Test set R^2: {:.2f}".format(reg.score(X_test, y_test)))

2.2KNeighborsRegressor分析

fig,axes = plt.subplots(1,3,figsize = (15,4))
line = np.linspace(-3,3,1000).reshape(-1,1)
for n_neighbors,ax in zip([1,3,9],axes):
    reg = KNeighborsRegressor(n_neighbors=n_neighbors)
    reg.fit(X_train,y_train)
    ax.plot(line,reg.predict(line))
    ax.plot(X_train,y_train,"^",c = mglearn.cm2(0),markersize = 8)
    ax.plot(X_test, y_test, 'v', c=mglearn.cm2(1), markersize=8)
    ax.set_title(
    "{} neighbor(s)\n train score:{:.2f} test score:{:.2f}".format(
    n_neighbors,reg.score(X_train,y_train),reg.score(X_test,y_test)))
    ax.set_xlabel("Feature")
    ax.set_ylabel("Target")
axes[0].legend(["Model predictions","Training data/target","Test data.target"],loc = "best")

看图我们可以发现单一的邻居训练集中的每一个点都对预测结果有显著的影响,这导致预测结果非常的不稳定。而考虑多个邻居后,预测结果变得更加平滑,但对训练数据的拟合并不好。

三.总结

KNeighbors分类器有两个重要的参数:邻居个数(3到5个)与数据点之间距离的度量方法(默认使用欧式距离)

K-NN算法的优点之一构建模型简单不需要过多调节就可以获得很不错的性能。

但是当训练集数量很大时预测速度会很慢。

数据集有很多特征时效果也往往不好,对于稀疏数据集(大多数的数据是缺失值或零值)来说,KNN算法尤其不好。

注:本人理解与学习笔记

参考《机器学习基础教程》

更多推荐