KNN分类算法原理与Python+sklearn实现根据身高和体重对体型分类

KNN算法是k-Nearest Neighbor Classification的简称,也就是k近邻分类算法。基本思路是在特征空间中查找k个最相似或者距离最近的样本,然后根据k个最相似的样本对未知样本进行分类。基本步骤为:

(1)计算已知样本空间中所有点与未知样本的距离;

(2)对所有距离按升序排列;

(3)确定并选取与未知样本距离最小的k个样本或点;

(4)统计选取的k个点所属类别的出现频率;

(5)把出现频率最高的类别作为预测结果,即未知样本所属类别。

下面的代码模拟了上面的算法思路和步骤,以身高+体重对肥胖程度进行分类为例,采用欧几里得距离。

from collections import Counter
import numpy as np

# 已知样本数据
# 每行数据分别为性别,身高,体重
knownData = ((1, 180, 85),
             (1, 180, 86),
             (1, 180, 90),
             (1, 180, 100),
 
             (1, 185, 120),
             (1, 175, 80),
             (1, 175, 60),
             (1, 170, 60),

             (1, 175, 90),
             (1, 175, 100),
             (1, 185, 90),
             (1, 185, 80))

knownTarget = ('稍胖', '稍胖', '稍胖', '过胖',
               '太胖', '正常', '偏瘦', '正常',
               '过胖', '太胖', '正常', '偏瘦')

def KNNPredict(current, knownData=knownData, knownTarget=knownTarget, k=3):
    # current为未知样本,格式为(性别,身高,体重)
    data = dict(zip(knownData, knownTarget))
    # 如果未知样本与某个已知样本精确匹配,直接返回结果
    if current in data.keys():
        return data[current]
   
    # 按性别过滤,只考虑current性别一样的样本数据
    g = lambda item:item[0][0]==current[0]
    samples = list(filter(g, data.items()))
    g = lambda item:((item[0][1]-current[1])**2+\
                     (item[0][2]-current[2])**2)**0.5
    distances = sorted(samples, key=g)
    # 选取距离最小的前k个
    distances = (item[1] for item in distances[:k])
    # 计算选取的k个样本所属类别的出现频率
    # 选择频率最高的类别作为结果
    return Counter(distances).most_common(1)[0][0]

unKnownData = [(1, 180, 70), (1, 160, 90), (1, 170, 85)]
for current in unKnownData:
    print(current, ':', KNNPredict(current))

运行结果为:

(1, 180, 70) : 偏瘦
(1, 160, 90) : 过胖
(1, 170, 85) : 正常

下面的代码使用扩展库sklearn中的k近邻分类算法处理了同样的问题:

# 使用sklearn库的k近邻分类模型
from sklearn.neighbors import KNeighborsClassifier

# 创建并训练模型
clf = KNeighborsClassifier(n_neighbors=3, weights='distance')
clf.fit(knownData, knownTarget)

# 分类
for current in unKnownData:
    print(current, end=' : ')
    current = np.array(current).reshape(1,-1)
    print(clf.predict(current)[0])

运行结果为:

(1, 180, 70) : 偏瘦
(1, 160, 90) : 过胖
(1, 170, 85) : 正常

---------相关阅读-----------

Python+sklearn使用线性回归算法预测儿童身高

使用线性回归拟合平面最佳直线及预测之Python+sklearn实现

----------喜大普奔----------

1、继《Python程序设计基础》(2017年9月第5次印刷)、《Python程序设计(第2版)》(2017年9月第4次印刷)、《Python可以这样学》(2017年7月第3次印刷)系列图书之后,董付国老师新书《Python程序设计开发宝典》已于2017年8月1日在清华大学出版社出版,并于2017年9月进行了第2次印刷。为庆祝新书《Python程序设计开发宝典》全面上架,清华大学出版社联合“赣江图书专营”淘宝店推出特价优惠活动,《Python程序设计开发宝典》原价69元,新书上架期间超低价39.8元,可以复制下面的链接使用浏览器打开查看图书详情和购买:

https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14464369246.84.46f16db0roWfX4&id=557107249812&rn=339cbc9df2bac424664103917dedfbd2&abbucket=8&tbpm=3

2、10月13日——15日,重庆,全国高校程序设计系列课程高级研究班,详见: 全国高校程序设计系列课程高级研修班(Python)通知
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dongfuguo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值