【数据分析】numpy基础第五天
前言
第五天是我们的numpy学习计划中的最后一天。
在数据处理和数据分析中,数据预处理是非常重要的一步。我们不可能完全靠肉眼来分析数据,总会有用到各种算法模型的时候,例如使用聚类、回归分析。
如果原来的数据非常“肮脏”,不规整,我们将会得到一个不可靠的糟糕结果,此时我们需要用两种十分常用的数据预处理手段来清洗我们的数据。
今天仅仅包括如下两个内容:
- Z-Score标准化
- Min-Max归一化
Z-Score标准化
Z-Score标准化
是一种常见的数据标准化方法,它通过对原始数据进行均值和标准差的线性变换,将数据变换为均值为0、标准差为1的分布。
Z-Score标准化后的数据,通常在机器学习模型上表现更好,并且,我们可以根据Z-Score标准化后的数据来去除异常值。
具体的标准化公式如下:
X standardized = X − X ˉ σ X_{\text{standardized}} = \frac{{X - \bar{X}}}{{\sigma}} Xstandardized=σX−Xˉ
其中, X s t a n d a r d i z e d X_{standardized} Xstandardized表示标准化后的数据, X X X表示原始数据, X m e a n X_{mean} Xmean表示原始数据的均值, X s t d X_{std} Xstd表示原始数据的标准差。
关于Z分数(Z-Score):
其实Z-Score标准化
,就是数据计算成对应的Z分数
,我们可以利用Z分数进行异常值处理
,如果Z分数大于某一个阈值(通常 ± 2),则认为它是异常值,进行丢弃。
使用Z分数处理异常值需要满足正态分布的假设。Z分数越大
,就代表它越接近正态分布的右侧
,Z分数越小
,就代表它越接近正态分布的左侧
,对于那些及其右侧或者及其左侧的数据,因为很可能是错误的数据
,所以视为异常值。
Z
=
X
−
X
ˉ
σ
Z = \frac{{X - \bar{X}}}{{\sigma}}
Z=σX−Xˉ
下面是使用Numpy实现Z-Score标准化的代码示例:
import numpy as np
def z_score(X):
X_mean = np.mean(X)
X_std = np.std(X)
X_standardized = (X - X_mean) / X_std
return X_standardized
Z-Score应用示例
在运行过上面的Z-Score标准化
的实现代码后,我们可以运行下面的代码。
假设我们现在有一批大学生的身高数据:
- 我们知道,正常成年人的身高一般都是在
[150, 190]
之间 - 而我们在下面的数据中添加了一个身高为
300
的异常数据
让我们来看看它的Z分数
是多少,并找出300
这个异常身高。
# 身高数据
arr = np.array([160, 170, 180, 165, 155, 163, 183, 188, 300])
# 计算arr中的元素的z分数
std_data = z_score(arr)
# np.abs()可以计算绝对值
abs_zc = np.abs(std_data)
print('原数据:')
print(arr)
print()
print('Z分数的绝对值:')
print(abs_zc)
print()
# 大于号“>”也是一个运算符,运算结果是True和False
compare = abs_zc > 2
print('比较结果:')
print(compare)
print()
# compare和arr的形状相同,区别是arr里面的是真正的数据,compare对应每个元素的比较结果
# 只有对应在compare里面为True的元素会被筛选出来
outlier = arr[compare]
print('异常值:')
print(outlier)
输出结果
从下面的输出结果中,我们可以看到,正常的身高的Z分数的绝对值都位于[0, 1]
之间,而身高为300
的那个异常数据的Z分数为2.73893945
,显然,这已经远远大于了2
这个阈值(这个阈值的设定并没有严格限定,我只能告诉你,阈值的绝对值越高,去除的数据越少,反之越多,这对应了正态分布的左右两端都只有少量数据的特点,通过设定Z分数的阈值,我们只保留正态分布中间的那些常见数据),我们应该将它视为异常值去除。
原数据:
[160 170 180 165 155 163 183 188 300]
Z分数的绝对值:
[0.59220312 0.35426437 0.11632561 0.47323375 0.7111725 0.5208215
0.04494399 0.07402539 2.73893945]
比较结果:
[False False False False False False False False True]
异常值:
[300]
Min-Max归一化
Min-Max归一化
是一种线性变换方法,将数据缩放到指定的范围内。它通过对原始数据进行线性变换,将数据映射到[0, 1]的范围内。
有时候原始数据的尺度
相差太大,不满足我们的算法模型的假设
(假设不同数据的尺度都是一致的),可能会让我们得到了错误的结果,此时我们就应该使用Min-Max归一化
,将数据归一化到[0, 1]
之间。
具体的归一化公式如下:
X normalized = X − X min X max − X min X_{\text{normalized}} = \frac{{X - X_{\text{min}}}}{{X_{\text{max}} - X_{\text{min}}}} Xnormalized=Xmax−XminX−Xmin
其中, X n o r m a l i z e d X_{normalized} Xnormalized表示归一化后的数据, X X X表示原始数据, X m i n X_{min} Xmin表示原始数据的最小值, X m a x X_{max} Xmax表示原始数据的最大值。
下面是使用Numpy实现Min-Max归一化的代码示例:
import numpy as np
def min_max(X):
X_min = np.min(X)
X_max = np.max(X)
X_normalized = (X - X_min) / (X_max - X_min)
return X_normalized
关于Min-Max其它小内容
其实不一定是归一化到[0, 1]
这个区间中,有些特殊情况会需要归一化到[-1, 1]
或者别的区间,但是大部分时候都是[0, 1]
区间。
Min-Max应用示例
在运行过上面的Min-Max归一化
的实现代码后,我们可以运行下面的代码。
假设我们现在有两批医学数据:
大尺度
的是患者平均的每日步数小尺度
的是患者的体脂百分比。
这两批数据的尺度非常巨大,如果算法模型更偏向大数值的数据,那么毫无疑问会偏向患者的平均每日步数这一边,这并不是我们想要的结果,因此我们需要进行Min-Max归一化
。
具体看下面的代码:
# 创建两列尺度差距很大的数据
col1 = np.array([55000, 45000, 35000, 25000, 15000]) # 较大数值的数据列
col2 = np.array([15, 25, 35, 45, 55]) # 较小数值的数据列
# 分别应用Min-Max规约
normalized_col1 = min_max(col1)
normalized_col2 = min_max(col2)
# 输出原始数据和归一化后的数据
print("原始数据 - 较大数值的列:")
print(col1)
# \n 代表换行符,仅仅写print()的时候,输出的就是\n这个换行符
print("\n归一化后 - 较大数值的列:")
print(normalized_col1)
print("\n原始数据 - 较小数值的列:")
print(col2)
print("\n归一化后 - 较小数值的列:")
print(normalized_col2)
总结
本文介绍了使用Numpy实现Min-Max归一化和Z-Score标准化算法的方法。归一化和标准化是数据预处理中常用的技术,能够有效地提高数据的可处理性和模型的性能。在实际应用中,根据具体的数据情况选择合适的预处理方法是非常重要的。希望本文能对读者在使用Numpy进行数据预处理时有所帮助。