数据预处理
现实的数据往往是充满噪声的,⽽没有⾼质量的数据,就没有⾼质量的数据挖掘结果。所以,我们需
要对数据进⾏预处理,以提⾼数据的质量。
其中数据质量设计因素主要有以下 :
- 准确性
- 完整性
- 一致性
- 时效性
- 可信性
- 可解释性
预处理的主要步骤:
- 数据清理:通过填写缺失值、光滑噪声数据、识别或删除离群点。并解决不⼀致性来“清理”数据
- 数据集成:将多个数据源、数据库集成在⼀个
- 数据规约:将得到的数据进⾏简化,去除冗余数据
- 数据变换:讲数据进⾏规范化、数据离散化和数据分层,可以使得数据挖掘在多个抽象层次上进
⾏。
数据清洗
现实中的数据⼀般是不完整的、有噪声的和不⼀致的。数据清洗试图填充缺失值、光滑噪声并识别离
群点和纠正数据中的不⼀致。
缺失值
- 现实中的数据⼀般是不完整的、有噪声的和不⼀致的。
- 数据清洗试图填充缺失值、光滑噪声并识别离群点和纠正数据中的不⼀致。
举个栗子 :
import numpy as np
import pandas as pd
raw_data = {'first_name': ['Jason', np.nan, 'Tina', 'Jake', 'Amy'],
'last_name': ['Miller', np.nan, 'Ali', 'Milner', 'Cooze'],
'age': [42, np.nan, 36, 24, 73],
'sex': ['m', np.nan, 'f', 'm', 'f'],
'preTestScore': [4, np.nan, np.nan, 2, 3],
'postTestScore': [25, np.nan, np.nan, 62, 70]} # 字典类型
# 注 :np.nan是numpy模块中生成nan空值的方法。 有时候我们获取的数据存在缺失值,这个往往⽤NaN来表示。
df = pd.DataFrame(raw_data) # 将字典类型转为DateFrame数据类型
print(df)
结果如下 :
age first_name last_name postTestScore preTestScore sex
0 42.0 Jason Miller 25.0 4.0 m
1 NaN NaN NaN NaN NaN NaN
2 36.0 Tina Ali NaN NaN f
3 24.0 Jake Milner 62.0 2.0 m
4 73.0 Amy Cooze 70.0 3.0 f
附: DataFrame: 是表格型数据类型,既有⾏索引⼜有列索引,每列数据可以为不同类型数据(数值、字符串、布尔型值等)
缺失值的处理方法
-
忽略缺失值
isnull()
判断是否缺失, 缺失返回False, 不缺失返回True- 当缺失值较少的时候,我们可以丢弃缺失的元组
- ⽽缺失值较多的时候,我们需要采取别的⽅法
-
删除缺失值所在的元组
dropna(axis=0)
直接删除含有缺失值的行, 简单粗暴,- 其中
axis
参数为0
表示删除含有缺失值的行, 参数为1
表示删除含有缺失值的列
-
⼈⼯填写缺失值
- 该⽅法对少数缺失值有效,但费时,且当数据⾮常⼤时难以实现
- 比如 :
df_manual.loc[1,'age'] = 30
- 其中loc为pandas中的location定位方法,用于定位数据的位置从而修改其值
- 这里的用法是将编号为1的行和列属性名为age的那个数据修改为30
- 该做法会直接修改数据的内容
-
使⽤⼀个全局常量填充缺失值
fillna(value=999)
- 即数据中所有空值的地方都用该值填充
-
使⽤属性中⼼度填充缺失值
- 比如用均值填充缺失值
-
使⽤最可能的值填充缺失值
- 可使⽤是回归、⻉叶斯等⽅法确定最可能的值。
- 也可以使⽤插值法填充。
栗子如下 :
import numpy as np
import pandas as pd
raw_data = {'first_name': ['Jason', np.nan, 'Tina', 'Jake', 'Amy'],
'last_name': ['Miller', np.nan, 'Ali', 'Milner', 'Cooze'],
'age': [42, np.nan, 36, 24, 73],
'sex': ['m', np.nan, 'f', 'm', 'f'],
'preTestScore': [4, np.nan, np.nan, 2, 3],
'postTestScore': [25, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(raw_data)
print(df)
# 忽略缺失值
# 当缺失值较少的时候,我们可以丢弃缺失的元组,⽽缺失值较多的时候,我们需要采取别的⽅法
## 判断缺失值
df_isnull = df.isnull() # 判断是否缺失, 缺失返回False, 不缺失返回True
# print(df_isnull)
## 删除缺失值所在的元组(⾏)
df_deal = df.dropna(axis=0) # 直接删除含有缺失值的行, 简单粗暴
# print(df_deal)
# ⼈⼯填写缺失值
# 该⽅法对少数缺失值有效,但费时,且当数据⾮常⼤时难以实现
## 将序号 1 的年龄填写为30
df_manual = df.copy() # 创建副本
df_manual.loc[1,'age'] = 30 # 直接在副本上修改
# print(df_manual)
# 使⽤⼀个全局常量填充缺失值
## ⽤999填充缺失值
df_fillnan = df.fillna(value=999) # 将所有NaN空值都用999填充
# print(df_fillnan)
# 使⽤属性中⼼度填充缺失值
## 给定元组均值
df_fillmean = df.fillna(value=df.mean()) # 只能填充数字类型的空值, 其他类型的不能填充
# print(df_fillmean)
# 使⽤最可能的值填充缺失值
# 可使⽤是回归、⻉叶斯等⽅法确定最可能的值。也可以使⽤插值法填充。
## 使⽤上⼀个值替代
df_lastValue = df.fillna(method='ffill') # 即将上个数据对应的值直接复制过来给空值的地方
# print(df_lastValue)
##使⽤线性插值法填充
df_fillline = df.interpolate() # 还是只能填充数字类型, 将非空值的数据通过线性模拟,大白话就是通过求直线方程, 然后将空值对应的行数或者列数代进去,获得的值
print(df_fillline)
噪声数据
- 噪声(noise) 是被测量的变量的随机误差或⽅差。
- 分箱(binning)
分箱通过查考数据的“临近”即周围值来光滑有序数据值。由于分箱⽅法考察邻近值,因此它进⾏的是
局部光滑。
将数据分为𝑛个等频的箱中,可以⽤箱均值、箱中位数或箱边界光滑数据。
# 噪声数据
data_price = np.array([15,4,8,21,28,21,24,25,34])
print(data_price)
## 对数据进⾏排序
data_price.sort()
print(data_price)
## 将数据进⾏分箱, 分3个箱
data_box = data_price.reshape([3,-1])
print(data_box)
## ⽤箱均值光滑
data_repeatmean = np.repeat(data_box.mean(axis=1), 3)
print(data_repeatmean)
## ⽤箱中位数光滑
data_repeatmedian = np.repeat(np.median(data_box, axis=1), 3)
print(data_repeatmedian)
# scipy是Python的一个科学计算库,它导入了numpy库中的所有命名空间,而且包含其他的一些库。其中的stats库是一个提供统计功能的库。
from scipy import stats # 从scipy包中导入stats库
values = [1.0, 1.0, 2.0, 1.5, 3.0]
s = stats.binned_statistic([1, 1, 2, 5, 7], values, 'mean', bins=3)
print(s)
## ⽤箱边界光滑
data_repeatmax = np.repeat(data_box.max(axis=1), 3)
print(data_repeatmax)
结果如下 :
[15 4 8 21 28 21 24 25 34]
[ 4 8 15 21 21 24 25 28 34]
[[ 4 8 15]
[21 21 24]
[25 28 34]]
[ 9. 9. 9. 22. 22. 22. 29. 29. 29.]
[ 8. 8. 8. 21. 21. 21. 28. 28. 28.]
BinnedStatisticResult(statistic=array([1.33333333, nan, 2.25 ]), bin_edges=array([1., 3., 5., 7.]), binnumber=array([1, 1, 1, 3, 3], dtype=int64))
[15 15 15 24 24 24 34 34 34]
数据规范化
最大最小规范化
-
最大最小规范化 (min-max scaled)
-
假设 m i n a min_a mina 和 m a x a max_a maxa 分别是属性a的最⼩值和最⼤值,计算公式如下:
- v 1 ′ = v i − m i n a m a x a − m i n a ( n e w m a x a − n e w m i n a ) + n e w m i n a v_1'=\frac{v_i-min_a}{max_a-min_a}(new_{max_a}-new_{min_a})+new_{min_a} v1′=maxa−minavi−mina(newmaxa−newmina)+newmina
-
这样就把A的值映射到区间 [ n e w m a x a , n e w m i n a ] [new_{max_a},new_{min_a}] [newmaxa,newmina]中的 v i ′ v_i' vi′中。
from sklearn import preprocessing
import numpy as np
X_train = np.array([
[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]
])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
print(X_train_minmax)
输出结果
[[0.5 0. 1. ]
[1. 0.5 0.33333333]
[0. 1. 0. ]]
Z-score 规范化(零均值规范化)
v i ′ = v i − a ˉ σ a v_i'=\frac{v_i-\bar{a} }{\sigma_a} vi′=σavi−aˉ
通过z-socre规范化,将数值的均值转换成0, ⽅差转换成1
from sklearn import preprocessing
import numpy as np
X_train = np.array([
[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]
])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
print(X_train_minmax)
X_scaled = preprocessing.scale(X_train) #z-score规范化处理,将数值的均值转换成0, ⽅差转换成1
print(X_scaled)
print(X_scaled.mean()) #求均值, 其值接近于0
print(X_scaled.var()) #求方差
输出结果 :
[[0.5 0. 1. ]
[1. 0.5 0.33333333]
[0. 1. 0. ]]
[[ 0. -1.22474487 1.33630621]
[ 1.22474487 0. -0.26726124]
[-1.22474487 1.22474487 -1.06904497]]
4.9343245538895844e-17
1.0
小数定标
通过移动属性 a 的⼩数点位置来进⾏规范化:
v i ′ = v i 1 0 j v_i'=\frac{v_i}{10^{j}} vi′=10jvi
其中 j 是使得 m a x ( ∣ v i ′ ∣ ) < 1 max(|v_i'|)<1 max(∣vi′∣)<1 的最⼩整数
from sklearn import preprocessing
X_train = np.array([
[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]
])
print(X_train / 10)
即结果为
[[ 0.1 -0.1 0.2]
[ 0.2 0. 0. ]
[ 0. 0.1 -0.1]]
主成分分析
主成分分析(principal components anaylysis) 主要是利⽤降维的思想,在损失很少信息的前提下减少数据的维度,通常将转化⽣成的综合指标称为主成分。每个主成分都是原始变量的线性组合,且各个主成分之间互不相关。