KNN算法理解

序言

KNN作为最基础的机器学习算法,是很多学习算法的孩子们最先接触到的,但该算法从头到尾自己实现也是有一定难度,很多课程只是教怎么调封装好的算法库,却没有教核心的算法怎么从头实现,所以有点舍本逐末。

算法核心

1、近朱者赤,近墨者黑。根据临近的标签值通过投票法则确定样本类别。
2、每一个未知样本都要计算它到所有已知有标签样本的距离。
3、k值选择比较重要。

代码实现

import numpy as np

def createdata():
    """
    创建一个数据集
    Return:
        features表示特征:我们这里用身高、体重来表示特征
        labels表示类别:有三个类别,分别是胖子、中子、瘦子 -> 对应1 2 3
    """
                     #["身高", "体重"]
    features = np.array([[167, 160],
                        [170, 140],
                        [180, 120],
                        [190, 130],
                        [150, 148],
                        [168, 135]])
                        
    categories_map = {1:"胖子", 2:"中子", 3:"瘦子"}
    labels = np.array([1, 2, 3, 3, 1, 2])
    return {"features":features, "labels":labels, "categories_map":categories_map}


def KNNClassify(samples: list, dataset: dict, k: int):
    """
    samples表示待分类的特征输入,单一样本.
    dataset表示有标签对应的数据集.
    """
    samples = np.array(samples)
    labels = dataset["labels"]
    num_samples = labels.shape[0] #数据集中样本的数量
    features = dataset["features"]
    diff = np.tile(samples, (num_samples, 1)) - features #这个单一样本特征和数据集中样本特征的差距
    L2 = diff**2 #L2距离
    L2_ALL = L2[:, 0] + L2[:, 1] #身高的差距和体重的差距和,表示总的差距,这里当然可以加权, 如w1 = 1.2, w2 = 0.8, w1*L2[:, 0] + w2*L2[:, 1]
    distance = L2_ALL ** 0.5 #开平方根
    sort_index = np.argsort(distance) #从小到大排序,返回索引
    class_count = {}
    for i in range(k):
        #选k个邻居, 误差距离和labels是一一对应的关系,所以可以根据误差排序的index找到对应的label
        neighbor_label = labels[sort_index[i]]
        #字典的get方法表示,如果字典中有这个key就返回对应的value,如果没有这个key就返回设定的数,这里应该设0.
        class_count[neighbor_label] = class_count.get(neighbor_label, 0) + 1

    #投票法则,前k个最近距离中某个类别数量最多,就把未知样本确定为这个类别
    max_count = 0
    for k,v in class_count.items():
        if v > max_count:
            max_count = v
            res = k

    return res

if __name__ == "__main__":
    input_samples = [[164.5, 98.2],
                     [175.0, 155.5]]
    dataset = createdata()
    names = ["ll", "ac"]
    categories_map = dataset["categories_map"]
    for name, sample in zip(names, input_samples):
        res = KNNClassify(samples=sample, dataset=dataset, k=3)
        pred = categories_map[res]
        print("%s是一个%s"%(name, pred))


思考总结

1、knn是监督算法还是无监督算法?
答:有监督,因为是通过“有标签”的样本最终确定未知样本的类别。
2、knn的k值怎么选择最优?
答:交叉验证,可以用一部分有标签的样本做验证集,选择不同的k值下看KNN对这些验证集样本分类的正确率,选择最高的正确率对应的k值就是寻求最优的一种方法。
3、knn的k选小了会怎么样?大了会怎么样?
答:k值选小了容易过拟合,分类结果不具有代表性。k值选大了也会造成误差积累,偏离了近朱者赤,近墨者黑的思想。
4、knn的优点和缺点?
答:优点:不用学习,简单。缺点:计算量大,每一个未知样本都要全部的训练集样本来确定它的类别。

参考

https://www.cnblogs.com/ahu-lichang/p/7151007.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

超超爱AI

土豪请把你的零钱给我点

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

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

打赏作者

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

抵扣说明:

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

余额充值