首页 > 编程语言 > 详细

K近邻算法(一):基本使用

时间:2020-06-05 00:29:35      阅读:50      评论:0      收藏:0      [点我收藏+]

一:K近邻算法

二:实际例子

(1) 判断电影类型

给一组电影,对应是打斗和接吻两个特征值来判断电影类型

import pandas as pd

rowdata = {"电影名称":["无问西东","后来的我们","前任3","红海行动","唐人街探案","战狼2"],
           "打斗次数":[1,5,12,108,112,115],
           "接吻次数":[101,89,97,5,9,8],
           "电影类型":["爱情片","爱情片","爱情片","动作片","动作片","动作片"]}
# 1.将字典格式,转换为能够处理的数据表格
movie_data = pd.DataFrame(rowdata)
print(movie_data)

#

电影名称 打斗镜头 接吻镜头 电影类型
0 无问西东 1 101 爱情片
1 后来的我们 5 89 爱情片
2 前任3 12 97 爱情片
3 红海行动 108 5 动作片
4 唐人街探案 112 9 动作片
5 战狼2 115 8 动作片

 

对应的用图像去描述的话

from matplotlib import pyplot as plt
x =  [1,5,12,108,112,115]
y =  [101,89,97,5,9,8]

# 画散点图,x和y里面的对应索引元素组成(x,y)
plt.scatter(x,y,s=80)

x1 = [24]
y1 = [67]
# market:表示点的形状  s:表示点的大小
plt.scatter(x1,y1,marker="^",s=80)
plt.show()

技术分享图片

从图中可以看出,左上角的圆都代表爱情电影,右下角的圆都代表动作电影。图中的三角形,表示要分类的电影。

技术分享图片

应为是两个特征值,二维平面就计算点与点的距离,计算结果如下

target_data = {"name":"猜猜看","type":"未知","data":(24,67)}
origin_data_list = [{"name":"无问东西","type":"爱情片","data":(1,101)},
                    {"name":"后来的我们","type":"爱情片","data":(5,89)},
                    {"name":"前任3","type":"爱情片","data":(12,97)},
                    {"name":"红海行动","type":"动作片","data":(108,5)},
                    {"name":"唐人街探案","type":"动作片","data":(112,9)},
                    {"name":"战狼2","type":"动作片","data":(115,8)}]

for info in origin_data_list:
    result = cmath.sqrt((info.get("data")[0]-target_data.get("data")[0]) ** 2 + (info.get("data")[1]-target_data.get("data")[1]) ** 2)
    print(target_data.get("name")+"距离" + info.get("name")+":" +str(result))


# 结果
猜猜看距离无问东西:(41.048751503547585+0j)
猜猜看距离后来的我们:(29.068883707497267+0j)
猜猜看距离前任3:(32.31098884280702+0j)
猜猜看距离红海行动:(104.4030650891055+0j)
猜猜看距离唐人街探案:(105.39449701004318+0j)
猜猜看距离战狼2:(108.45275469069469+0j)

距离猜猜看最近电影是后来的我们,类型是爱情片,如果我们根据这种形式进行判断的话,就叫做最近邻算法(KNN:k-nearest neighbor)。

第一步:K就是判定你要选择离你最近的几个点,假如我们选择K为5,那么离猜猜看最近的距离前五位分别是(29,32,41,104,105)

第二步:最近的几个点进行投票,票数多久的一方获胜,猜猜看就属于这一方,爱情片3票,概率为60%,动作片2票,概率为40%,所以猜猜看就属于爱情片。

完整的代码

import pandas as pd
rowdata = {"电影名称":["无问西东","后来的我们","前任3","红海行动","唐人街探案","战狼2"],
           "打斗镜头":[1,5,12,108,112,115],
           "接吻镜头":[101,89,97,5,9,8],
           "电影类型":["爱情片","爱情片","爱情片","动作片","动作片","动作片"]}
# 1.将字典格式,转换为能够处理的数据表格
movie_data = pd.DataFrame(rowdata)
# 2.计算已知类别和当前点的距离
new_data = [24,67]
# 对已知类别的数据进行处理 distance = movie_data.iloc[:6,1:3] # pandas数据格式,iloc(行,列)切割方法
# 切割的结果
打斗镜头  接吻镜头
0     1   101
1     5    89
2    12    97
3   108     5
4   112     9
5   115     8
distance = ((distance - new_data)**2)
print(distance)
# 打印的结果是
打斗镜头  接吻镜头
0   529  1156
1   361   484
2   144   900
3  7056  3844
4  7744  3364
5  8281  3481
distance = distance.sum(1)
print(distance)
# 打印的结果是
0     1685
1      845
2     1044
3    10900
4    11108
5    11762
print(list(distance**0.5))
# 打印的结果是
dtype: int64
[41.048751503547585, 29.068883707497267, 32.31098884280702, 104.4030650891055, 105.39449701004318, 108.45275469069469]

# 3. 对距离进行升序排序
distance = list(disctance**0.5)
distance_1 = pd.DataFrame({"distance":distance,"lable":(movie_data.iloc[:6,3])})
print(distance_1)
# 结果
    distance lable
1   29.068884   爱情片
2   32.310989   爱情片
0   41.048752   爱情片
3  104.403065   动作片
4  105.394497   动作片
5  108.452755   动作片
sort_disctance_1 = distance_1.sort_values(by="distance")  # 默认升序
print(sort_disctance_1)
# 结果
 distance lable
1   29.068884   爱情片
2   32.310989   爱情片
0   41.048752   爱情片
3  104.403065   动作片
4  105.394497   动作片
5  108.452755   动作片
sort_disctance_1 = sort_disctance_1[:5] # 因为k选取的5,因此取前五近的的距离
print(sort_disctance_1)
# 结果
  distance lable
1   29.068884   爱情片
2   32.310989   爱情片
0   41.048752   爱情片
3  104.403065   动作片
4  105.394497   动作片
# 4.进行概率统计
result = sort_disctance_1.loc[:,"lable"]
print(result)
# 结果是
1    爱情片
2    爱情片
0    爱情片
3    动作片
4    动作片
result = result.value_counts()
print(result)
# 结果是
Name: lable, dtype: object
爱情片    3
动作片    2
result = result.index
print(result)
# 结果是
Name: lable, dtype: int64
Index([爱情片, 动作片], dtype=object)
result = result[0]
print("电影的分类为:",result)
# 结果是
电影的分类为: 爱情片

 

封装成函数

def classify(new_data,dataSet,k):
    """
    函数功能:KNN分类器
    参数说明
    :param new_data: 需要预测的分类数据集
    :param dataSet: 已知分类标签的数据集(训练集)
    :param k: K-近邻算法参数,选择距离最近的k个点
    :return: 分类结果
    """
    result = list()
    distance = list((((dataSet.iloc[:,1:3]-new_data)**2).sum(1)) ** 0.5)
    distance_sort = pd.DataFrame({"distance":distance,"lable":dataSet.iloc[:,3]})
    distance_sort = distance_sort.sort_values(by="distance")[:k]
    ret = distance_sort.loc[:,"lable"].value_counts()
    result.append(ret.index[0])
    return result

if __name__ == __main__:
    rowdata = {"电影名称": ["无问西东", "后来的我们", "前任3", "红海行动", "唐人街探案", "战狼2"],
               "打斗镜头": [1, 5, 12, 108, 112, 115],
               "接吻镜头": [101, 89, 97, 5, 9, 8],
               "电影类型": ["爱情片", "爱情片", "爱情片", "动作片", "动作片", "动作片"]}
    movie_data = pd.DataFrame(rowdata)
    new_data = [24,67]
    k = 3
    result = classify(new_data,movie_data,k)
    print(result)

# 结果
[爱情片]

 

三:K近邻算法的局限性

算法的准确性与K的取值有关系

技术分享图片

假如K取3的话,那么测试数据就属于三角形,假如k取5的话,测试数据就属于正方形。

K近邻算法的改进:https://blog.csdn.net/qq_36330643/article/details/77532161

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

# TODO

K近邻算法(一):基本使用

原文:https://www.cnblogs.com/meloncodezhang/p/13047242.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!