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

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 默认使用统一权重,即每个邻域中的点的权重相同,如果使用距离作为权重,那么距离待分类点较近的近邻会被赋予更大的权重,在决策过程起到更重要的作用。

猜你喜欢

转载自blog.csdn.net/lyb06/article/details/130162731