上节我们简单介绍了K近邻算法的使用方法,本节我们继续介绍K近邻算法用于回归,本次我们使用wave数据集来进行测试,我们分别选取2个和5个邻居来看一下wave数据的预测结果,对应的代码如下:

import mglearn

from sklearn.model_selection import train_test_split

mglearn.plots.plot_knn_regression(n_neighbors=2)

mglearn.plots.plot_knn_regression(n_neighbors=5)



用于K临近算法是在scikit-learn的KNeighborsRegressor类中实现。其具体用法和KNeighborsClassifier用法一样,下面我们使用100个样本,然后通过使用不同的邻居个数来看一下wave数据的预测结果,对应代码如下:

from sklearn.neighbors import KNeighborsRegressor

x, y = mglearn.datasets.make_wave(n_samples=100)

#将wave数据集分为训练集和测试集

x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)

#模型实例化,并将邻居个数设为5

reg = KNeighborsRegressor(n_neighbors=5)

#利用训练数据和训练目标值来拟合模型

reg.fit(x_train, y_train)

print("Test set predictions:\n{}".format(reg.predict(x_test)))

print("Test set R^2: {:.2f}".format(reg.score(x_test, y_test)))

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

#创建1000个数据点,在-3和3之间均匀分布

line = np.linspace(-3, 3, 1000).reshape(-1, 1)

for n_neighbors, ax in zip([1, 9,25], axes):

#利用1,3和9、25个邻居分别进行预测

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=9)

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 predicitons", "training data/target", "test data/target"], loc="best")

运行结果如下:


根据上述结果可以看出,当只用一个邻居时,每一个点的数据都对预测结果有影响,这个时候的训练精确度最高,随着邻居个数的增加,跳动比较大的点对结果的影响逐渐见底,训练精度也逐渐降低,预测结果也逐渐平稳,但是其拟合效果不好。所以,一般情况下,综合训练精度和稳定性考虑,一般邻居个数选择较小的邻居个数,一般3-5个。

K临近算法的有点、缺点以及参数:K临近算法的有点事模型易于理解,通常不需要过多的调节就可以得到不错的性能。在没有接触更高技术之前,该算法是一个很好地基础算法,且其构建速度快,一般适用于训练集较小的模型。

缺点:在训练集很大时(特征数很多或者样本数很大),同时预测速度可能会比较慢。且使用该算法比较依赖对数据的预处理(后续介绍怎么预处理数据)。尤其对于稀疏数据集(多数值为零的数据集)效果尤其不好。

参数:一般来说,K近邻分类器有两个重要的参数:邻居个数和数据点之间距离的度量方法。在实践中,使用较小的邻居个数(一般3-5个)往往会得到较好的结果。但是为了综合考虑其性能,则需要对该参数做相应的调整。