x_{scale} = \frac {x - x_{min}} {x_{max} - x_{min}}
- 均值方差归一化(standardization): 把所有数据归一到均值为0方差为1的分布中。
适用于数据中没有明显的边界,有可能存在极端数据值的情况.
x_{scale} = \frac {x - x_{mean}} {S}
1.2 最值归一化实现
为了了解最值归一化的代码实现,我们可以创建100个随机数,然后对其进行最值归一化。
import numpy as np# 创建100个随机数x = np.random.randint(0,100,size=100)# 最值归一化(向量)# 最值归一化公式,映射到0,1之间(x - np.min(x)) / (np.max(x) - np.min(x))# 最值归一化(矩阵)# 0~100范围内的50*2的矩阵X = np.random.randint(0,100,(50,2))# 将矩阵改为浮点型X = np.array(X, dtype=float)# 最值归一化公式,对于每一个维度(列方向)进行归一化。# X[:,0]第一列,第一个特征X[:,0] = (X[:,0] - np.min(X[:,0])) / (np.max(X[:,0]) - np.min(X[:,0]))# X[:,1]第二列,第二个特征X[:,1] = (X[:,1] - np.min(X[:,1])) / (np.max(X[:,1]) - np.min(X[:,1]))# 如果有n个特征,可以写个循环:for i in range(0,2):
X[:,i] = (X[:,i]-np.min(X[:,i])) / (np.max(X[:,i] - np.min(X[:,i])))
下面我们可以简单地绘制样本,并使用np.mean()/np.std()
来计算其均值和方差
import matplotlib.pyplot as plt# 简单绘制样本,看横纵坐标plt.scatter(X[:,0],X[:,1])
plt.show()
1.3 均值方差归一化实现
同样地,为了了解均值方差归一化的代码实现,我们可以创建100个随机数,然后对其进行均值方差归一化。
X2 = np.array(np.random.randint(0,100,(50,2)),dtype=float)# 套用公式,对每一列做均值方差归一化for i in range(0,2):
X2[:,i]=(X2[:,i]-np.mean(X2[:,i])) / np.std(X2[:,i])
下面我们可以简单地绘制样本
plt.scatter(X2[:,0],X2[:,1])
plt.show()
计算其均值/方差
np.mean(X2[:,0])
np.std(X2[:,1])
1.4 Sklearn中的归一化
首先我们来看一个在实际使用归一化时的一个小陷阱。
我们在建模时要将数据集划分为训练数据集&测试数据集。
训练数据集进行归一化处理,需要计算出训练数据集的均值mean_train和方差std_train。
问题是:我们在对测试数据集进行归一化时,要计算测试数据的均值和方差么?
答案是否定的。在对测试数据集进行归一化时,仍然要使用训练数据集的均值train_mean和方差std_train。这是因为测试数据是模拟的真实环境,真实环境中可能无法得到均值和方差,对数据进行归一化。只能够使用公式(x_test - mean_train) / std_train
因此我们要保存训练数据集中得到的均值和方差。
在sklearn中专门的用来数据归一化的方法:StandardScaler。
下面我们加载鸢尾花数据集
import numpy as npfrom sklearn import datasetsfrom sklearn.model_selection import train_test_split
iris = datasets.load_iris()
X = iris.data
y = iris.target
X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.2,random_state=666)
使用数据归一化的方法:
from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()# 归一化的过程跟训练模型一样standardScaler.fit(X_train)
standardScaler.mean_
standardScaler.scale_ # 表述数据分布范围的变量,替代std_# 使用transformX_train_standard = standardScaler.transform(X_train)
X_test_standard = standardScaler.transform(X_test)
如此就能输出归一化后的数据了。
1.5 自己实现均值方差归一化
同样地,我们仿照sklearn的风格,可以自己实现一下均值方差归一化的方法。
我们在之前的工程中创建processing.py:
import numpy as npclass StandardScaler:
def init(self):
self.mean_ = None
self.scale_ = None
def fit(self, X):
“”“根据训练数据集X获得数据的均值和方差”“”
assert X.ndim == 2, “The dimension of X must be 2”
求出每个列的均值
self.mean_ = np.array([np.mean(X[:,i] for i in range(X.shape[1]))])
self.scale_ = np.array([np.std(X[:, i] for i in range(X.shape[1]))]) return self def tranform(self, X):
“”“将X根据StandardScaler进行均值方差归一化处理”“”
assert X.ndim == 2, “The dimension of X must be 2”
assert self.mean_ is not None and self.scale_ is not None, \ “must fit before transform”
assert X.shape[1] == len(self.mean_), \ “the feature number of X must be equal to mean_ and std_”
创建一个空的浮点型矩阵,大小和X相同
resX = np.empty(shape=X.shape, dtype=float) # 对于每一列(维度)都计算
for col in range(X.shape[1]):
resX[:,col] = (X[:,col] - self.mean_[col]) / self.scale_[col] return resX
0x02 kNN优缺点
KNN的主要优点有:
-
理论成熟,思想简单,既可以用来做分类也可以用来做回归
-
天然解决多分类问题,也可用于回归问题
-
和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
-
由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
KNN的主要缺点有:
- 计算量大,效率低。
即使优化算法,效率也不高。
-
高度数据相关,样本不平衡的时候,对稀有类别的预测准确率低
-
相比决策树模型,KNN模型可解释性不强
-
维数灾难:
随着维度的增加,“看似相近”的两个点之间的距离越来越大,而knn非常依赖距离
| 维数 | 点到点 | 距离 |
| — | — | — |
| 1维 | 0到1的距离 | 1 |
| 2维 | (0,0)到(1,1)的距离 | 1.414 |
| 3维 | (0,0,0)到(1,1,1)的距离 | 1.73 |
| 64维 | (0,0,…0)到(1,1,…1) | 8 |
| 10000维 | (0,0,…0)到(1,1,…1) | 100 |
大家感觉一万维貌似很多,但实际上就是100*100像素的黑白灰图片。
以上就是关于kNN算法的总结。
你是不是以为这一篇就两节内容就结束了?没想到吧!下面还有一波干货:kNN优化之KD树。
3 KD树
K近邻法的重要步骤是对所有的实例点进行快速k近邻搜索。如果采用线性扫描(linear scan),要计算输入点与每一个点的距离,时间复杂度非常高。因此在查询操作是,使用kd树。
3.1 kd树的原理
kd树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,且kd树是一种二叉树,表示对k维空间的一个划分。
k-d tree是每个节点均为k维样本点的二叉树,其上的每个样本点代表一个超平面,该超平面垂直于当前划分维度的坐标轴,并在该维度上将空间划分为两部分,一部分在其左子树,另一部分在其右子树。即若当前节点的划分维度为d,其左子树上所有点在d维的坐标值均小于当前值,右子树上所有点在d维的坐标值均大于等于当前值,本定义对其任意子节点均成立。
3.2 kd树的构建
常规的k-d tree的构建过程为:
-
循环依序取数据点的各维度来作为切分维度,
-
取数据点在该维度的中值作为切分超平面,
-
将中值左侧的数据点挂在其左子树,将中值右侧的数据点挂在其右子树,
-
递归处理其子树,直至所有数据点挂载完毕。
对于构建过程,有两个优化点:
-
选择切分维度:根据数据点在各维度上的分布情况,方差越大,分布越分散,从方差大的维度开始切分,有较好的切分效果和平衡性。
-
确定中值点:预先对原始数据点在所有维度进行一次排序,存储下来,然后在后续的中值选择中,无须每次都对其子集进行排序,提升了性能。也可以从原始数据点中随机选择固定数目的点,然后对其进行排序,每次从这些样本点中取中值,来作为分割超平面。该方式在实践中被证明可以取得很好性能及很好的平衡性。
例子:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/b4d26352ff97f8f0aeb996e595a8a274.jpeg)
最后
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/b4d26352ff97f8f0aeb996e595a8a274.jpeg)
最后
[外链图片转存中…(img-68PxaiVp-1712476671371)]
[外链图片转存中…(img-7LU88tf2-1712476671371)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!