机器学习入门(二),KNN近邻算法

KNN数学公式完整计算(以电影数据为例)

目标 :预测新电影 [23, 3, 17] 的类型
特征 :搞笑镜头数、拥抱镜头数、打斗镜头数
类别 :0=喜剧片、1=动作片、2=爱情片
参数:K=3(取3个最近邻居)

数据表格化

样本 搞笑镜头(x₁) 拥抱镜头(x₂) 打斗镜头(x₃) 标签(y) 类型
1 39 0 31 0 喜剧片
2 3 2 65 1 动作片
3 2 3 55 2 爱情片
4 9 38 2 2 爱情片
5 8 34 17 2 爱情片
6 5 2 57 1 动作片
7 21 17 5 0 喜剧片
8 45 2 9 0 喜剧片

待预测:Q = 23, 3, 17

数学公式体系

1. 距离公式(欧氏距离)

复制代码
d(x, y) = √[(x₁ - y₁)² + (x₂ - y₂)² + (x₃ - y₃)²]

2. K近邻集合

复制代码
Nₖ(q) = {(x⁽ⁱ⁾, y⁽ⁱ⁾) | 距离d(q, x⁽ⁱ⁾) 最小的K个样本}

3. 投票决策

复制代码
ŷ = argmax_{c∈{0,1,2}} ∑_{(x⁽ⁱ⁾,y⁽ⁱ⁾)∈Nₖ(q)} I(y⁽ⁱ⁾ = c)

其中 I(条件) 是指示函数(条件成立=1,否则=0)

逐步计算过程

第1步:计算所有距离

通用公式:d_i = √(23 - x₁_i)² + (3 - x₂_i)² + (17 - x₃_i)²

计算样本1(喜剧片):
复制代码
d₁ = √[(23-39)² + (3-0)² + (17-31)²]
   = √[(-16)² + 3² + (-14)²]
   = √[256 + 9 + 196]
   = √461 ≈ 21.47
计算样本2(动作片):
复制代码
d₂ = √[(23-3)² + (3-2)² + (17-65)²]
   = √[20² + 1² + (-48)²]
   = √[400 + 1 + 2304]
   = √2705 ≈ 52.01
计算样本3(爱情片):
复制代码
d₃ = √[(23-2)² + (3-3)² + (17-55)²]
   = √[21² + 0² + (-38)²]
   = √[441 + 0 + 1444]
   = √1885 ≈ 43.42
计算样本4(爱情片):
复制代码
d₄ = √[(23-9)² + (3-38)² + (17-2)²]
   = √[14² + (-35)² + 15²]
   = √[196 + 1225 + 225]
   = √1646 ≈ 40.57
计算样本5(爱情片):
复制代码
d₅ = √[(23-8)² + (3-34)² + (17-17)²]
   = √[15² + (-31)² + 0²]
   = √[225 + 961 + 0]
   = √1186 ≈ 34.44
计算样本6(动作片):
复制代码
d₆ = √[(23-5)² + (3-2)² + (17-57)²]
   = √[18² + 1² + (-40)²]
   = √[324 + 1 + 1600]
   = √1925 ≈ 43.87
计算样本7(喜剧片):
复制代码
d₇ = √[(23-21)² + (3-17)² + (17-5)²]
   = √[2² + (-14)² + 12²]
   = √[4 + 196 + 144]
   = √344 ≈ 18.55
计算样本8(喜剧片):
复制代码
d₈ = √[(23-45)² + (3-2)² + (17-9)²]
   = √[(-22)² + 1² + 8²]
   = √[484 + 1 + 64]
   = √549 ≈ 23.43

第2步:距离排序表

排名 样本 特征向量 标签 距离 类型
1 7 21, 17, 5 0 18.55 喜剧片
2 1 39, 0, 31 0 21.47 喜剧片
3 8 45, 2, 9 0 23.43 喜剧片
4 5 8, 34, 17 2 34.44 爱情片
5 4 9, 38, 2 2 40.57 爱情片
6 3 2, 3, 55 2 43.42 爱情片
7 6 5, 2, 57 1 43.87 动作片
8 2 3, 2, 65 1 52.01 动作片

第3步:选取K=3个最近邻

根据排序,最近的3个邻居是:

复制代码
N₃(q) = { (样本7, 标签0), (样本1, 标签0), (样本8, 标签0) }

用数学集合表示:

复制代码
N₃(q) = {(x⁽⁷⁾,0), (x⁽¹⁾,0), (x⁽⁸⁾,0)}
      = {([21,17,5],0), ([39,0,31],0), ([45,2,9],0)}

第4步:多数投票

投票公式:对于每个类别c,计算:v_c = ∑_{(x,y)∈N₃(q)} I(y = c)

计算各类别票数:
复制代码
v₀ = I(0=0) + I(0=0) + I(0=0) = 1 + 1 + 1 = 3
v₁ = I(0=1) + I(0=1) + I(0=1) = 0 + 0 + 0 = 0
v₂ = I(0=2) + I(0=2) + I(0=2) = 0 + 0 + 0 = 0

票数统计:

复制代码
类别0(喜剧片):3票
类别1(动作片):0票
类别2(爱情片):0票

第5步:决策结果

决策公式:

复制代码
ŷ = argmax_{c∈{0,1,2}} {v₀=3, v₁=0, v₂=0}

计算最大值:

复制代码
max(3, 0, 0) = 3
argmax = 对应的类别 = 0

最终预测:ŷ = 0 (喜剧片)

实现代码

例一

python 复制代码
def dm01_knn_clas():
    # 1 导入依赖包
    from sklearn.neighbors import KNeighborsClassifier

    # 2 准备数据  # 0-喜剧片 1-动作片 2-爱情片
    x = [[39, 0, 31],  # 0
         [3, 2, 65],  # 1
         [2, 3, 55],  # 2
         [9, 38, 2],  # 2
         [8, 34, 17],  # 2
         [5, 2, 57],  # 1
         [21, 17, 5],  # 0
         [45, 2, 9]]  # 0
    y = [0, 1, 2, 2, 2, 1, 0, 0]

    # 3 实例化模型
    estimator = KNeighborsClassifier(n_neighbors=3)
    print('estimator-->', estimator)

    # 4 模型训练 .fit()
    estimator.fit(x, y)

    # 5 模型预测 .predict() 搞笑镜头23 拥抱镜头3 打动镜头17
    pred = estimator.predict([[23, 3, 17]])
    print('pred-->', pred)

列二

python 复制代码
def dm02_knn_clas():
    # 1.导入依赖包
    from sklearn.neighbors import KNeighborsClassifier

    # 2.准备数据  # 0-喜剧片 1-动作片 2-爱情片
    x = [[39, 0, 31],  # 0
         [3, 2, 65],  # 1
         [2, 3, 55],  # 2
         [9, 38, 2],  # 2
         [8, 34, 17],  # 2
         [5, 2, 57],  # 1
         [21, 17, 5],  # 0
         [45, 2, 9]]  # 0
    y = [0, 1, 2, 2, 2, 1, 0, 0]

    # 分为3类
    estimator = KNeighborsClassifier(n_neighbors=3)
    print('estimator-->', estimator)

    # 4.模型训练
    estimator.fit(x, y)
    score = estimator.score(x, y)
    print('score-->', score)

    # 5 模型预测 .predict() 搞笑镜头23 拥抱镜头3 打动镜头17
    pred = estimator.predict([[23, 3, 17]])
    print('pred-->', pred)

    pred = estimator.predict([[23, 3, 17], [8, 34, 17]])
    print('pred-->', pred)

    # 6. 保存模型
    import joblib
    joblib.dump(estimator, './model/knn_model.bin')
    print('\n模型已保存为: ./model/knn_model.bin')

    # 9. 验证模型加载和预测
    loaded_model = joblib.load('./model/knn_model.bin')
    test_pred = loaded_model.predict([[23, 3, 17], [8, 34, 17]])
    print(f'加载模型后的预测验证: {test_pred}')
相关推荐
回眸&啤酒鸭4 天前
【回眸】Minicart 电商购物车核心功能落地指南
人工智能
一隅论数智4 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
AI的探索之旅4 天前
97 个 OpenCV 实例(三十):双目立体,从标定到点云
人工智能·opencv·计算机视觉
AlbertZein4 天前
Step-5-Preview 上手实测:3D 游戏、金融分析、网页设计一次跑完
人工智能·aigc
LaughingZhu4 天前
Product Hunt 每日热榜 | 2026-09-19
人工智能·深度学习·神经网络·搜索引擎·百度
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
wukangjupingbb4 天前
智能网联汽车安全能力框架
人工智能
龙亘川4 天前
明月照湾区,智启新赛道:从顶流文旅IP盛会看智慧文旅升级路径
人工智能·智慧城市·开源软件·数据可视化
飞猫的边缘AI4 天前
边缘AI应用:家用AI摄像头怎么做数据训练?
人工智能·边缘计算·ai算法·边缘ai