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

文章目录

  • 一、KNN算法
    • 1.1 算法概述
    • 1.2 KNN 算法的应用领域
  • 二、理论基础
    • 2.1 KNN算法原理
    • 2.2 距离度量方法
      • 2.2.1 欧式距离(Euclidean Distance)
      • 2.2.2 曼哈顿距离(Manhattan Distance)
      • 2.2.3 余弦相似度(Cosine Similarity)
    • 2.3 K值的选择
  • 三、数据准备
    • 2.1 数据预处理
    • 2.2 特征选择和特征缩放
  • 四、实现KNN算法
    • 4.1 导入必要的库和数据集
    • 4.2 数据集的划分
    • 4.3 计算距离
    • 4.4 找出最近的 K 个近邻
    • 4.5 进行分类或回归预测
    • 4.6 模型评估
  • 五、参数调优
    • 5.1 K值的选择
    • 5.2 距离度量方法的选择
    • 5.3 代码
  • 六、KNN算法的扩展
    • 6.1 加权KNN
    • 6.2 KNN回归
    • 6.3 KD树
  • 七、实例应用
    • 7.1 电影推荐系统
      • 开发步骤
      • 完整代码
    • 7.2 手写数字识别
      • 开发步骤
      • 完整代码


一、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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/42275.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python和django中安装mysqlclient失败的解决方案

在Pychram中和pip中安装mysqlclient都不成功&#xff0c;只能直接下载二进制包进行安装了&#xff0c;下载页面中根据python的版本选择对应WHL包下载&#xff0c;下载地址 mysqlclient PyPIhttps://pypi.org/project/mysqlclient/#files 通过pip命令进行安装 pip install d:\…

传输网络介绍

文章目录 1、通信传输介质有哪些&#xff1f;2、通信网络常见的组网形式有哪些&#xff1f;3、光纤通信常用的复用技术是哪两种&#xff1f;4、SDH的复用技术是什么&#xff1f;5、灰光和彩光的区别在哪里&#xff1f;6、波长的计算公式&#xff1f;7、5G时代&#xff0c;承载网…

esp32-cam红外实时监控报警系统(巴发云和邮箱同时推送)

esp32-cam红外实时监控报警系统 设想-巴发云转折-照片数量限制代码避开巴发云照片限制邮箱的坑同时我的巴发云微信也受到了提醒报警&#xff0c;虽然没有图片显示。 设想-巴发云 我想做一个人体红外传感器发现人体报警&#xff0c;同时给我手机发报警提醒&#xff0c;同时发送…

​​Layui之用户管理实例(对数据的增删改查)

目录 ​编辑一、R工具介绍&#xff08;&#xff09; ​编辑二、数据表的增删改查 ​编辑2.1我们先得从查询数据库的语句入手 2.2优化dao类 2.4UserAction类 2.5前台的页面实现增删改查操作 2.6 userManage页面JS 2.7user新增、修改iframe层js 前言 上一篇我分享了…

【图像处理OpenCV(C++版)】——5.6 图像平滑之联合双边滤波

前言&#xff1a; &#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; &#x1f31f;&#x1f31f;&#x1f31f; 本专栏主要结合OpenCV和C来实现一些基本的图像处理算法并详细解释各参数含义&#xff0c;适用于平时学习、工作快…

Orleans 微软基于 Actor 的分布式框架

一、Actor模型工作原理 Actor模型是一种并发编程模型&#xff0c;它基于消息传递实现&#xff0c;是一种轻量级的并发模型。在Actor模型中&#xff0c;每个Actor都是一个独立的执行单元&#xff0c;它可以接收和发送消息&#xff0c;并且可以执行一些本地操作&#xff0c;但是不…

Internet Download Manager IDM 破解版 中文便携版 v6.41.15

Internet Download Manager 介绍 Internet Download Manager&#xff0c;全球最佳下载利器。Internet Download Manager (简称IDM) 是一款Windows 平台功能强大的多线程下载工具&#xff0c;国外非常受欢迎。支持断点续传&#xff0c;支持嗅探视频音频&#xff0c;接管所有浏览…

【Python爬虫开发基础⑭】Scrapy架构(组件介绍、架构组成和工作原理)

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;python网络爬虫从基础到实战 欢迎订阅&#xff01;后面的内容会越来越有意思~ &#x1f4a1;往期推荐&#xff1a; ⭐️前面比较重要的基础内容&#xff1a; 【Python爬…

【ArcGIS Pro微课1000例】0028:绘制酒店分布热力图(POI数据)

本文讲解在ArcGIS Pro中文版中,基于长沙市酒店宾馆分布矢量点数据(POI数据)绘制酒店分布热力图。 文章目录 一、加载酒店分布数据二、绘制热度图参考阅读: 【GeoDa实用技巧100例】004:绘制长沙市宾馆热度图 【ArcGIS微课1000例】0070:制作宾馆酒店分布热度热力图 一、加载…

从0到1构建证券行业组织级项目管理体系的探索与实践︱东吴证券PMO负责人娄鹏呈

东吴证券股份有限公司信息技术总部PMO负责人娄鹏呈先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;从0到1构建证券行业组织级项目管理体系的探索与实践。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&a…

联通 Flink 实时计算平台化运维实践

摘要&#xff1a;本文整理自联通数科实时计算团队负责人、Apache StreamPark Committer 穆纯进在 Flink Forward Asia 2022 平台建设专场的分享&#xff0c;本篇内容主要分为四个部分&#xff1a; 实时计算平台背景介绍 Flink 实时作业运维挑战 基于 StreamPark 一体化管理 …

力扣题目解析:生成奇数个字符的字符串的巧妙方法

本篇博客会讲解力扣“1374. 生成每种字符都是奇数个的字符串”的解题思路&#xff0c;这是题目链接。 这道题的解题思路很巧妙&#xff0c;它利用了字符串长度n的奇偶性&#xff1a; 如果n是奇数&#xff0c;那么就把字符串全部填充为’a’&#xff0c;这样每种字符都是奇数个…

基于linux下的高并发服务器开发(第一章)- 目录遍历函数

10 / 目录遍历函数 // 打开一个目录 #include <sys/types.h> #include <dirent.h>DIR *opendir(const char *name); 参数&#xff1a; - name: 需要打开的目录的名称 返回值&#xff1a; DIR * 类型&#xff0c;理解为目录流 错误…

网络安全/黑客技术—学习笔记

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

韦东山Linux驱动入门实验班(4)LED驱动

前言 &#xff08;1&#xff09;我们学习完hello驱动之后&#xff0c;对驱动程序开发有了一点点认识了之后。现在可以开始对硬件进行实际操作了&#xff0c;本人使用的是i.max6ull开发板&#xff0c;STM32MP157和全志的D1H也会进行讲解。 &#xff08;2&#xff09;如果还有对于…

Simulink仿真模块 - Data Store Read

Data Store Read:从数据存储中读取数据 在仿真库中的位置为:Simulink / Signal Routing 模型为: 说明 Data Store Read 模块将指定数据存储中的数据复制到其输出中。多个 Data Store Read 模块可从同一个数据存储读取数据。 用来读取数据的源数据存储由 Data Store Memory 模…

低代码技术:提高效率降低成本的全新选择

一、前言 企业想要独立的应用程序&#xff0c;开发者在寻求更快速、更高效、更灵活的开发方法&#xff0c;以适应快速变化的市场需求。在这个背景下&#xff0c;低代码技术以提高效率降低成本的方式走进人们视野&#xff0c;成为了一种全新的应用程序开发方式。 二、相比传统的…

手写IOC

IOC原理(手写IOC) Spring框架的IOC是基于反射机制实现的。 反射回顾 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff0c;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息…

在Linux下做性能分析1:基本模型

介绍 本Blog开始介绍一下在Linux分析性能瓶颈的基本方法。主要围绕一个基本的分析模型&#xff0c;介绍perf和ftrace的使用技巧&#xff0c;然后东一扒子&#xff0c;西一扒子&#xff0c;逮到什么说什么&#xff0c;也不一定会严谨。主要是把这个领域的一些思路和技巧串起来。…

解码 LangChain|用 LangChain 和 Milvus 从零搭建 LLM 应用

如何从零搭建一个 LLM 应用&#xff1f;不妨试试 LangChain Milvus 的组合拳。 作为开发 LLM 应用的框架&#xff0c;LangChain 内部不仅包含诸多模块&#xff0c;而且支持外部集成&#xff1b;Milvus 同样可以支持诸多 LLM 集成&#xff0c;二者结合除了可以轻松搭建一个 LLM…