机器学习入门(二),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}')
相关推荐
wyw00005 分钟前
目标检测之YOLO
人工智能·yolo·目标检测
发哥来了5 分钟前
AI视频生成企业级方案选型指南:2025年核心能力与成本维度深度对比
大数据·人工智能
_codemonster10 分钟前
强化学习入门到实战系列(四)马尔科夫决策过程
人工智能
北邮刘老师15 分钟前
智能体治理:人工智能时代信息化系统的全新挑战与课题
大数据·人工智能·算法·机器学习·智能体互联网
laplace012324 分钟前
第七章 构建自己的agent智能体框架
网络·人工智能·microsoft·agent
诗词在线28 分钟前
中国古代诗词名句按主题分类有哪些?(爱国 / 思乡 / 送别)
人工智能·python·分类·数据挖掘
高锰酸钾_38 分钟前
机器学习-L1正则化和L2正则化解决过拟合问题
人工智能·python·机器学习
${王小剑}41 分钟前
深度学习损失函数
人工智能·深度学习
啊巴矲43 分钟前
小白从零开始勇闯人工智能:机器学习初级篇(PCA数据降维)
人工智能·机器学习
geneculture1 小时前
融智学形式本体论:一种基于子全域与超子域的统一认知架构
大数据·人工智能·哲学与科学统一性·信息融智学·融智时代(杂志)