近邻算法
1.K近邻算法简介
1.1 问题
分类或者回归问题
1.2 定义
如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
1.3 距离
欧式距离
1.4 分类流程
目标:预测未知样本所属的分类
- 计算未知样本到每一个训练样本的距离
- 将训练样本根据距离大小升序排列
- 取出距离最近的 K 个训练样本
- 进行多数表决,统计 K 个样本中哪个类别的样本个数最多
- 将未知的样本归属到出现次数最多的类别
1.5 回归案例
目标:预测未知样本所属的分类
- 计算未知样本到每一个训练样本的距离
- 将训练样本根据距离大小升序排列
- 取出距离最近的 K 个训练样本
- 把这个 K 个样本的目标值计算其平均值
- 将未知的样本预测的值了
2.API
2.1 Scikit-learn
2.1.1 安装pip3 install scikit-learn==0.19.1
2.2.2 内容
- 分类算法 K近邻算法、支持向量机…
- 回归模型 岭回归、Lasoo 回归…
- 聚类算法 K-mean
- 特征降维 特征降维、特征选择
- 模型选择 用于数据划分的工具…
- 预处理 特征缩放,归一化、标准化
2.2 API
2.2.1 函数 sklearn.neighbors.KNeighborsClassifier(n_neighbors=5)
n_neighbors:int 这个就是K值
2.2.2 使用过程
-
导入模块 from sklearn.neighbors import KNeighborsClassifier
-
创建估计器(学习器) estimator = KNeighborsClassifier(n_neighbors=1)
-
模型训练 estimator.fit(x, y) x 训练样本,不包括目标值 y 目标值
-
预测 estimator.predict([[1]]) 参数:待预测的未知样本
传入的参数可以是多个未知样本,返回结果是一个预测之后类别的列表
-
注意 K 值是小于训练样本数量
3.距离度量
3.1 度量方式
- 欧式距离
-
曼哈顿距离
-
切比雪夫距离
-
闵式距离
- p = 1,曼哈顿距离
- p = 2,欧式距离
- p = ∞, 切比雪夫距离
3.2 KNN 算法
KNN 算法使用的就是闵式距离,只不过p默认是2
3.3 闵式距离的缺点:
- 将各个分量的量纲(scale),也就是“单位”相同的看待了;
- 注意 需要额外这种不同的单位,将其转换为同一个数据范围内,保证不同的特征对距离计算产生影响尽量均衡。
- 离散属性计算
- 离散值存在 order 的关系 比如:早、中、晚,可以将其转换成连续的数字,0、0.5、1
- 离散值不存在 order 的关系 比如:好、坏,将其转换为:(1,0)、(0,1)
4.K值选择
4.1 重要性
决定模型的预测能力,泛化性能
4.2 两个概念
- 近似误差 关注训练集,一般不是我们想要的模型
- 估计误差 关注的测试集,可能就是一个比较好的模型
4.3 K值选择矛盾
-
K值过小
-
容易受到异常点的影响
-
模型变得复杂,过拟合
如果K值等于1.此时需要计算到每个训练样本的距离,排序,取哪一个最近邻的样本,才能够得出结果
-
-
K值过大
-
受到样本均衡的影响
-
模型变得简单,欠拟合
如果K值等于样本数量,此时我们还需要去计算距离吗?不需要
-
4.4 K值选择策略:
一般选择较小的值,没有办法直接给定。此时需要一些方法来寻找这个最合适的K值。交叉验证。
5.KD Tree
5.1 KD 树的作用
提高查找最近邻点的效率
5.2 KD 树的基本思想
- 将训练样本集按照某种规则划分N的区域,把待预测的样本也按照相同的规则,也落入到某个区域内。
- 接下来,在当前区域,或者相邻区域内进行搜索最近邻点。
- KD 树是一个平衡二叉树
5.3 KD树要确定的问题
- 拿到的样本点 (a1.,a2,a3)、(b1、b2、b3)
- 要确定根据那个维度去划分
- 随机选择
- 顺序选择
- 方差最大的哪个维度
- 要确定当前选中的维度的哪个值进行划分
- 中位数
- 注意:如果中位数对应的不是一个具体的样本点,可以选择前后两个值。
5.4 构建KD树
- 将训练样本集按照某种规则划分N的区域
5.5 KD 树搜索最近邻点
- 正向搜索
- 确定位置样本大概落在哪个区间
- 反向回溯
- 在当前区间、邻近区间内搜索最近邻点
6.数据集
6.1 获取数据
-
函数 sklearn.datasets
-
加载大数据集 datasets.fetch_*(data_home=None)
- 例子 sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
-
加载小数据 datasets.load_*()
- 例子 sklearn.datasets.load_iris()
6.2 了解数据集信息
- **data:**特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
- target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
- **DESCR:**数据描述
- feature_names:特征名,新闻数据,手写数字、回归数据集没有
- **target_names:**标签名
6.3 查看数据的分布
- sns.lmplot(x, y, data, hue, fit_reg)
7.数据集划分
- sklearn.model_selection.train_test_split(arrays, *options)
- train_test_split(data, target, test_size, random_state=22)
- data 数据集
- target 目标值
- test_size 测试集的比重
- random_state 如果不设置,每次随机产生。如果设置,则每次产生的是固定的数据集
- 返回值: 训练样本集, 测试样本集, 训练集标签,测试集标签
8.特征预处理
8.1 定义
通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
8.2 特征缩放
- 归一化(公式)
-
mx 缩放的最大值,mi 缩放的最小值
-
API: sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
-
标准化(公式)
-
API: sklearn.preprocessing.StandardScaler( )
fit_transform(X)
-
归一化和标准化区别
- 归一化会受到异常值的影响,标准化表现较好
- 标准化在在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
9.案例:鸢尾花种类预测
9.1 API
- sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
- brute是蛮力搜索,也就是线性扫描,当训练集很大时,计算非常耗时。
- kd_tree,构造kd树存储数据以便对其进行快速检索的树形数据结构,kd树也就是数据结构中的二叉树。以中值切分构造的树,每个结点是一个超矩形,在维数小于20时效率高。
- ball tree是为了克服kd树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每个节点是一个超球体。
9.2 步骤
1.获取数据集 from sklearn.datasets import load_iris
2.数据基本处理 from sklearn.model_selection import train_test_split
3.特征工程 from sklearn.preprocessing import StandardScaler
4.机器学习(模型训练) from sklearn.neighbors import KNeighborsClassifier
5.模型评估 score 准确率:预测正确的样本数量占总样本数量的比重
9.3 思考
- 使用不同训练集的 KNN 也是不同的模型
- K值不同,模型也不同
9.4 标准 API
-
第一种方式
-
StandardScaler().fit_transform(x_train)
先计算标准差、均值,再进行转换
-
-
第二种方式
-
s = StandardScaler()
-
s.fit(X)
只计算样本的标准和均值
-
s.transform(X)
将样本进行标准化
-
9.3 思考
- 使用不同训练集的 KNN 也是不同的模型
- K值不同,模型也不同
9.4 标准 API
-
第一种方式
-
StandardScaler().fit_transform(x_train)
先计算标准差、均值,再进行转换
-
-
第二种方式
-
s = StandardScaler()
-
s.fit(X)
只计算样本的标准和均值
-
s.transform(X)
将样本进行标准化
-