KNN算法原理及其实现

本文是作者在学习张伟楠,赵寒烨,俞勇所著书籍《动手学机器学习》的学习过程记录。如有侵权,联系删除。

由于作者初学机器学习,很多内容相对基础。如有错误,恳请联系订正并谅解,谢谢!

1,KNN算法原理

        分类任务的核心在于通过分析大量x_1{}的样本的标签y,进而判断所需预测的x的标签y。KNN算法则是在于通过确定需要预测的x机器临近的已分类的x_1{}的标签来判断x的标签。

         如图,内圈为K=3时,外圈为K=5时。故KNN算法的基本思路在于使样本的分类分布服从邻居的多数。

2,KNN算法的源代码及实现

        KNN算法最核心的在于距离的计算:

def distance(a,b):
    return np.sqrt(np.sum(np.square(a-b)))

        随后,我们可以定义KNN的一个class。

class KNN:
    def __init__(self,k,label_num)
        self.k=k #确定k值,knn中最重要的区分环节
        self.label_num=label_num #确定有多少的label

        拥有了class后,我们需要对class中保存训练数据,并进一步的计算距离。

    def fit(self,x_train,y_train):
        self.x_train=x_train
        self.y_train=y_train

    def get_knn_indices(self,x):   
        dis=list(map(lambda a:distance(a,x),self.x_train))
        #计算样本到目标样本的距离,并保存在一个list(即dis)中
        knn_indices=np.argsort(dis)
        #按照距离从小到大排序
        knn_indices=knn_indices[:self.k]
        #取最近k个下标
        return knn_indices

        如此,我们完成了knn算法最重要的一部分:确定距离。 接下来就在于如何具体实现了

    def get_label(self,x):
        knn_indices=self.get_knn_indices(x)
        label_statistic=np.zeros(shape=[self.label_num])
        #创建一个label_statistic数组,其大小等于self.label_num的大小。
        #此时我们开始计数在K内不同label有多少个x
        for index in knn_indices:
            label=int(self.y_train[index])
            label_statistic[label] += 1
        return np.argmax(label_statistic)

        在此,我们便完成了knn的主体工作。我们只需要根据get_label的返回预测输入x的label即可

    def predict(self,x_test):
        predicted_test_labels=np.zeros(shape=[len(x_test)],dtype=int)
        #为要预测的x预留足够空间记录其label
        for i,x in enumerate(x_test):
            predicted_test_labels[i]=self.get_label(x)
        #对每一个x预测其label
        return predicted_test_labels

        最后,直接调用KNN即可!

for k in range(1,10):
    knn=KNN(k,label_num=10)
    knn.fit(x_train,y_train)
    prediced_labels=knn.predict(x_test)
    

        综上,代码如下:

def distance(a,b):
    return np.sqrt(np.sum(np.square(a-b)))

class KNN:
    def __init__(self,k,label_num):
        self.k=k
        self.lable_num=label_num

    def fit(self,x_train,y_train):
        self.x_train=x_train
        self.y_train=y_train

    def get_knn_indices(self,x):
        dis=list(map(lambda a:distance(a,x),self.x_train))
        knn_indices=np.argsort(dis)
        knn_indices=knn_indices[:self.k]
        return knn_indices
    
    def get_label(self,x):
        knn_indices=self.get_knn_indices(x)
        label_statistic=np.zeros(shape=[self.lable_num])
        for index in knn_indices:
            label=int(self.y_train[index])
            label_statistic[label]+=1
        return np.argmax(label_statistic)

    def predict(self,x_test):
        predicted_test_labels=np.zeros(shape=[len(x_test)],dtype=int)
        for i,x in enumerate(x_test):
            predicted_test_labels[i]=self.get_label(x)
        return predicted_test_labels

for k in range(1,10):
    knn=KNN(k,label_num=10)
    knn.fit(x_train,y_train)
    predicted_labels=knn.predict(x_test)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值