机器学习之KNN(二)算法梳理总结及经典面试题实现

57 篇文章 2 订阅

KNN算法

定义

  • 有监督算法
  • 可以解决分类、回归问题

算法原理

  • 物以类聚人以群分
  • 输入一个样本点,计算所有样本到该样本点的欧式距离,取前k个进行决策

三个要素

  • 欧式距离 判断类别远近
  • k值,选择方式
    过小 受噪音影响
    多大 收到其他样本影响
    超参数计算,找最优得分方式
  • 决策方式
    分类
    投票法
    带权投票法
    回归
    求均值
    带权求均值

优点、缺点

  • 优点

    思想简单,能做分类和回归
    惰性学习,无需训练(蛮力法),KD树的话,则需要建树
    对异常点不敏感

  • 缺点
    计算量大、速度慢
    样本不平衡的时候,对稀有类别的预测准确率低(平衡采样和代价敏感学习都不好用)
    KD树,球树之类的模型建立需要大量的内存
    相比决策树模型,KNN模型可解释性不强

闵可夫斯基距离

  • 闵可夫斯基距离
    假设有两个样本点x1,x2,它们两者间的闵可夫斯基距离Lp定义为:
    在这里插入图片描述

  • 曼哈顿距离
    当p=1时,称为曼哈顿距离(Manhattan distance),即:
    在这里插入图片描述

  • 欧式距离
    当p=2时,称为欧氏距离(Euclidean distance),即:
    在这里插入图片描述

经典面试题KNN的实现

使用等权投票,然后对未知影片的类型进行预测

在这里插入图片描述

代码实现如下

#投票法做分类
# 数据代码化
T = [[3, 104, 0],
    [2, 100, 0],
    [1, 81, 0],
    [101, 10, 1],
    [99, 5, 1],
    [98, 2, 1]]
#预测分类
x = [18, 90]
#用最近k个点做预测
K = 5
#记录所有样本点到预测点距离
dis = []

# 导入求平方根函数
from math import sqrt
# 循环求出每个样本点到预测点的欧式距离并存储记录
for i in T:
    d = sqrt((x[0]-i[0])**2 + (x[1]-i[1])**2)
    #添加距离和标签
    dis.append([d, i[2]])
    
#按照距离排序
dis.sort(key=lambda x:x[0])

# box 距离最近的前k个标签点
box = [i[1] for i in dis[0:K]]
# 如果总和没有超过k值的一般,证明0多,所以预测为0,反之预测为1.
print(1 if sum(box)>K/2 else 0)

使用带权投票(权重与距离反比),然后对未知影片的类型进行预测

在这里插入图片描述

代码实现如下

# 带权分类
# 训练样本点
T = [[3, 104, -1],
    [2, 100, -1],
    [1, 81, -1],
    [101, 10, 1],
    [99, 5, 1],
    [98, 2, 1]]
# 测试样本
x = [18, 90]
# k值
K = 5
# 记录距离和标签
dis = []
# 求平方根函数
from math import sqrt
# 循环求解距离并存储记录
for i in T:
    d = sqrt((x[0]-i[0])**2 + (x[1]-i[1])**2)
    dis.append([d, i[2]])
# 降序排列
dis.sort(key=lambda x:x[0])
# 距离越小,1/i[0]*i[1]乘积越大,代表权重越高,所有和大于0为正,预测为1,反之为-1
print(-1 if sum([1/i[0]*i[1] for i in dis[:K]])<0 else 1)

使用等权均值,然后对未知影片的甜蜜指数进行预测(回归)

在这里插入图片描述

代码实现如下

# 等权回归
T = [[3, 104, 98],
    [2, 100, 93],
    [1, 81, 95],
    [101, 10, 16],
    [99, 5, 8],
    [98, 2, 7]]
# 预测值
x = [18, 90]
# k值
K = 5
# 记录距离
dis = []

from math import sqrt
for i in T:
    d = sqrt((x[0]-i[0])**2 + (x[1]-i[1])**2)
    dis.append([d, i[2]])
# 排序
dis.sort(key=lambda x:x[0])

from numpy import mean
# 对k个样本点的y值求平均值为预测样本的y值
print(mean([i[1] for i in dis[0:K]]))

使用带权均值,然后对未知影片的甜蜜指数进行预测

在这里插入图片描述

代码实现如下

# 带权回归
# 数据样本
T = [
    [3, 104, 98],
    [2, 100, 93],
    [1, 81, 95],
    [101, 10, 16],
    [99, 5, 8],
    [98, 2, 7]
]
# 预测数据
x = [18, 90]
# k值
K = 4
# 记录距离
dis = []

import math
for i in T:
    d = (x[0]-i[0])**2 + (x[1]-i[1])**2
    #pow方法   幂函数
    dis.append([pow(d,1/2), i[2]])
dis.sort(key=lambda x:x[0])

dis = [[1/i[0],i[1]] for i in dis][0:K]
a = 1 / sum([i[0] for i in dis])
print(dis)
res = sum([i[0]*i[1] for i in dis])
print(res)
  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值