K-近邻算法---学习笔记整理

K-近邻算法

1、掌握K-近邻算法实现过程

2、知道K-近邻算法的距离公式

3、知道K-近邻算法的超参数K值以及取值问题

4、知道kd树实现搜索的过程

5、应用knn实现分析类

6、知道交叉验证实现过程

7、知道超参数搜索过程

8、应用GridSearchCV实现算法参数的调优

1、什么是K-近邻算法(k-NearestNeighbor):

如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

1.1、欧式距离

在这里插入图片描述

1.2、电影类型分析案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6uJTYWZP-1647484874999)(C:\Users\ldw\AppData\Roaming\Typora\typora-user-images\image-20210930112746930.png)]

算出唐人街探案和其它每个电影的距离,可以看出和喜剧片距离最近,判断唐人街探案是喜剧片

1.3、KNN算法流程总结

1)计算已知类别数据集中的点与当前点之间的距离

2)按距离递增次序排序

3)选取与当前点距离最小的K个点

4)统计前K个点所在的类别出现的频率

5)返回前K个点出现频率最高的类别作为当前点的预测分类

2、K近邻算法api初步使用

2.1、机器学习流程复习

获取数据集 – 数据基本处理 – 特征工程 – 机器学习 — 模型评估

2.2、K-近邻算法API

在这里插入图片描述

3、距离度量

3.1、距离公式的基本性质

在这里插入图片描述

3.2、常见距离公式

1、欧式距离

2、曼哈顿距离

在这里插入图片描述

3、切比雪夫距离

在这里插入图片描述

4、闵可夫斯基距离

在这里插入图片描述

4、距离计算

1、连续属性

若属性值之间存在有序关系,则可将其转化为连续值。如身高 高、中等、矮 可转化为[1,0.5,0]

2、离散属性

若属性值之间不存在有序关系,则通常将其转化为向量的形式,如性别男女,转化为{(1,0),(0,1)}

5、K值的选择

k值过小,容易收到异常点的影响,容易过拟合

K值过大,收到样本均衡的问题,容易欠拟合

6、 kd树

6.1、什么是kd树

为了避免每次都重新计算一遍距离,算法会把距离信息保存在一颗树里,这样在计算之前从梳理查询距离信息,尽量避免重复计算。其基本原理是,如果A和B距离很远,B和C距离很近,那么A和C距离也很远。

6.2、kd树原理

1、树的建立

2、最近邻域搜索

kd树是一种对K维空间中的实例点进行存储一遍对其进行快速检索的树形数据结构。kd树是一种二叉树,表示对k维空间的一个划分

6.3、构造方法

1、构造根节点

2、通过递归的方法,不断对k维空间进行划分,生成子节点

3、上述过程知道子区域内没有实例时终止(终止时的结点为叶节点),在此过程中,将实例保存在相应的结点上。

4、通常,循环的选择坐标轴对空间划分,选择训练实例点在坐标轴上的中位数为切分点,这样得到的kd树是平衡的。

6.4、问题

选择向量的哪一维进行划分:数据比较分散的那一堆进行划分(分散程度用方差衡量)

如何划分数据:中位数划分

7、特征预处理

通过一些转换函数将特征数据转换诚更加适合算法模型的特征数据过程

1、为什么要进行归一化/标准化

特征的单位或者大小相差较大,或者某特征的方差相比其它的特征要大出几个数量级,容易影响(支配)目标结果,是的一些算法无法学习到其它的特征

2、归一化

定义:通过对原始数据进行变换把数据映射到(默认[0,1])之间

公式:x1 = (x-min)/(max-min) x2=x1*(mx-mi)+mi

作用与每一列,max为一列的最大值,min为一列的最小值,那么x2为最终结果,mx,mi分别为指定区间值默认mx为1,mi为0

在这里插入图片描述

API接口

sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)…)

MinMaxScaler.fit_transform(X)

返回值:转化后的形状相同的array

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

def minmax_demo():
    data = pd.read_csv()
    print(data)

    #1、实例化
    transfer = MinMaxScaler(feature_range=(3,5))

    #进行转换
    ret_data = transfer.fit_transform(data("","",""))
    print("归一化之后的数据为:\n",ret_data)

minmax_demo()

最大值最小值非常容易收到异常点的影响,所以这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景

3、标准化

通过对原始数据进行变换,把数据变换到均值为0,标准差为1的范围内

公式
x = ( x − m e a n ) / σ x=(x-mean)/σ x=xmean/σ
作用于每一列,mean为平均值,σ为标准差

API接口

sklearn.preprocessing.StandardScaler(feature_range=(0,1)…)

StandardScaler.fit_transform(X)

返回值:转化后的形状相同的array

import pandas as pd
from sklearn.preprocessing import MinMaxScaler,StandardScaler

def Stand_demo():
    data = pd.read_csv()
    print(data)

    #1、实例化
    transfer = StandardScaler()

    #进行转换
    ret_data = transfer.fit_transform(data("","",""))
    print("标准化之后的数据为:\n",ret_data)

Stand_demo()

在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。

9、案例分析----鸢尾花

from sklearn.datasets import load_iris
import seaborn as sns
import  matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection  import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

#1、数据获取
iris =load_iris()
print(iris)
#python图表中文不显示
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False


#2、数据可视化
iris_d = pd.DataFrame(iris['data'],columns=['Sepal_Length','Sepal_Width','Petal_Length','Pepal_Width'])
iris_d['Species'] = iris.target

def plot_iris(iris,col1,col2):
    sns.lmplot(x=col1, y=col2, data=iris, hue="Species", fit_reg=False) #hue是目标值
    plt.xlabel(col1)
    plt.ylabel(col2)
    plt.title('鸢尾花种类分布图')
    plt.show()
plot_iris(iris_d,'Pepal_Width','Sepal_Length')

#3、数据集划分
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size =0.2,random_state=22)
y_test.shape
y_train.shape

#4、特征值预处理
transfer =StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test= transfer.transform(x_test)

#机器学习KNN
estimator=KNeighborsClassifier(n_neighbors=5)
estimator.fit(x_train,y_train)

#模型评估
y_pre=estimator.predict(x_test)
print("预测值是:\n",y_pre)
print("预测值和真实值的对比是:\n",y_pre==y_test)

#准确率计算
score=estimator.score(x_test,y_test)
print("准确率是:\n",score)

9.1、结论

在这里插入图片描述
在这里插入图片描述
预测值是:
[0 2 1 2 1 1 1 1 1 0 2 1 2 2 0 2 1 1 1 1 0 2 0 1 2 0 2 2 2 2]
预测值和真实值的对比是:
[ True True True True True True True False True True True True
True True True True True True False True True True True True
True True True True True True]
准确率是:
0.9333333333333333

10、KNN算法优缺点

优点:

简单有效、 重新训练的代价低、适合类域交叉样本、适合大样本自动分类

缺点

惰性学习(基本上是重新学习)、类别评分不是规格化

输出可解释性不强、对不均衡的样本不擅长、计算量较大

11、交叉验证:网格搜索

1、定义

交叉验证:将拿到的训练数据,分为训练集和验证集。如下图,嫁给你数据分成4分,其中一份作为验证集,然后经过4次(组)的测试,每次都更换不同的验证集,即将得到4组模型的结果,取平均值作为最终结果,又称4折交叉验证

在这里插入图片描述

交叉验证的目的:为了让评估的模型更加准确可信

注意:交叉验证不能提高模型的准确率

2、什么是网格搜索

超参数:sklearn中,需要手动指定的参数,叫做超参数

网格搜索就是把这些超参数的值,通过字典的形式传递出去,然后进行选择最优值。
在这里插入图片描述

3、交叉验证,网格搜索API

sklearn.model_selection.GridSearchCV(estimator,para_grid=None,cv=None) 对估计器的指定参数进行详尽搜索

estimate:估计器对象 para_grid 估计器参数 cv:指定几折交叉验证 fit:输入训练数据 score:准确率

结果分析:bestscore_:在交叉验证中验证的最好结果

bestestimator:最好的参数模型

cvresults:每次交叉验证后的验证机准确率和训练集准确率结果

from sklearn.datasets import load_iris
import seaborn as sns
import  matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection  import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

#1、数据获取
iris =load_iris()
print(iris)
#python图表中文不显示
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False


#2、数据可视化
iris_d = pd.DataFrame(iris['data'],columns=['Sepal_Length','Sepal_Width','Petal_Length','Pepal_Width'])
iris_d['Species'] = iris.target

def plot_iris(iris,col1,col2):
    sns.lmplot(x=col1, y=col2, data=iris, hue="Species", fit_reg=False) #hue是目标值
    plt.xlabel(col1)
    plt.ylabel(col2)
    plt.title('鸢尾花种类分布图')
    plt.show()
plot_iris(iris_d,'Pepal_Width','Sepal_Length')

#3、数据集划分
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size =0.2,random_state=22)
y_test.shape
y_train.shape

#4、特征值预处理
transfer =StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test= transfer.transform(x_test)

#机器学习KNN
estimator=KNeighborsClassifier()

#模型调优--交叉验证,网格搜索
param_grid ={"n_neighbors":[1,3,5,7]}
estimator = GridSearchCV(estimator,param_grid=param_grid,cv=5)

#模型训练
estimator.fit(x_train,y_train)

#模型评估
y_pre=estimator.predict(x_test)
print("预测值是:\n",y_pre)
print("预测值和真实值的对比是:\n",y_pre==y_test)

#准确率计算
score=estimator.score(x_test,y_test)
print("准确率是:\n",score)

#查看交叉验证,网格搜索的一些属性
print("最好的结果:\n",estimator.best_score_)
print("最好的参数模型:\n",estimator.best_estimator_)
print("每次交叉验证后的准确率结果:\n",estimator.cv_results_)

在这里插入图片描述

结论
预测值是:
[0 2 1 2 1 1 1 1 1 0 2 1 2 2 0 2 1 1 1 1 0 2 0 1 2 0 2 2 2 2]
预测值和真实值的对比是:
[ True True True True True True True False True True True True
True True True True True True False True True True True True
True True True True True True]
准确率是:
0.9333333333333333
最好的结果:
0.9583333333333333
最好的参数模型:
KNeighborsClassifier()
每次交叉验证后的准确率结果:
{‘mean_fit_time’: array([0. , 0.00312543, 0. , 0.00312495]), ‘std_fit_time’: array([0. , 0.00625086, 0. , 0.0062499 ]), ‘mean_score_time’: array([0., 0., 0., 0.]), ‘std_score_time’: array([0., 0., 0., 0.]), ‘param_n_neighbors’: masked_array(data=[1, 3, 5, 7],
mask=[False, False, False, False],
fill_value=’?’,
dtype=object), ‘params’: [{‘n_neighbors’: 1}, {‘n_neighbors’: 3}, {‘n_neighbors’: 5}, {‘n_neighbors’: 7}], ‘split0_test_score’: array([0.95833333, 0.95833333, 1. , 1. ]), ‘split1_test_score’: array([0.95833333, 0.91666667, 0.91666667, 0.91666667]), ‘split2_test_score’: array([0.95833333, 0.95833333, 1. , 1. ]), ‘split3_test_score’: array([0.875 , 0.875 , 0.91666667, 0.91666667]), ‘split4_test_score’: array([0.95833333, 0.95833333, 0.95833333, 0.95833333]), ‘mean_test_score’: array([0.94166667, 0.93333333, 0.95833333, 0.95833333]), ‘std_test_score’: array([0.03333333, 0.03333333, 0.0372678 , 0.0372678 ]), ‘rank_test_score’: array([3, 4, 1, 1])}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值