k近邻算法 python实现

k近邻算法(knn)

  • k近邻算法原理:

    存在一个样本数据集合(训练样本集),并且样本集中的每个数据都存在标签。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据的(最近邻)的分类标签,作为新数据的分类。一般只选取样本集中最相似的前k个数据。k一般是不大于20的整数。

  • 优缺点

    • 优点:精度高,对异常值不敏感,无数据输入假定。
    • 缺点:计算复杂度高,空间复杂度高。
    • 使用数据范围:数值型和标称型(数值型例如0.1具体值,标称型是指真或假)
  • 特征距离计算(距离计算方法有很多,这里先列三种)

    • 欧氏距离
      d [ X n 1 , X n 2 ] = ∑ i = 1 n ( X i 1 − X i 2 ) 2 d[X_{n}^{1}, X_{n}^{2}] = \sqrt{\sum_{i=1}^{n}(X_{i}^{1}-X_{i}^{2})^{2}} d[Xn1,Xn2]=i=1n(Xi1Xi2)2
    • 曼哈顿距离
      d [ X n 1 , X n 2 ] = ∑ i − 1 n ∣ X i 1 − X i 2 ∣ d[X_{n}^{1}, X_{n}^{2}] = \sum_{i-1}^{n}\left | X_{i}^{1}-X_{i}^{2} \right | d[Xn1,Xn2]=i1nXi1Xi2
    • 切比雪夫距离
      d [ X n 1 , X n 2 ] = m a x ( ∣ X 1 1 − X 1 2 ∣ , ∣ X 2 1 − X 2 2 ∣ , . . . . . . ∣ X n 1 − X n 2 ∣ ) d[X_{n}^{1}, X_{n}^{2}] = max(\left | X_{1}^{1}-X_{1}^{2} \right |,\left | X_{2}^{1}-X_{2}^{2} \right |,......\left | X_{n}^{1}-X_{n}^{2} \right |) d[Xn1,Xn2]=max(X11X12,X21X22,......Xn1Xn2)
  • 简单例子(电影类型)

根据欧氏距离计算公式,算出未知电影与已知电影类型之间的距离。

电影名称打斗镜头接吻镜头电影类型欧式距离
13104爱情片20.5
22100爱情片18.7
3181爱情片19.2
410110动作片115.3
5995动作片117.4
6982动作片118.9
?1890未知

根据欧式距离我们可以对电影按照距离大小进行排序,假定K=3,则最近邻的三个电影分别是电影2,电影3,电影1,这三种电影的列别都是爱情片,所以我们可以认为未知电影的类型也是爱情片。

  • k近邻算法的一般流程
    (1)收集数据:可以使用任意方法
    (2)准备数据:计算距离所需要的数值
    (3)分析数据:可以使用任何方法
    (4)训练数据:k近邻算法不需要进行训练
    (5)测试算法:计算错误率(选取不在数据集中的已知类别的数据进行测试)
    (6)使用算法。
  • python 实现knn算法 改进约会网站的配对效果
    约会数据实例(1-不喜欢的人 2-魅力一般的人 3-极具魅力的人):
每年飞行里程数每天游戏视频耗费时间百分比每周消费冰激凌公升数交往类型
409208.3269760.9539523
144887.1534691.6739042
260521.4418710.8051241
7513613.1473940.4289641
383441.6697880.1342961
7299310.1417401.0329551
  • 第一步:准备数据,从文本中读取数据
@tools.funcRunTime
def load_data(file_path):
    try:
        feature = []
        label = []
        with open(file_path) as f:
            for line in f:
                feature_temp = []
                line = [float(i) for i in line.strip().split()]
                feature_temp.append(line[0:3])
                abel.append(int(line[-1]))
                feature.extend(feature_temp)
        return np.mat(feature), label
    except Exception as msg:
       tools.printInfo(2, msg)
       sys.exit()
  • 准备数据:归一化数值(减少因为数值原因影响分类结果)
@tools.funcRunTime
def normalization_data(feature):
    try:
        # 计算特征的均值和标准差
        feature_u = feature.mean(axis=0)
        feature_sigma = np.std(feature, axis=0)
        # 计算特征矩阵的大小
        feature_size = np.shape(feature)
        feature_u = feature_u.repeat(feature_size[0], axis=0)
        feature_sigma = feature_sigma.repeat(feature_size[0], axis=0)
        # 归一化
        feature = (feature - feature_u) / feature_sigma
        return feature
    except Exception as msg:
        tools.printInfo(2, msg)
        sys.exit()
  • 实现算法
def knn(unknown_data, feature, feature_u, feature_sigma, label):
    try:
        # 未知数据归一化
        unknown_data = (unknown_data - feature_u) / feature_sigma
        feature_size = np.shape(feature)
        # 未知数据与已知数据的距离
        unknown_data = unknown_data.repeat(feature_size[0], axis=0)
        unknown_data = unknown_data - feature
        unknown_data = np.multiply(unknown_data, unknown_data)
        unknown_data = np.sum(unknown_data, axis=1)
        unknown_data = np.sqrt(unknown_data)
        # 未知数据距离排序取前五的类别
        unknown_data = [i[0] for i in unknown_data.tolist()]
        k_label = [i[0] for i in sorted(enumerate(unknown_data), key=lambda x:x[1])]
        k_label = k_label[0:5]
        k_label = [label_data[i] for i in k_label]
        return k_label
    except Exception as msg:
        tools.printInfo(2, msg)
        sys.exit()
  • 上述代码以及数据在github的地址为:https://github.com/xzccfzy/knn.git
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值