【Sklearn】基于K邻近算法的数据分类预测(Excel可直接替换数据)
- 1.模型原理
- 模型原理:
- 数学模型:
- 2.模型参数
- 3.文件结构
- 4.Excel数据
- 5.下载地址
- 6.完整代码
- 7.运行结果
1.模型原理
K最近邻(K-Nearest Neighbors,KNN)是一种基本的监督学习算法,用于分类和回归任务。其模型原理如下:
模型原理:
对于分类任务,KNN的原理可以概括为以下几个步骤:
-
训练阶段: 将训练数据集中的每个数据点与其标签一起存储。这些数据点和标签构成了训练样本。
-
预测阶段: 当需要对新的数据点进行分类时,KNN算法执行以下步骤:
-
计算测试数据点与训练数据集中每个点之间的距离,使用所选择的距离度量(如欧氏距离)。
-
从训练数据集中选择K个与测试数据点距离最近的数据点,这些数据点就是测试数据点的“最近邻居”。
-
根据这K个最近邻居的标签,预测测试数据点的标签。对于分类任务,可以通过多数表决的方式,即选择K个邻居中出现最多次的标签作为预测标签。
-
数学模型:
假设我们有一个训练数据集 D D D,包含 N N N 个样本,每个样本有 d d d 个特征。在分类任务中,每个样本都有一个标签。
- 训练数据集: D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } D = \{(x_1, y_1), (x_2, y_2), ..., (x_N, y_N)\} D={(x1,y1),(x2,y2),...,(xN,yN)},其中 x i x_i xi 是一个 d d d 维特征向量, y i y_i yi 是样本 x i x_i xi 对应的标签。
对于一个新的测试数据点 x x x,KNN的分类过程可以用以下公式表示:
y ^ = argmax y ∑ i = 1 K w i ⋅ I ( y i = y ) \hat{y} = \text{argmax}_y \sum_{i=1}^{K} w_i \cdot I(y_i = y) y^=argmaxyi=1∑Kwi⋅I(yi=y)
其中:
- y ^ \hat{y} y^ 是测试数据点的预测标签。
- y i y_i yi 是第 i i i 个最近邻居的标签。
- w i w_i wi 是第 i i i 个最近邻居的权重(通常为1或距离的倒数)。
- I ( y i = y ) I(y_i = y) I(yi=y) 是指示函数,如果 y i = y y_i = y yi=y,则为1,否则为0。
KNN算法在预测时需要选择合适的 K K K 值、距离度量、权重等参数。较小的 K K K 值会导致模型更容易受到噪声影响,而较大的 K K K 值可能导致决策边界不够灵活。距离度量的选择和权重的设置也会影响算法的性能。
当需要对新的数据点进行分类时,KNN算法执行以下步骤:
-
计算距离: 对于测试数据点 x x x,计算它与训练数据集中每个数据点 x i x_i xi 之间的距离。可以使用欧氏距离(Euclidean distance)等距离度量方法:
欧氏距离公式: d ( x , x i ) = ∑ j = 1 d ( x j − x i j ) 2 d(x, x_i) = \sqrt{\sum_{j=1}^{d} (x_j - x_{ij})^2} d(x,xi)=∑j=1d(xj−xij)2
其中, d d d 是数据的维度, x j x_j xj 是测试数据点的第 j j j 个特征值, x i j x_{ij} xij 是训练数据点 x i x_i xi 的第 j j j 个特征值。
-
选择最近邻: 从训练数据集中选择距离测试数据点最近的 K K K 个数据点,这些数据点就是测试数据点的最近邻居。
-
多数表决: 对于分类任务,根据最近邻居的标签进行多数表决,选择出现次数最多的标签作为测试数据点的预测标签。
-
欧氏距离公式:
d ( x , x i ) = ∑ j = 1 d ( x j − x i j ) 2 d(x, x_i) = \sqrt{\sum_{j=1}^{d} (x_j - x_{ij})^2} d(x,xi)=j=1∑d(xj−xij)2
在这个公式中, d d d 是数据的维度, x j x_j xj 是测试数据点的第 j j j 个特征值, x i j x_{ij} xij 是训练数据点 x i x_i xi 的第 j j j 个特征值。
请注意,上述描述和公式仅概括了KNN算法的基本原理。在实际应用中,还需要根据具体问题选择合适的距离度量、权重等参数,以及处理距离相等的情况等。
2.模型参数
KNeighborsClassifier
是Scikit-Learn中用于K最近邻分类的类。以下是部分常用的参数列表:
- n_neighbors: K值,表示用于预测的最近邻居的数量。
- weights: 用于预测的近邻的权重,可以是’uniform’(均匀权重)或’distance’(根据距离进行加权)。
- algorithm: 用于计算最近邻的算法,可以是’auto’(根据数据自动选择),‘ball_tree’,‘kd_tree’,‘brute’。
- leaf_size: 在使用’ball_tree’或’kd_tree’算法时,指定叶子节点的大小。
- p: 距离度量参数,1表示使用曼哈顿距离,2表示使用欧氏距离,其他值表示使用闵可夫斯基距离。
- metric: 距离度量函数,默认为’minkowski’。可以是各种内置度量,或者自定义距离度量函数。
- n_jobs: 并行计算的任务数量,-1表示使用所有可用的CPU核心。
- algorithm: 用于计算最近邻的算法,可以是’auto’(自动选择),‘ball_tree’,‘kd_tree’,‘brute’。
- leaf_size: 在使用’ball_tree’或’kd_tree’算法时,指定叶子节点的大小。
- metric_params: 距离度量的附加参数。
以下是使用KNeighborsClassifier
的例子:
from sklearn.neighbors import KNeighborsClassifier
# 创建K最近邻模型,设置K值为5,使用欧氏距离,使用均匀权重
model = KNeighborsClassifier(n_neighbors=5, weights='uniform', p=2)
请注意,上述示例只是一部分参数,还有其他可用参数未列出。您可以根据需求在创建模型时调整这些参数。
3.文件结构
iris.xlsx % 可替换数据集
Main.py % 主函数
4.Excel数据
5.下载地址
- 资源下载地址
6.完整代码
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
def knn_classification(data_path, test_size=0.2, random_state=42, n_neighbors=3):
# 加载数据
data = pd.read_excel(data_path)
# 分割特征和标签
X = data.iloc[:, :-1] # 所有列除了最后一列
y = data.iloc[:, -1] # 最后一列
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=random_state)
# 创建K最近邻模型
# 1. ** n_neighbors: ** K值,表示用于预测的最近邻居的数量。
# 2. ** weights: ** 用于预测的近邻的权重,可以是'uniform'(均匀权重)或'distance'(根据距离进行加权)。
# 3. ** algorithm: ** 用于计算最近邻的算法,可以是'auto'(根据数据自动选择),'ball_tree','kd_tree','brute'。
# 4. ** leaf_size: ** 在使用'ball_tree'或'kd_tree'算法时,指定叶子节点的大小。
# 5. ** p: ** 距离度量参数,1表示使用曼哈顿距离,2表示使用欧氏距离,其他值表示使用闵可夫斯基距离。
# 6. ** metric: ** 距离度量函数,默认为'minkowski'。可以是各种内置度量,或者自定义距离度量函数。
# 7. ** n_jobs: ** 并行计算的任务数量,-1表示使用所有可用的CPU核心。
# 8. ** algorithm: ** 用于计算最近邻的算法,可以是'auto'(自动选择),'ball_tree','kd_tree','brute'。
# 9. ** leaf_size: ** 在使用'ball_tree'或'kd_tree'算法时,指定叶子节点的大小。
# 10. ** metric_params: ** 距离度量的附加参数。
# 创建K最近邻模型,设置K值为5,使用欧氏距离,使用均匀权重
model = KNeighborsClassifier(n_neighbors=5, weights='uniform', p=2)
# 在训练集上训练模型
model.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = model.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
return confusion_matrix(y_test, y_pred), y_test.values, y_pred, accuracy
if __name__ == "__main__":
# 使用函数进行分类任务
data_path = "iris.xlsx"
confusion_mat, true_labels, predicted_labels, accuracy = knn_classification(data_path, n_neighbors=5)
print("真实值:", true_labels)
print("预测值:", predicted_labels)
print("准确率:{:.2%}".format(accuracy))
# 绘制混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_mat, annot=True, fmt="d", cmap="Blues")
plt.title("Confusion Matrix")
plt.xlabel("Predicted Labels")
plt.ylabel("True Labels")
plt.show()
# 用圆圈表示真实值,用叉叉表示预测值
# 绘制真实值与预测值的对比结果
plt.figure(figsize=(10, 6))
plt.plot(true_labels, 'o', label="True Labels")
plt.plot(predicted_labels, 'x', label="Predicted Labels")
plt.title("True Labels vs Predicted Labels")
plt.xlabel("Sample Index")
plt.ylabel("Label")
plt.legend()
plt.show()