sklearn实验2——使用KNN对鸢尾花数据集分类

该实验详细介绍了KNN算法的基本原理和操作步骤,通过鸢尾花数据集展示了不同近邻数(K值)和权重设置对分类精度的影响。实验发现,增加近邻数可以使决策边界更平滑,降低模型复杂度,而使用距离权重可以强化近邻的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、实验目的

  1. 理解近邻法的基本原理,能实现K近邻(KNN)算法;

  2. 针对特定应用场景及数据,能用KNN进行分类;

  3. 熟悉不同近邻数对于算法的影响。

2、实验原理

KNN算法是一种简单分类算法。它以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则,将未知样本与K个最近邻样本中所属类别占比较多的归为一类。

3、实验内容

  1. 读取iris鸢尾花数据集。
  2. KNN算法实现:
    1. 使用默认的近邻数量和权重,预测精度为多少?
    2. 增大或减少近邻数量,观察对算法的影响;
    3. 改变权重设置,观察对算法的影响。
  3. 使用花萼长度和花萼宽度,设置近邻数量为5,绘制KNN分类器图。

4、实验代码

1、导入实验要用到的相关库

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

2、加载并划分鸢尾花数据集(这里选择了所有的特征用于分类)

iris_data = load_iris()
X = iris_data["data"]
y = iris_data["target"]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=10)

3、使用默认的近邻数量和权重,查看预测精度

# 使用默认的近邻数量和权重,查看预测精度
knn = KNeighborsClassifier()    # 默认 n_neighbors = 5, weight = 'uniform'
knn.fit(X_train, y_train)       # 用训练数据拟合模型
print("模型精度:", knn.score(X_test, y_test))

K近邻分类模型 KNeighborsClassifier 默认 n_neighbors = 5,即使用与未知样本距离最近的 5 个训练样本对其进行分类;默认 weight = 'uniform',表示使用统一权重,即每个邻域中的所有点均被加权。如果设置 weight = 'distance',表示权重点与其距离的倒数,即查询点的近邻比远处的近邻具有更大的影响力。

输出:

模型精度: 0.9736842105263158

4、查看测试集第一个数据划分所用到的数据点

# 查看测试集第一个数据划分所用到的数据点
n = knn.kneighbors_graph(X_test)
print(n.toarray()[0])

kneighbors_gragp() 计算 X_test 中点的 k 临近点的(加权)图形 ,其输出为稀疏矩阵的格式,将其转换为数组的形式输出,第一个数据的结果如下所示。

输出:

[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.
 0. 1. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]

5、增大近邻数,查看对算法的影响

# 增大近邻数,查看对算法的影响
knn = KNeighborsClassifier(n_neighbors=15) 
knn.fit(X_train, y_train)       # 用训练数据拟合模型
print("模型精度:", knn.score(X_test, y_test))

输出:

模型精度: 0.9736842105263158

6、改变权重设置,查看对算法的影响

# 改变权重设置,查看对算法的影响
knn = KNeighborsClassifier(weights='distance')  # distence表示用距离的导数作为权重设置,即越近的点影响力越大
knn.fit(X_train, y_train)
print("模型精度:", knn.score(X_test, y_test))

输出:

模型精度: 0.9736842105263158

7、查看不同 n_neighbors 的设置在训练集和测试集上的精度

# 查看不同 n_neighbors 的设置在训练集和测试集上的精度
training_accuracy = []
test_accuracy = []
# n_neighbors取值从1到16
neighbors_settings = range(1, 16)
for n_neighbors in neighbors_settings:
    # 构建模型
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)
    clf.fit(X_train, y_train)
    # 记录训练集精度
    training_accuracy.append(clf.score(X_train, y_train))
    # 记录泛化精度
    test_accuracy.append(clf.score(X_test, y_test))
plt.plot(neighbors_settings, training_accuracy, label="training accuracy")
plt.plot(neighbors_settings, test_accuracy, label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend()

输出:

 8、使用花萼长度和花萼宽度,设置近邻数量为5,绘制KNN分类器图

# 使用花萼长度和花萼宽度,设置近邻数量为5,绘制KNN分类器图
X = iris_data["data"][:,(0,1)]
y = iris_data["target"]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=1)

from matplotlib.colors import ListedColormap
h = .02  # 设置网格中的步长
n_neighbors = 5

# 提取色谱
cmap_light = ListedColormap(['orange', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])

for weights in ['uniform', 'distance']:
    # 我们创建最近邻分类器的实例并拟合数据。
    clf = KNeighborsClassifier(n_neighbors, weights=weights)
    clf.fit(X, y)

    # 绘制决策边界。 为此,我们将为网格[x_min,x_max] x [y_min,y_max]中的每个点分配颜色。
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

    # 将结果放入颜色图
    Z = Z.reshape(xx.shape)
    plt.figure()
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)

    # 绘制训练数据
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.title("3-Class classification (k = %i, weights = '%s')"
              % (n_neighbors, weights))

plt.show()

输出:

 

5、实验总结

KNN 不同近邻数对算法的影响:
随着近邻数越来越多,决策边界也越来越平滑。更平滑的边界对应更简单的模型。
使用更少的邻居对应更高的模型复杂度,而使用更多的邻居对应更低的模型复杂度。

KNN 不同权重对算法的影响:
KNN 默认使用统一权重,即每个邻域中的点的权重相同,如果使用距离作为权重,那么距离待分类点较近的近邻会被赋予更大的权重,在决策过程起到更重要的作用。

### 实现KNN算法鸢尾花数据集进行分类 #### 加载准备数据 为了使用KNN算法鸢尾花数据集进行分类,首先需要加载数据集。`scikit-learn`库提供了方便的方法来获取这个经典的数据集。 ```python from sklearn.datasets import load_iris import numpy as np # 加载鸢尾花数据集 iris = load_iris() print(f"数据集的键: {iris.keys()}") # 显示数据集中包含的信息类别[^4] # 查看特征名称和目标名称 print(f"特征名: {iris['feature_names']}") print(f"标记名: {iris['target_names']}") # 数据形状 print(f"数据维度: {iris.data.shape}") # 总共有150条记录,每条记录有4个属性[^3] ``` 这段代码展示了如何导入必要的模块以及加载鸢尾花数据集打印了一些基本信息以便了解所处理的内容。 #### 划分训练集与测试集 为了让模型能够评估其性能,在实际预测之前应该把原始数据分为两部分——一部分用于训练模型,另一部分用来验证模型的效果。 ```python from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( iris['data'], iris['target'], test_size=0.2, random_state=0) print(f"训练样本数量: {len(X_train)}") print(f"测试样本数量: {len(X_test)}") ``` 这里设置了`test_size=0.2`意味着80%的数据会被用作训练而剩下的20%则作为测试用途;同时指定了`random_state=0`以确保每次分割的结果一致。 #### 创建训练KNN模型 有了上述准备工作之后就可以创建一个K近邻(KNN)分类器实例将它应用于训练好的数据上了: ```python from sklearn.neighbors import KNeighborsClassifier knn_clf = KNeighborsClassifier(n_neighbors=3) # 设置邻居数为3 knn_clf.fit(X_train, y_train) ``` 此段脚本定义了一个具有三个最近邻参数(`n_neighbors`)的KNN分类器对象,调用了`.fit()`函数让该分类器学习给定输入输出之间的关系模式[^1]。 #### 测试模型准确性 最后一步就是利用预留出来的那部分未见过的新数据去检验我们刚刚建立起来的学习机究竟表现得怎么样: ```python accuracy_score = knn_clf.score(X_test, y_test)*100 print(f'Accuracy on the testing set is {accuracy_score:.2f}%') ``` 这会计算出我们的KNN分类器对于未知案例做出正确判断的比例,从而给出一个直观的感受关于整个建模过程的有效程度[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值