【 Python 全栈开发 - 人工智能篇 - 43 】KNN算法


一、KNN算法

1.1 算法概述

K最近邻(K-Nearest NeighborsKNN)算法是一种常用的基于实例的监督学习算法,它可以用于分类和回归任务。KNN算法的核心思想是通过计算样本之间的距离,将测试样本归类到训练样本中距离最近的 K 个邻居所属的类别。

KNN 算法的基本步骤如下:

  1. 选择 K 的值,即确定最近邻的数量。
  2. 计算测试样本与训练样本之间的距离,常用的距离度量方法包括欧氏距离、曼哈顿距离等。
  3. 根据距离计算结果,找出 K 个距离最近的训练样本。
  4. 根据 K 个最近邻的类别,通过多数投票的方式确定测试样本的类别。
  5. 输出测试样本的预测类别。

KNN 算法的优点包括简单易懂、无需训练过程、适用于多分类问题等。然而,它的缺点是计算复杂度高、存储空间开销大,尤其在处理大规模数据集时效率较低。

1.2 KNN 算法的应用领域

KNN 算法在许多领域都有广泛的应用,以下是几个常见的应用领域:

  1. 图像识别:KNN 算法可以用于图像分类和识别任务。通过计算图像之间的距离,将待识别图像归类到训练集中与之最相似的类别,实现图像识别和分类。
  2. 推荐系统:KNN 算法可以用于推荐系统中的用户协同过滤。通过计算用户之间的相似度,找到与目标用户最相似的K个用户,将这些用户喜欢的物品推荐给目标用户。
  3. 文本分类:KNN 算法可以用于文本分类任务,如垃圾邮件过滤、情感分析等。通过计算文本之间的相似度,将待分类的文本归类到与之最相似的K个训练文本所属的类别。
  4. 医学诊断:KNN 算法可以用于医学诊断中的疾病分类。通过计算患者之间的相似度,将待诊断的患者归类到与之最相似的K个训练患者所患疾病的类别。

下面是一个使用 Python 实现的简单的 KNN 算法示例:

import numpy as np

def euclidean_distance(x1, x2):
    return np.sqrt(np.sum((x1 - x2) ** 2))

class KNN:
    def __init__(self, k=3):
        self.k = k

    def fit(self, X, y):
        self.X_train = X
        self.y_train = y

    def predict(self, X):
        y_pred = [self._predict(x) for x in X]
        return np.array(y_pred)

    def _predict(self, x):
        distances = [euclidean_distance(x, x_train) for x_train in self.X_train]
        k_indices = np.argsort(distances)[:self.k]
        k_nearest_labels = [self.y_train[i] for i in k_indices]
        most_common = np.argmax(np.bincount(k_nearest_labels))
        return most_common

# 示例用法
X_train = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]])
y_train = np.array([0, 0, 1, 1, 0, 1])

knn = KNN(k=3)
knn.fit(X_train, y_train)
X_test = np.array([[2, 2], [1, 1], [6, 9]])
y_pred = knn.predict(X_test)

print(y_pred)  # 输出预测结果

二、理论基础

2.1 KNN算法原理

KNN 算法基于一个简单的思想:如果一个样本在特征空间中的 K 个最近邻居中的大多数属于某个类别,那么该样本很可能属于这个类别。KNN 算法在模型训练过程中不会进行显式的模型学习,而是直接利用训练数据进行预测。下面简要介绍 KNN 算法的步骤:

  1. 计算测试样本与训练样本之间的距离。
  2. 选择距离测试样本最近的K个训练样本。
  3. 根据这K个训练样本的类别进行投票,选择票数最多的类别作为测试样本的预测类别。

KNN 算法在处理分类问题时,通常使用 “多数表决” 的方式来确定样本的类别;在处理回归问题时,可以采用平均值等方式得到预测结果。

2.2 距离度量方法

在 KNN 算法中,计算样本之间的距离是一个关键步骤,决定了最终的分类结果。常用的距离度量方法包括:

2.2.1 欧式距离(Euclidean Distance)

欧式距离是最常用的距离度量方法。对于两个样本向量 x 和 y,其欧式距离可以通过以下公式计算:

distance = sqrt(sum((x_i - y_i)^2) for i in range(len(x)))

2.2.2 曼哈顿距离(Manhattan Distance)

曼哈顿距离也称为城市街区距离,它计算样本向量之间的距离,公式如下:

distance = sum(abs(x_i - y_i) for i in range(len(x)))

2.2.3 余弦相似度(Cosine Similarity)

余弦相似度度量样本之间的夹角余弦值,可以衡量它们方向上的相似程度。对于两个样本向量 x 和 y,余弦相似度的计算公式如下:

similarity = dot(x, y) / (norm(x) * norm(y))

2.3 K值的选择

K 值的选择是 KNN 算法中的一个重要参数。K 值过小容易受到噪声影响,K 值过大又可能忽略了样本局部特性。因此,选择一个合适的 K 值至关重要。

K 值的选择可以通过交叉验证等方法进行。通常情况下,较小的 K 值(例如 1 或 3)容易产生复杂的决策边界,适合处理噪声较小的数据集;而较大的 K 值(例如 10 或 20)则会产生较为平滑的决策边界,适用于处理噪声较大的数据集。

当然,K 值的选择也需要考虑计算复杂度。较大的K值意味着在预测时需要考虑更多的训练样本,计算量相应增加。

总之,K 值的选择需要综合考虑数据集特性和计算复杂度,以达到最优的分类性能。

使用 Python 实现 KNN 算法:

import numpy as np

class KNN:
    def __init__(self, k=3, distance_metric='euclidean'):
        self.k = k
        self.distance_metric = distance_metric

    def fit(self, X_train, y_train):
        self.X_train = X_train
        self.y_train = y_train

    def predict(self, X_test):
        y_pred = [self._predict(x for x in X_test]
        return np.array(y_pred)

    def _predict(self, x):
        # 计算样本x与所有训练样本之间的距离
        if self.distance_metric == 'euclidean':
            distances = [np.linalg.norm(x - x_train) for x_train in self.X_train]
        elif self.distance_metric == 'manhattan':
            distances = [np.sum(np.abs(x - x_train)) for x_train in self.X_train]
        elif self.distance_metric == 'cosine':
            distances = [np.dot(x, x_train) / (np.linalg.norm(x) * np.linalg.norm(x_train)) for x_train in self.X_train]
        else:
            raise ValueError("Invalid distance metric. Supported metrics: 'euclidean', 'manhattan', 'cosine'")

        # 对距离进行排序,取前k个最近的样本索引
        k_indices = np.argsort(distances)[:self.k]

        # 获取这k个样本的类别
        k_nearest_classes = [self.y_train[i] for i in k_indices]

        # 对类别进行多数表决,得到预测类别
        most_common = np.bincount(k_nearest_classes).argmax()
        return most_common

# 示例数据
X_train = np.array([[1, 2], [2, 3], [3, 4], [5, 1]])
y_train = np.array([0, 0, 1, 1])
X_test = np.array([[2.5, 3.5], [4, 2]])

# 创建KNN模型并进行训练
knn = KNN(k=2, distance_metric='euclidean')
knn.fit(X_train, y_train)

# 进行预测
predictions = knn.predict(X_test)
print(predictions) # 输出 [0 1]

以上代码演示了一个简单的 KNN 算法的实现,并使用欧式距离作为距离度量方法。


三、数据准备

本文使用 sklearn 中的鸢尾花数据集做示范。

2.1 数据预处理

在使用 KNN 算法之前,我们需要对数据进行预处理。首先,导入所需的库和鸢尾花数据集:

from sklearn import datasets

# 导入鸢尾花数据集
iris = datasets.load_iris()

2.2 特征选择和特征缩放

KNN 算法的性能受特征的选择和特征缩放的影响。在本例中,我们选择鸢尾花数据集的所有特征,并对其进行缩放以确保它们具有相似的尺度。

from sklearn.preprocessing import StandardScaler

# 特征选择
X = iris.data

# 特征缩放
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

四、实现KNN算法

4.1 导入必要的库和数据集

首先,我们需要导入一些必要的库和数据集。scikit-learn 库提供了许多机器学习算法的实现,包括 KNN。

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

4.2 数据集的划分

我们将使用 scikit-learn 库中的鸢尾花数据集。这个数据集包含了 150 个样本,每个样本有 4 个特征,分别是花萼长度、花萼宽度、花瓣长度和花瓣宽度。数据集中的每个样本都属于三个类别之一:Setosa、Versicolor 和 Virginica。

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

4.3 计算距离

KNN 算法的核心是计算样本之间的距离。常用的距离度量方法有欧氏距离、曼哈顿距离等。在这里,我们将使用默认的欧氏距离。

# 计算欧氏距离
def euclidean_distance(x1, x2):
    return np.sqrt(np.sum((x1 - x2) ** 2))

4.4 找出最近的 K 个近邻

在 KNN 算法中,我们需要找出与待预测样本最近的 K 个邻居。我们可以通过计算待预测样本与所有训练样本之间的距离,并选择最近的 K 个邻居。

# 找出最近的K个邻居
def find_nearest_neighbors(X_train, y_train, x, K):
    distances = []
    for i, sample in enumerate(X_train):
        distance = euclidean_distance(sample, x)
        distances.append((distance, y_train[i]))
    
    distances.sort(key=lambda x: x[0])
    neighbors = distances[:K]
    return neighbors

4.5 进行分类或回归预测

找出最近的 K 个邻居之后,我们可以使用投票或取平均值的方法进行分类或回归预测。

# 进行分类预测
def predict_classification(neighbors):
    class_votes = {}
    for neighbor in neighbors:
        label = neighbor[1]
        if label in class_votes:
            class_votes[label] += 1
        else:
            class_votes[label] = 1
    
    sorted_votes = sorted(class_votes.items(), key=lambda x: x[1], reverse=True)
    return sorted_votes[0][0]

# 进行回归预测
def predict_regression(neighbors):
    return np.mean([neighbor[1] for neighbor in neighbors])

4.6 模型评估

最后,我们可以使用测试集对模型进行评估,计算预测准确率。

# 创建KNN分类器
knn = KNeighborsClassifier(n_neighbors=3)

# 在训练集上训练模型
knn.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

五、参数调优

在使用 KNN 算法时,需要对一些关键参数进行调优,以提高算法的性能。在本章节中,我们将重点讨论以下两个参数的调优:K 值的选择和距离度量方法的选择。

5.1 K值的选择

KNN 算法中的 K 值代表了最近邻的数量。选择合适的 K 值对算法的性能有重要影响。较小的 K 值会使模型对噪声敏感,可能导致过拟合;较大的 K 值可能会使模型丧失一些局部特性,导致欠拟合。

为了选择合适的 K 值,我们可以尝试不同的 K 值,并通过交叉验证等方法比较它们在验证集上的性能。通常情况下,K 值选择一个奇数可以避免分类不确定性。

以下是一个示例代码,演示如何通过网格搜索法选择最佳的 K 值:

from sklearn.model_selection import GridSearchCV

# 创建KNN分类器
knn = KNeighborsClassifier()

# 设置参数范围
param_grid = {'n_neighbors': [1, 3, 5, 7, 9]}

# 使用网格搜索法选择最佳的K值
grid_search = GridSearchCV(knn, param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 打印最佳的K值和对应的准确率
print("Best K:", grid_search.best_params_)
print("Best Accuracy:", grid_search.best_score_)

GridSearchCV函数通过交叉验证的方式,遍历指定参数的所有可能取值,并选择在验证集上性能最好的参数取值。

5.2 距离度量方法的选择

KNN 算法中使用的距离度量方法对最终的分类结果有直接影响。在实际应用中,常用的距离度量方法有欧氏距离、曼哈顿距离和余弦相似度等。

为了选择合适的距离度量方法,我们可以通过交叉验证等方法比较它们在验证集上的性能。以下是一个示例代码,演示如何通过网格搜索法选择最佳的距离度量方法:

# 创建KNN分类器
knn = KNeighborsClassifier()

# 设置参数范围
param_grid = {'metric': ['euclidean', 'manhattan', 'cosine']}

# 使用网格搜索法选择最佳的距离度量方法
grid_search = GridSearchCV(knn, param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 打印最佳的距离度量方法和对应的准确率
print("Best Distance Metric:", grid_search.best_params_)
print("Best Accuracy:", grid_search.best_score_)

通过比较不同的距离度量方法在验证集上的性能,我们可以选择最合适的距离度量方法。

5.3 代码

以下是一个补充示例代码,结合之前的 KNN 算法和数据集的前处理部分,演示如何应用参数调优的方法选择最佳的 K 值和距离度量方法:

# 导入必要的库和数据集
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建KNN分类器
knn = KNeighborsClassifier()

# 设置参数范围
param_grid = {'n_neighbors': [1, 3, 5, 7, 9], 'metric': ['euclidean', 'manhattan', 'cosine']}

# 使用网格搜索法选择最佳的参数
grid_search = GridSearchCV(knn, param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 打印最佳的参数和对应的准确率
print("Best Parameters:", grid_search.best_params_)
print("Best Accuracy:", grid_search.best_score_)

# 在测试集上进行预测
y_pred = grid_search.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Test Accuracy:", accuracy)

通过参数调优,我们可以选择最佳的 K 值和最佳的距离度量方法,从而提高 KNN 算法的性能。


六、KNN算法的扩展

6.1 加权KNN

在标准的 KNN 算法中,每个最近邻的投票权重是相等的。但在某些情况下,我们希望给距离更近的邻居更高的权重。这就是加权 KNN 算法的核心思想。

我们将使用 scikit-learn 库中的鸢尾花数据集来演示加权 KNN 的使用。首先,我们需要导入必要的库和数据集:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# 导入鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target

接下来,我们将数据集分割成训练集和测试集,并使用加权 KNN 进行分类:

# 将数据集分割成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建加权KNN分类器对象
knn = KNeighborsClassifier(weights='distance')

# 在训练集上训练模型
knn.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

在上述代码中,我们通过设置weights='distance'来启用加权 KNN。这样,距离更近的邻居将具有更高的权重,对分类结果的影响更大。

6.2 KNN回归

除了分类任务,KNN 算法还可以用于回归任务。在 KNN 回归中,我们预测一个样本的目标值,通过考虑其最近邻的目标值的平均或加权平均。

我们仍然使用鸢尾花数据集,但这次我们将预测花瓣长度(petal length)的值。以下是使用 KNN 回归进行预测的示例代码:

from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error

# 创建KNN回归器对象
knn_reg = KNeighborsRegressor(n_neighbors=5)

# 在训练集上训练模型
knn_reg.fit(X_train, y_train)

# 在测试集上进行预测
y_pred_reg = knn_reg.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred_reg)
print("Mean Squared Error:", mse)

在上述代码中,我们创建了一个 KNN 回归器对象,并将邻居的数量设置为 5。然后,我们使用训练集训练模型,并在测试集上进行预测。最后,我们计算预测结果与真实目标值之间的均方误差。

6.3 KD树

KNN 算法在处理大型数据集时可能会遇到效率问题,因为它需要计算每个样本与所有训练样本之间的距离。为了加快 KNN 算法的速度,可以使用 KD 树。

KD 树是一种二叉树结构,用于存储样本点。它可以将搜索最近邻的时间复杂度从O(n)降低到O(log(n))

以下是使用 KD 树进行 KNN 分类的示例代码:

from sklearn.neighbors import KDTree

# 构建KD树
kdtree = KDTree(X_train)

# 设置最近邻的数量
k = 3

# 查询测试样本的最近邻
distances, indices = kdtree.query(X_test, k)

# 统计最近邻的类别
y_pred_kd = [y_train[idx] for idx in indices]

# 计算准确率
accuracy_kd = accuracy_score(y_test, y_pred_kd)
print("Accuracy (KD Tree):", accuracy_kd)

在上述代码中,我们首先使用训练集构建了一个 KD 树。然后,我们通过调用query方法来查询测试样本的最近邻。最后,我们统计最近邻的类别,并计算准确率。

通过使用 KD 树,我们可以加速 KNN 算法的搜索过程,特别是对于高维数据集而言。


七、实例应用

7.1 电影推荐系统

开发步骤

在开始之前,我们需要安装以下依赖库:pandassklearn。你可以使用以下命令进行安装:

pip install pandas sklearn

首先,我们需要加载MovieLens数据集。你可以从https://grouplens.org/datasets/movielens/下载MovieLens数据集,也可以直接连同本电影推荐系统一起免费下载(推荐,比较快):https://download.csdn.net/download/SHUTIAN2010/88056667

下载后,你将获得三个文件:movies.datratings.datusers.dat

首先,导入了需要的库:pandas库用于数据处理,sklearn库中的NearestNeighbors类用于构建 KNN 模型。

import pandas as pd
from sklearn.neighbors import NearestNeighbors

接下来,加载三个数据集:movies(包含电影 ID、标题和类别)、ratings(包含用户 ID、电影 ID、评分和时间戳)和users(包含用户 ID、性别、年龄、职业和邮编)。

# 加载数据集
movies = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\movies.dat', sep='::', header=None, names=['movieId', 'title', 'genres'], encoding='latin1', engine='python')
ratings = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\ratings.dat', sep='::', header=None, names=['userId', 'movieId', 'rating', 'timestamp'], encoding='latin1', engine='python')
users = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\users.dat', sep='::', header=None, names=['userId', 'gender', 'age', 'occupation', 'zipCode'], encoding='latin1', engine='python')

然后,将moviesratings两个数据集合并为一个新的数据集movie_ratings,基于'movieId'列进行合并。

# 合并电影和评分数据集
movie_ratings = pd.merge(movies, ratings, on='movieId')

之后,使用pivot_table函数创建了一个电影评分矩阵movie_matrix,以用户 ID 为行索引,电影 ID 为列索引,评分为值。缺失的评分值用 0 填充。

# 创建电影评分矩阵
movie_matrix = movie_ratings.pivot_table(index='userId', columns='movieId', values='rating').fillna(0)

接着,设置 KNN 模型的参数:k 为最近邻居的数量(在这里设置为 10),metric设为'cosine'表示使用余弦相似度进行距离计算,algorithm设为'brute'表示使用暴力法搜索最近邻居。

# 训练KNN模型
k = 10  # 设置最近邻居数量
knn_model = NearestNeighbors(metric='cosine', algorithm='brute')

然后,使用fit函数将电影评分矩阵作为输入,训练了 KNN 模型。

knn_model.fit(movie_matrix.values)

接下来,指定要为哪个用户进行电影推荐,这里的用户 ID 为 1。通过movie_matrixindex属性和get_loc方法,获取了用户 ID 在电影评分矩阵中的索引。

# 为用户进行电影推荐
user_id = 1  # 指定用户ID
user_index = movie_matrix.index.get_loc(user_id)  # 获取用户索引

然后,代码使用kneighbors函数找到与指定用户最相似的 k 个邻居。首先,代码使用iloc方法定位到用户在电影评分矩阵中的行,并用reshape函数将其变为二维数组。然后,代码将这个数组作为输入,使用kneighbors函数得到最近邻居的距离和索引。

distances, indices = knn_model.kneighbors(movie_matrix.iloc[user_index, :].values.reshape(1, -1), n_neighbors=k+1)

最后,代码通过遍历邻居索引列表,并筛选出有效的电影 ID(小于电影评分矩阵中电影 ID 的数量),将推荐的电影 ID 添加到recommended_movie_ids列表中。

for i in range(1, len(indices[0])):
    if indices[0][i] < len(movie_matrix.columns):
        recommended_movie_ids.append(movie_matrix.columns[indices[0][i] - 1])

最后,利用isin函数筛选出推荐电影 ID 对应的电影信息,并打印出电影的 ID、标题和类别。

recommended_movies = movies[movies['movieId'].isin(recommended_movie_ids)]
print(recommended_movies[['movieId', 'title', 'genres']])

输出:

      movieId                        title                       genres
549       553             Tombstone (1993)                      Western
1359     1380                Grease (1978)       Comedy|Musical|Romance
1441     1468            Booty Call (1997)               Comedy|Romance
1564     1605        Excess Baggage (1997)            Adventure|Romance
1569     1611  My Own Private Idaho (1991)                        Drama
1968     2037            Candleshoe (1977)  Adventure|Children's|Comedy

完整代码

直接免费下载(包括数据库):https://download.csdn.net/download/SHUTIAN2010/88056667

import pandas as pd
from sklearn.neighbors import NearestNeighbors

# 加载数据集
movies = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\movies.dat', sep='::', header=None, names=['movieId', 'title', 'genres'], encoding='latin1', engine='python')
ratings = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\ratings.dat', sep='::', header=None, names=['userId', 'movieId', 'rating', 'timestamp'], encoding='latin1', engine='python')
users = pd.read_csv(r'D:\Administrator\Desktop\st\PROGRAMS\Python\10 KNN\users.dat', sep='::', header=None, names=['userId', 'gender', 'age', 'occupation', 'zipCode'], encoding='latin1', engine='python')

# 合并电影和评分数据集
movie_ratings = pd.merge(movies, ratings, on='movieId')

# 创建电影评分矩阵
movie_matrix = movie_ratings.pivot_table(index='userId', columns='movieId', values='rating').fillna(0)

# 训练KNN模型
k = 10  # 设置最近邻居数量
knn_model = NearestNeighbors(metric='cosine', algorithm='brute')
knn_model.fit(movie_matrix.values)

# 为用户进行电影推荐
user_id = 1  # 指定用户ID
user_index = movie_matrix.index.get_loc(user_id)  # 获取用户索引

distances, indices = knn_model.kneighbors(movie_matrix.iloc[user_index, :].values.reshape(1, -1), n_neighbors=k+1)
recommended_movie_ids = []
for i in range(1, len(indices[0])):
    if indices[0][i] < len(movie_matrix.columns):
        recommended_movie_ids.append(movie_matrix.columns[indices[0][i] - 1])


recommended_movies = movies[movies['movieId'].isin(recommended_movie_ids)]
print(recommended_movies[['movieId', 'title', 'genres']])

7.2 手写数字识别

开发步骤

首先,导入需要使用的库和模块。
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

接下来,加载手写数字数据集。

# 加载手写数字数据集
digits = load_digits()
X = digits.data
y = digits.target

然后,通过调用 train_test_split() 函数将数据集划分为训练集和测试集。

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

接下来,使用 KNeighborsClassifier 类构建了一个KNN分类器对象 knn

# 构建KNN分类器
knn = KNeighborsClassifier(n_neighbors=5)

然后,调用 knn.fit() 方法训练模型,将训练集的特征矩阵 X_train 和目标向量 y_train 作为参数传递给该方法。

# 训练模型
knn.fit(X_train, y_train)

接着,使用训练好的模型 knn 对测试集的特征矩阵 X_test 进行预测,将预测结果保存在 y_pred 中。

# 预测测试集结果
y_pred = knn.predict(X_test)

最后,通过调用 accuracy_score() 函数计算了预测结果 y_pred 与真实标签 y_test 之间的准确率,并将准确率值保存在 accuracy 变量中。再使用 print() 函数打印输出准确率。

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("准确率:", accuracy)

输出:

准确率: 0.9861111111111112

完整代码

直接下载:https://download.csdn.net/download/SHUTIAN2010/88056675

import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# 加载手写数字数据集
digits = load_digits()
X = digits.data
y = digits.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 构建KNN分类器
knn = KNeighborsClassifier(n_neighbors=5)

# 训练模型
knn.fit(X_train, y_train)

# 预测测试集结果
y_pred = knn.predict(X_test)

#计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("准确率:", accuracy)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是DPC-KNN-PCA算法Python完整代码,包括数据预处理、DPC-KNN-PCA算法实现和结果可视化: ```python import numpy as np import pandas as pd import matplotlib.pyplot as plt # 数据预处理 data = pd.read_csv('data.csv') X = data.values[:, :-1] y = data.values[:, -1] # DPC-KNN-PCA算法实现 def DPC_KNN_PCA(X, k, alpha, beta, gamma): n, m = X.shape D = np.zeros((n, n)) for i in range(n): for j in range(n): D[i, j] = np.linalg.norm(X[i] - X[j]) D_sort = np.sort(D, axis=1) idx_sort = np.argsort(D, axis=1) K = np.zeros((n, k)) for i in range(n): for j in range(k): K[i, j] = idx_sort[i, j+1] W = np.zeros((n, n)) for i in range(n): for j in range(k): W[int(K[i, j]), i] = 1 W = np.maximum(W, W.T) D_bar = np.diag(np.sum(W, axis=1)) L = D_bar - W M = np.dot(X.T, L).dot(X) [U, S, V] = np.linalg.svd(M) U_pca = U[:, :2] Z = np.dot(X, U_pca) L_pca = np.dot(U_pca.T, M).dot(U_pca) D_pca = np.diag(np.sum(L_pca, axis=1)) L_norm = np.linalg.inv(np.sqrt(D_pca)).dot(L_pca).dot(np.linalg.inv(np.sqrt(D_pca))) W_norm = np.exp(-alpha*L_norm) - np.eye(n) D_norm = np.diag(np.sum(W_norm, axis=1)) L1_norm = D_norm - W_norm L2_norm = np.linalg.inv(np.sqrt(D_norm)).dot(L_norm).dot(np.linalg.inv(np.sqrt(D_norm))) W_dpc = np.exp(-beta*L1_norm - gamma*L2_norm) - np.eye(n) D_dpc = np.diag(np.sum(W_dpc, axis=1)) L_dpc = D_dpc - W_dpc return Z, L_dpc # 运行DPC-KNN-PCA算法并可视化结果 Z, L_dpc = DPC_KNN_PCA(X, 10, 0.5, 0.1, 0.1) plt.scatter(Z[:, 0], Z[:, 1], c=y) plt.show() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值