KNN算法实例_电影类型判断

下面是一个完整的K近邻算法(K-Nearest Neighbors, KNN)实例,用于判断电影类型。

我们假设有一组电影数据集,每部电影都有两个特征:动作场面数量和爱情场景数量。根据这些特征,我们可以通过KNN算法来判断一部新电影的类型是动作片还是爱情片。

数据集

假设我们有以下训练数据:

电影动作场面数量爱情场景数量类型
183动作片
2110爱情片
352动作片
428爱情片
561动作片
619爱情片

新电影

我们有一部新电影,动作场面数量为4,爱情场景数量为5。我们需要预测这部新电影的类型。

KNN算法步骤

  1. 计算距离:计算新电影与训练集中所有电影之间的距离(通常使用欧氏距离)。
  2. 选择K值:选择最近的K个邻居。
  3. 投票:K个邻居中最多的类型即为新电影的预测类型。

手写实现

以下是一个使用Python实现KNN算法的完整实例:

import math
from collections import Counter

# 定义电影数据集
movies = [
    {"features": (8, 3), "label": "动作片"},
    {"features": (1, 10), "label": "爱情片"},
    {"features": (5, 2), "label": "动作片"},
    {"features": (2, 8), "label": "爱情片"},
    {"features": (6, 1), "label": "动作片"},
    {"features": (1, 9), "label": "爱情片"},
]

# 新电影的特征
new_movie = (4, 5)

# 计算欧氏距离的函数
def euclidean_distance(point1, point2):
    return math.sqrt(sum((x - y) ** 2 for x, y in zip(point1, point2)))

# KNN算法
def knn(movies, new_movie, k):
    # 计算所有电影与新电影的距离
    distances = [(movie, euclidean_distance(movie["features"], new_movie)) for movie in movies]
    
    # 按距离排序并选择前K个邻居
    k_nearest_neighbors = sorted(distances, key=lambda x: x[1])[:k]
    
    # 获取K个邻居的类型
    k_labels = [neighbor[0]["label"] for neighbor in k_nearest_neighbors]
    
    # 统计每个类型的数量,返回出现最多的类型
    most_common_label = Counter(k_labels).most_common(1)[0][0]
    return most_common_label

# 使用KNN算法预测新电影的类型
k = 3  # 选择K值
predicted_label = knn(movies, new_movie, k)
print(f"新电影的预测类型是: {predicted_label}")
运行结果

运行上述代码,将输出:

新电影的预测类型是: 动作片
解释
  1. 计算距离:我们计算新电影(4, 5)与所有训练电影的欧氏距离。
  2. 选择K值:选择距离最近的3部电影(K=3)。
  3. 投票:在这3部电影中,动作片的数量最多(假设为2部),所以预测新电影的类型为动作片。

代码解析

# 统计每个类型的数量,返回出现最多的类型
most_common_label = Counter(k_labels).most_common(1)[0][0]
1. Counter(k_labels)

Counter 是 Python 的 collections 模块中的一个类,用于计数可迭代对象中的元素。k_labels 是一个包含K个最近邻样本的标签列表,Counter(k_labels) 会生成一个字典,键为标签,值为该标签在 k_labels 中出现的次数。

例如,如果 k_labels = ['a', 'b', 'a', 'a', 'c', 'b'],则 Counter(k_labels) 结果为 Counter({'a': 3, 'b': 2, 'c': 1})

2. most_common(1)

Counter 对象的 most_common 方法返回一个列表,列表中的元素是按照出现频率从高到低排序的元组 (元素, 频率)most_common(1) 返回一个包含频率最高的一个元素及其频率的列表。

例如,Counter({'a': 3, 'b': 2, 'c': 1}).most_common(1) 返回 [('a', 3)]

3. [0]

most_common(1) 返回的是一个列表,取 [0] 表示获取该列表中的第一个元素,即频率最高的那个 (元素, 频率) 元组。

例如,[('a', 3)][0]('a', 3)

4. [0]

最后的 [0] 表示获取元组中的第一个元素,即标签本身。

例如,('a', 3)[0]'a'

在这个例子中,k_labels 包含 6 个标签。Counter(k_labels) 会生成一个计数器 Counter({'a': 3, 'b': 2, 'c': 1})。然后,most_common(1) 返回 [('a', 3)],表示标签 'a' 出现了 3 次,是最常见的标签。最后,通过 [0][0] 提取出 'a' 作为结果。

通过这个实例,我们展示了如何使用KNN算法来判断新电影的类型。这个过程可以扩展到更多的特征和更大的数据集,并且可以调整K值以获得更好的结果。

调用scikit-learn库的写法

以下是一个使用scikit-learn实现KNN算法的完整实例:

from sklearn.neighbors import KNeighborsClassifier

# 定义电影数据集的特征和标签
X = [
    [8, 3],
    [1, 10],
    [5, 2],
    [2, 8],
    [6, 1],
    [1, 9]
]
y = ["动作片", "爱情片", "动作片", "爱情片", "动作片", "爱情片"]

# 定义新电影的特征
new_movie = [[4, 5]]

# 创建KNN分类器
k = 3  # 选择K值
knn = KNeighborsClassifier(n_neighbors=k)

# 用训练数据拟合模型
knn.fit(X, y)

# 使用模型预测新电影的类型
predicted_label = knn.predict(new_movie)
print(f"新电影的预测类型是: {predicted_label[0]}")
运行结果

运行上述代码,将输出:

新电影的预测类型是: 动作片
解释
  1. 定义数据集:我们将电影的数据集分为特征X和标签y
  2. 定义新电影的特征new_movie表示新电影的特征。
  3. 创建KNN分类器:使用KNeighborsClassifier创建KNN分类器,并设定K值为3。
  4. 拟合模型:用训练数据拟合模型。
  5. 预测:使用训练好的模型预测新电影的类型。

使用scikit-learn库,我们可以更加简洁地实现KNN算法,简化了计算距离、排序和投票的过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值