ML k近邻学习

k近邻学习

多摘自西瓜书

1.概述

k k k 近邻 ( k k k-Nearest Neighbor, KNN) 学习是一种常用的监督学习方法,其工作机制简单:

给定测试样本,基于某种距离度量找出训练集中与之最靠近的 k k k 个训练样本,然后基于这 k k k 个“邻居”的信息进行预测。通常,在分类任务中可以使用“投票法”,及选择这 k k k 个样本中出现最多的类别标记作为预测结果;在回归任务中可以使用“平均法”,即将这 k k k 个样本的实值输出标记的平均值作为预测结果;还可以基于距离远近进行加权平均或加权投票,距离越近的样本权重越大。

KNN学习是“懒惰学习” (lazy learning) 的著名代表,此类学习技术在训练阶段仅仅将样本保存起来,训练时间开销为零,待收到测试样本后再进行处理。与之相反,再训练阶段就对样本进行学习处理的方法成为“急切学习” (eager learning).

在这里插入图片描述

显然, k k k 是一个重要的超参数,当 k k k 取不同值时,分类结果也会有显著不同。另一方面,若采用不同的距离计算方式,则找出的“近邻”可能有显著差别,从而也会导致分类结果有显著不同。

2.距离度量


以下摘自(https://blog.csdn.net/weixin_45884316/article/details/115221211)


特征空间中两个实例点之间的距离是二者相似程度的反应,所以 k k k 近邻算法中一个重要的问题是计算样本之间的距离,以确定训练样本中哪些样本与测试样本更加接近。

2.1欧式距离

在这里插入图片描述

2.2曼哈顿距离

在这里插入图片描述

2.3其他

当已有距离度量方法不能满足需求时,可以探索符合需求的距离度量方法。

实际的数据中,往往是离散型变量和连续型变量同时存在,如何计算这种混合变量下的样本相似度是一个开放性的问题。一种简单的方法是,在进行距离计算之前对样本中的离散型变量进行One-Hot编码,然后选取上述介绍的距离计算方法进行处理。

3.KNN简单实现

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

# 手写KNN算法 (分类任务)
class KNN():
    def __init__(self, k=5):
        self.k = k

    def fit(self, xtrain, ytrain):  # 懒惰学习,保存训练数据
        self.xtrain = xtrain
        self.ytrain = ytrain

    # 构造距离计算函数
    def cal_distance(self, x):
        # x为一个样本
        # 欧氏距离
        distance = np.sqrt(np.sum(np.power((np.mat(self.xtrain) - np.mat(x)), 2), axis=1))  # 广播机制
        return distance

    # 根据 k 投票法
    def k_vote(self, distance):
        index = np.argsort(distance, axis=0)[:self.k]
        labels = self.ytrain[index]
        labels = [i[0] for i in labels]  # 将多个嵌套array转换成list便于处理
        label = pd.Series(labels).value_counts().idxmax()
        return label

    # 构造预测函数
    def predict(self, xtest):
        y_pred = []
        for i in xtest:
            distance = self.cal_distance(i)
            label = self.k_vote(distance)
            y_pred.append(label)
        return y_pred

    # 构造打分score函数
    def score(self, xtest, ytest):
        y_pred = self.predict(xtest)
        from sklearn.metrics import accuracy_score
        return accuracy_score(ytest, y_pred)


if __name__ == '__main__':
    # 读取数据集
    data = load_breast_cancer()
    # DateFrame格式显示
    X = data.data
    y = data.target
    name = ['平均半径', '平均纹理', '平均周长', '平均面积',
            '平均光滑度', '平均紧凑度', '平均凹度',
            '平均凹点', '平均对称', '平均分形维数',
            '半径误差', '纹理误差', '周长误差', '面积误差',
            '平滑度误差', '紧凑度误差', '凹度误差',
            '凹点误差', '对称误差',
            '分形维数误差', '最差半径', '最差纹理',
            '最差的边界', '最差的区域', '最差的平滑度',
            '最差的紧凑性', '最差的凹陷', '最差的凹点',
            '最差的对称性', '最差的分形维数', '患病否']
    data = np.concatenate((X, y.reshape(-1, 1)), axis=1)
    table = pd.DataFrame(data=data, columns=name)

    X = table.iloc[:, :-1]  # 特征
    y = table.iloc[:, -1]  # 标签
    Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size=0.3, random_state=420)

    clf = KNN()
    clf.fit(np.array(Xtrain), np.array(Ytrain))
    acc = clf.score(np.array(Xtest), np.array(Ytest))
    print(acc)
    
    """
    0.9181286549707602
    """

4.sklearn库实现

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np


#读取数据集
data = load_breast_cancer()
#DateFrame格式显示
X = data.data
y = data.target
name = ['平均半径','平均纹理','平均周长','平均面积',
    '平均光滑度','平均紧凑度','平均凹度',
    '平均凹点','平均对称','平均分形维数',
    '半径误差','纹理误差','周长误差','面积误差',
    '平滑度误差','紧凑度误差','凹度误差',
    '凹点误差','对称误差',
    '分形维数误差','最差半径','最差纹理',
    '最差的边界','最差的区域','最差的平滑度',
    '最差的紧凑性','最差的凹陷','最差的凹点',
    '最差的对称性','最差的分形维数','患病否']
data=np.concatenate((X,y.reshape(-1,1)),axis=1)
table=pd.DataFrame(data=data,columns=name)
X = table.iloc[:,:-1] # 特征
y = table.iloc[:,-1] # 标签

# 划分测试集和训练集(Xtrain,Xtest,Ytrain,Ytest)
Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size = 0.2,random_state=420)# random_state 随机种子 随机取样

#建模
clf = KNeighborsClassifier(n_neighbors=5)
clf = clf.fit(Xtrain,Ytrain)

score = clf.score(Xtest,Ytest)
print(score)
'''
0.9385964912280702
'''

5.绘制学习曲线确定最优超参数 k k k

import matplotlib.pyplot as plt
score = [] # 得分列表

k = range(1,20) # 设置k范围

# 遍历k分别计算得分 
for i in k:
    clf = KNeighborsClassifier(n_neighbors=i)
    clf = clf.fit(Xtrain,Ytrain)

    score.append(clf.score(Xtest,Ytest))
    
plt.plot(k,score)
_ = plt.xticks(range(1,20)) # x轴刻度
plt.show

在这里插入图片描述


仅作学习笔记使用,侵删

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值