2-2监督学习算法 K近邻算法

本文深入探讨了K近邻(KNN)算法,包括其基本原理、分类实现、决策边界的分析以及在癌症数据集上的测试精度分析。通过示例展示了KNN在不同邻居数下的决策边界变化,指出邻居数影响模型性能。此外,还介绍了KNN在回归问题中的应用,以及回归模型的表现。最后,文章强调了KNN在多特征数据集上的局限性及其在实际应用中的地位。
摘要由CSDN通过智能技术生成

2-2监督学习算法 K近邻算法(基础)

一、基本介绍:

K近邻算法可以说是最基础的机器学习算法,对新数据点做出预测时,算法能够在训练集在寻找到与其最接近的几个数据点来判断其属类。

二、操作实现KNN分类:

1-使用forge数据集(一个模拟二分类的数据集)进行K近邻算法的实现:

"""导入必要的库"""
import mglearn
from mglearn.datasets import make_forge # forge数据集
from sklearn.model_selection import train_test_split # 分类器
from sklearn.neighbors import KNeighborsClassifier # KNN模型
from matplotlib import pyplot as plt
data, target = make_forge()
#print("数据:\n{}".format(data))
print("数据规模:\n{}".format(data.shape))
#print("目标:\n{}".format(target))
print("目标规模:\n{}".format(target.shape))
数据规模:
(26, 2)
目标规模:
(26,)


D:\Anaconda\true\lib\site-packages\sklearn\utils\deprecation.py:86: FutureWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn
  warnings.warn(msg, category=FutureWarning)
可知该数据集有26个数据点,分类目标有两个.
X_train, X_test, y_train, y_test = train_test_split(data, target, random_state=0)
print(data)
print(target)
print(X_train.shape)
print(X_test.shape)
[[ 9.96346605  4.59676542]
 [11.0329545  -0.16816717]
 [11.54155807  5.21116083]
 [ 8.69289001  1.54322016]
 [ 8.1062269   4.28695977]
 [ 8.30988863  4.80623966]
 [11.93027136  4.64866327]
 [ 9.67284681 -0.20283165]
 [ 8.34810316  5.13415623]
 [ 8.67494727  4.47573059]
 [ 9.17748385  5.09283177]
 [10.24028948  2.45544401]
 [ 8.68937095  1.48709629]
 [ 8.92229526 -0.63993225]
 [ 9.49123469  4.33224792]
 [ 9.25694192  5.13284858]
 [ 7.99815287  4.8525051 ]
 [ 8.18378052  1.29564214]
 [ 8.7337095   2.49162431]
 [ 9.32298256  5.09840649]
 [10.06393839  0.99078055]
 [ 9.50048972 -0.26430318]
 [ 8.34468785  1.63824349]
 [ 9.50169345  1.93824624]
 [ 9.15072323  5.49832246]
 [11.563957    1.3389402 ]]
[1 0 1 0 0 1 1 0 1 1 1 1 0 0 1 1 1 0 0 1 0 0 0 0 1 0]
(19, 2)
(7, 2)
该数据是二维的(影响其分类的特征有两个), 分类目标有两类,0和1.
经过分类器划分后,训练集含有数据点19个,测试集含有数据点7个.
# 从训练集数据中构建K近邻模型:
clf = KNeighborsClassifier(n_neighbors=3)
clf.fit(X_train, y_train)
# 对模型进行预测
print("预测新数据点可能属于的分类:\n{}".format(clf.predict(X_test)))
print("预测精度:\n{:.2f}".format(clf.score(X_test, y_test)))
预测新数据点可能属于的分类:
[1 0 1 0 1 0 0]
预测精度:
0.86
fit(训练集数据,训练集标签):以训练集数据为基础,构造一个KNN模型. 也可以说是拟合函数.
predict(测试集数据): 返回预测测试集中出现的数据点属于的分类.
score(测试集数据):返回测试集数据预测的准确度.

之后会学习如何提升预测精度,降低损失值。

K近邻可视化:

mglearn.plots.plot_knn_classification(n_neighbors=1)

在这里插入图片描述

当选取邻居数为1或2时,算法会直接找到离新数据点最近的数据,并将其归为一类。

mglearn.plots.plot_knn_classification(n_neighbors=3)

在这里插入图片描述

当选取的邻居大于2时,算法会采用投票法,即邻近的多个数据点中出现最多的类别会与新数据点归为一类。

2-KNN算法分析(仍是以forge数据集为例)

①决策边界:
最简单的决策边界例子:考试成绩,低于60分的为不及格,否则即为及格。
# 涉及plt的绘图基础,下将做说明.
fig, axes = plt.subplots(1,4, figsize=(10, 3))

# zip函数较为常用,应该掌握.
for n, ax in zip([1, 3, 9, 12], axes):
    # 直接构建实例化模型即可:
    clf = KNeighborsClassifier(n_neighbors=n).fit(data, target)
    # 绘制边界函数:
    mglearn.plots.plot_2d_separator(clf, data, fill=True, eps=0.5, ax=ax, alpha=.4)
    # 导入数据点:
    mglearn.discrete_scatter(data[:, 0], data[:, 1], target, ax=ax)
    ax.set_title(f"neighbor(s):{n}")
    ax.set_xlabel("features 0")
    ax.set_ylabel("features 1")
axes[0].legend(loc=3)
print("分析决策边界得出结论:邻居数越多得到的决策边界越平滑,拟合效果越好。")
分析决策边界得出结论:邻居数越多得到的决策边界越平滑,拟合效果越好。

在这里插入图片描述

I.plt绘图基础补充:

figure 可以理解成“画布”,即绘图所需要的窗口。

axes 为画布中的一片区域,可以被划分成许多个小区块。

subplot方法 — 在一个区域中绘制多个子图,如上图所示。

      ~~~~~      参数:nrows(可省略)= 展示子图的行数, ncols(可省略)= 展示子图列数, figsize=(x, y)展示画布大小,省略即默认大小。
legend()方法:显示图例.

II.涉及的其他方法:

zip():将可迭代对象打包成元组输出。

name = ('jack', 'alex', 'sony', 'joey')
age = (25, 28, 21, 30)
for a, n in zip(name, age):
    print(a, n)
jack 25
alex 28
sony 21
joey 30

mglearn.plots.plot_2d_separactor(): 显示模型的决策边界。

参数1:clf 分类器本体,参数2: data 被分类后的数据。(其他参数暂时不理解什么意思,查遍网络无所获,望大神解答.)

mglearn.discrete_scatter():导入数据点。

参数1:X[ :, 0] – 数据的第一个属性, 参数2:X[:, 1] – 数据的第二属性, 参数3:y(分类标签).
上文说过该数据集是二维的,前两个参数可以用来定位改数据点在图中的位置,第三个参数用来分类。

3-测试精度和训练精度的关系(以癌症数据集为例子):

威斯康星州乳腺癌数据简介
from sklearn.datasets import load_breast_cancer

# 导入数据
cancer = load_breast_cancer()
X = cancer.data
y = cancer.target
print(f"这是一个二分类模型,分类结果为{cancer.target_names[0]}(恶性), {cancer.target_names[1]}(良性).")
print(f"特征:\n{cancer.feature_names}\n(有点复杂,不懂也罢。只要知道这些因素影响着分类结果就行了,至于了解哪一个影响结果较大,后面会学。)")
这是一个二分类模型,分类结果为malignant(恶性), benign(良性).
特征:
['mean radius' 'mean texture' 'mean perimeter' 'mean area'
 'mean smoothness' 'mean compactness' 'mean concavity'
 'mean concave points' 'mean symmetry' 'mean fractal dimension'
 'radius error' 'texture error' 'perimeter error' 'area error'
 'smoothness error' 'compactness error' 'concavity error'
 'concave points error' 'symmetry error' 'fractal dimension error'
 'worst radius' 'worst texture' 'worst perimeter' 'worst area'
 'worst smoothness' 'worst compactness' 'worst concavity'
 'worst concave points' 'worst symmetry' 'worst fractal dimension']
(有点复杂,不懂也罢。只要知道这些因素影响着分类结果就行了,至于了解哪一个影响结果较大,后面会学。)
# 分出训练集,测试集:
X_train, X_test, y_train,y_test = train_test_split(X, y, stratify=y, random_state=66)

# 精度记录器(由于是不断训练的,因此用列表记录精度变化过程):
train_accurcy = [] # 训练精度
test_accurcy = []  # 测试精度(泛化精度)

# 设置邻居数,查看在不同邻居取值下的精度变化过程:
n_settings = range(1, 11)
for n in n_settings:
    # 建模:
    clf = KNeighborsClassifier(n_neighbors=n).fit(X_train, y_train)
    # 记录训练精度:
    train_accurcy.append(clf.score(X_train, y_train))
    # 记录泛化精度:
    test_accurcy.append(clf.score(X_test, y_test))
# 绘图:
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.plot(n_settings, train_accurcy, label='training_accurcy')
plt.plot(n_settings, test_accurcy, label='test_accurcy')
plt.xlabel("邻居数")
plt.ylabel("精度(%)")
plt.legend()

在这里插入图片描述

观察测试精度,当邻居数为6时,该模型拥有最佳性能。

三、操作实现(KNN回归)

用wave数据集模拟KNN回归模型,wave数据集也是一个模拟回归的数据集。
from sklearn.neighbors import KNeighborsRegressor
from mglearn.datasets import make_wave
# 固定流程,妹啥好说的:
X, y = make_wave(n_samples=40)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

reg = KNeighborsRegressor(n_neighbors=3).fit(X_train, y_train)

print("预测的回归值:\n{}".format(reg.predict(X_test)))
print("预测精度:\n{:.2f}".format(reg.score(X_test, y_test)))
预测的回归值:
[-0.05396539  0.35686046  1.13671923 -1.89415682 -1.13881398 -1.63113382
  0.35686046  0.91241374 -0.44680446 -1.13881398]
预测精度:
0.83
KNN回归算法分析:
import numpy as np
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# 创建1000个数据点,在-3和3之间均匀分布
line = np.linspace(-3, 3, 1000).reshape(-1, 1)
for n, ax in zip([1, 3, 9], axes):
    reg = KNeighborsRegressor(n_neighbors=n).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, '^', c=mglearn.cm2(1), markersize=8)

在这里插入图片描述

单一邻居时,每一个点都对预测结果有影响,出现过拟合现象;考虑多邻居后有所改观,但仍然拟合得不够好。

四、小结

课本上的KNN介绍只不过是皮毛,看完这些代码只能差不多了解到KNN的一些浅薄应用(无非就是调用库KNeighborsClassifier或者KNeighborsRegression来预测结果,比较精度。
KNN算法不适用于多特征数据集,实际中应用不是特别多,了解就好。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值