【机器学习】K邻近算法(KNN)

算法介绍

如图是鸢尾花特征及类别数据的部分显示。有0,1,2三个类别,我们可以通过比较鸢尾花样本特征的相似程度来对鸢尾花种类进行判断。

KNN:

  1. 得到与目标样本特征的相似度最高的k个样本
  2. 在这k个样本中,统计各个类别的多少,目标样本类别=多数样本类别

在这里插入图片描述

算法实现

划分训练集和测试集

from sklearn.model_selection import train_test_split
def split_df(df,test_size,random_state):
    y = df['target']
    x = df.drop(['target'],axis=1)
    
    #划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x,y, test_size=test_size, random_state=random_state)
    return x_train, x_test, y_train, y_test

#导入鸢尾花数据    
import pandas as pd
df = pd.read_csv('./iris.csv')
#做数据划分
x_train, x_test, y_train, y_test = split_df(df,0.1,42)

计算相似度

这里,我们使用欧氏距离来衡量相似度:
d i s t a n c e ( a , b ) = ∑ i = 1 n ( a i − b i ) 2 distance(a,b) = \sqrt{\sum_{i=1}^{n}(a_i-b_i)^2} distance(a,b)=i=1n(aibi)2

def cal_simlarity(df,test):
    #输入:df 训练集 test 测试集
    #输出: distances 每列代表测试集里不同的样本与训练集的特征相似度
    
    distances= pd.DataFrame()
    #取训练集的行数
    p = df.shape[0]
    #对测试集每行操作
    for row in test.index:
       #求测试集的每个样本与训练集样本的相似度
        distance = np.sqrt(((df - np.tile(test.loc[row],(p,1)))**2).sum(axis=1))
        column_name = f"Distance_{row}"
        distances[column_name] = distance
   
    return distance,distances
distance,distances = cal_simlarity(x_train,x_test)

distances
测试集与原训练集的相似度矩阵在这里插入图片描述

knn分类

由上一节我们可以得到,某一个目标样本与训练样本的相似度。接下来只需对相似度排序,选出最小的前k个相似度对于的样本索引,从而得到对于的类别。接着对这些类别进行统计,找到出现次数最多的类别,我们的目标样本的类别则表示为该类别。

from collections import Counter
def knnselect(distance,k,y_train):
    #每一列做从小到大排序,记得保留索引
    sort_distance = distance.sort_values().reset_index(drop=False)
    #取前k行
    k_sort = sort_distance.head(k)
    y_sorts=[]
    #找到前k相似度对应的y标签值
    for i in range(k):
        y_sort = y_train.loc[k_sort.iloc[i,0]]
        y_sorts.append(y_sort)
    #对类别进行统计
    count = Counter(y_sorts)
    max_freq = max(count.values())
    most_common = [num for num, freq in count.items() if freq == max_freq]
    return most_common
#对每个测试集样本调用knnselect函数
result = distances.apply(lambda col: knnselect(col,5,y_train),axis=0 )

最后测试样本的类别标签为:
在这里插入图片描述

计算正确率

def cal_correct(re1,y_test):
    re1 = result.stack().reset_index(drop=True).values
    y_test = y_test.values
    num = len(y_test)
    #如果类别是一样的 记为1
    correct = sum(re1==y_test)
    return correct/num
cal_correct(re1,y_test)
# print;1.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值