机器学习入门(二),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}')
相关推荐
Leinwin1 小时前
智能体驱动业务转型:Microsoft Copilot Studio平台全面升级
人工智能·microsoft·copilot
腾飞开源1 小时前
17_Spring AI 干货笔记之谷歌生成式AI聊天
人工智能·多模态·工具调用·gemini·spring ai·google genai·思维配置
qxbs1 小时前
汽修帮手资料库终身免费使用——首家免费资料库网站,查汽车维修资料就用汽修帮手,里面几万套车型维修手册电路图保养手册培训资料针脚定义保险丝图解
人工智能·汽车
算法与编程之美1 小时前
理解pytorch中的L2正则项
人工智能·pytorch·python·深度学习·机器学习
学兔兔VIP1 小时前
多模态AI融合的电力边缘物联终端研究与应用
人工智能·物联网·电力系统·智能终端·多模态ai
阿恩.7701 小时前
金融经济学国际期刊/会议:前沿研究与创新
大数据·人工智能·笔记·计算机网络
smart19981 小时前
Infortrend普安存储GS支持GPU Direct存储,带宽最大化适合AI/HPC/科研制造
人工智能·能源·制造·智能硬件
Cathy Bryant1 小时前
概率论直觉(三):边缘化
笔记·机器学习·数学建模·概率论
R-G-B1 小时前
【P19 机器学习-分类算法及应用实践】手写数字识别(KNN)
python·机器学习·分类·手写数字识别·knn算法