简单的数据分析-数据预处理_哔哩哔哩_bilibili的笔记
数据预处理的常用流程:去除唯一属性,处理缺失值,属性编码,数据标准化正则化,特征选择,主成分分析。
数据无量钢化
在特征选择之前,一般需要进行数据无量纲化处理,使得表征不同属性的特征具有可比性,数据无量钢化一般采用归一化和正则化方法。
归一化
优点:提升模型的收敛速度和精度。
min-max标准化
缺陷:新数据加入后可能会影响最大值和最小值,需要重新定义。
实现方法:在sklearn中,使用preprocessing.MinMaxScaler来实现,MinMaxScaler的重要参数feature_range,控制把数据压缩到我们希望的范围,默认是【0,1】
使用pandas
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
data=[[-1,2],[-0.5,6],[0,10],[1,18]]#data的结构为二维数组
#换成表
df=pd.DataFrame(data)
print(df)
#实现归一化
scaler=MinMaxScaler()#实例化
scaler=scaler.fit(data)#fit的本质生成最小值和最大值①
result=scaler.transform(data)#通过接口导出结果②
print(result)
result_=scaler.fit_transform(data)#训练和导出的结果一步达成(和上面的①②是一样的结果)
scaler.inverse_transform(result)#归一化后的结果逆转(就是变回原来的数据)
#使用MinMaxScaler的参数feature_range实现将数据归一化到【0,1】以外的范围中
scaler=MinMaxScaler(feature_range=[5,10])#依然实例化
result=scaler.fit_transform(data)#fit_transform一步导出结果
print(result)
#如果x中特征数量过多,fit会报错并显示数据量太大无法计算
#此时采用partial_fit作为训练接口
#scaler=scaler.partial_fit(data)
结果显示:
当归一化到【0,1】时,生成的二维数组左右两列的数据都相同,这表示数据表中这两列的数据提供的信息量是一样的。
当归一化到【5,10】时,左右两列的结果相同。
使用numpy
import numpy as np
x=np.array([[-1,2],[-0.5,6],[0,10],[1,18]])
#归一化
x_nor=(x-x.min(axis=0))/(x.max(axis=0)-x.min(axis=0))
print(x_nor)
结果显示:
#逆转归一化
x_returned=x_nor*(x.max(axis=0)-x.min(axis=0))+x.min(axis=0)
print(x_returned)
结果显示:
将已经逆转的数组重新逆转回原来的数组,不改变数据。
标准化
概念:将数据按照均值进行中心化,再按照标准差来进行缩放,数据就会服从均值为0,方差为1的正态分布(标准正态分布)。
公式如图:
from sklearn.preprocessing import StandardScaler
data=[[-1,2],[-0.5,6],[0,10],[1,18]]
scaler=StandardScaler()#实例化
scaler.fit(data)#fit的本质是生成均值和方差
scaler.mean_#查看均值的属性mean_
scaler.var_#查看方差的属性var_
x_std=scaler.transform(data)#通过接口导出数据
x_std.mean()#导出的结果是一个数组,用mean()查看均值
x_std.std()#用std()查看方差
scaler.fit_transform(data)#使用fit_transform(data)一步达成结果
scaler.inverse_transform(x_std)#使用inverse_transform逆转标准化
结果显示:
通过接口导出数据:
标准化的目的就是为了是每一列的数据均值为0,方差为1。
使用fit_transform(data)可以一步达成上述结果:
进行逆转后:回到最初的数据。
关于fit,transform和fit_transform可以查看链接:fit_transform,fit,transform区别和作用详解 - 灰信网(软件开发博客聚合)
对MinMaxScaler和StandardScaler的补充
对MinMaxScaler和StandardScaler来说:
空值(NaN)会被当作缺失值,输入数据时也只能输入二维及其以上的数组,我们一般导入的是特征矩阵,通常会是两个以上的特征。
如何选择:
StandardScaler用来特征缩放,在不涉及距离,梯度,协方差计算以及数据需要被压缩到特定区间时可以使用。
MinMaxScaler在异常值中敏感,异常值很可能会影响最大最小值。
缺失值
数据缺失比重很小时,可舍弃
数据缺失比重过大时,应进行填补
类型:
完全随机缺失:数据的缺失是随机的,不依赖于任何不完全变量或完全变量。
随机缺失:数据的缺失不是完全随机,依赖于其他完全变量。
完全非随机缺失:数据的缺失依赖于不完全变量自身。
属性:
单值缺失:缺失值属于同一属性
任意缺失:缺失值属于不同的属性
单调缺失:对于时间序列的数据,可能存在时间的缺失
处理方法
1、简单删除
2、用可能值进行填充
均值插补:数据的属性分为定距型和非定距型。如果缺失值是定距型,就以该属性存在的平均值来插补缺失的值;如果是非定距型,就用众数来进行填补。
同类均值插补:属于单值插补,它用层次聚类模型预测缺失变量的类型,再用该类型的均值进行插补。
极大似然估计:如果类型为随机缺失且模型对于完整的样本是正确的,那么我们可以观察数据的边际分布来对位置参数进行极大似然估计。常采用期望值最大化的方法,前提是适用于大样本。
多重插补:估计出待插补的值,形成多组可选插补值,选择出最合适的。步骤:①生成多组插补值集合②针对完整数据集的统计方法进行统计分析③对于结果根据评分函数进行选择,产生最终插补值。
使用SimpleImputer进行填充
import pandas as pd
data=pd.read_csv(r"···",index_col=0)
data.head()#查看数据前五行
data.info()#查看数据类型和数量
#填补年龄
Age=data.loc[:,"Age"].values.reshape(-1,1)#sklearn当中特征矩阵是二维的,“;,”的意思是选中所有的数据
#这一行分为三步,先是从所有列中提出“Age”这一列的信息,并且去除掉索引值,最后进行升维,把一维数组升维至二维
Age[:20]
from sklearn.inpute import SimpleImputer
imp_mean=SimpleImputer()#实例化,默认均值进行填补
imp_median=SimpleImputer(strategy="median")#用中位数进行填补
imp_0=SimpleImputer(strategy="constant",fill_value=0)#用0进行填补
imp_mean=imp_mean.fit_transform(Age)#fit_transform一步完成调取结果
imp_median=imp_median.fit_transform(Age)
imp_0=imp_0.fit_transform(Age)
imp_mean[:20]#查看用mean填补空值的前二十位数据,下同
imp_median[:20]
imp_0[:20]
#使用中位数进行填补
data.loc[:,"Age"]=imp_median
data.info()
#使用众数进行填补
Embarked=data.loc[:,"Embarked"].values.reshape(-1,1)
imp_mode=impleImputer(strategy="most_frequent")
data.loc[:,"Embarked"]=imp_mode.fit_transform(Embarked)
data.info()
使用pandas进行填充
import pandas as pd
data=pd.read_csv(r"···",index_col=0)#导入文件
data.head()
data.loc[:,"Age"]=data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())#先获取“Age”这一列数据,之后用中位数填充缺失值
#fillna在DataFrame里面直接进行填补
data.dropna(axis=0,inplace=True)
#.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
#参数inplace为True时表示在原数据集上进行修改,为False时表示生成一个复制对象,不修改原数据集,默认为False
处理分类型数据
from sklearn.preprocessing import LabelEncoder#导入标签编码的类
y=data.iloc[:,-1]#获取最后一列 标签 标签数据允许一维数据的输入
le=LabelEncoder()#实例化
le=le.fit(y)#导入数据
label=le.transform(y)#transform接口调取结果
le.classes_#属性.classes查看标签中究竟有多少类别
label#查看获取的结果label
le.fit_transform(y)#也可以直接fit_transform一步到位
le.inverse_transform(label)#使用.inverse_transform可以逆转
data.iloc[:,-1]=label#让标签等于我们运行出来的结果
data.head()
#如果不进行教学展示的写法
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1]=LabelEncoder().fit_transform(data.iloc[:,-1])
#preprocessing.OrdinalEncoder:特征专用,能够将分类特征转换为分类数值
#接口.categories_对应LabelEncoder的接口classes_ 一模一样的功能
data_=data.copy()#对数据进行拷贝
data_.head()
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_#查看每一列拥有的类别
data_.iloc[:,1:-1]=OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
data_.head()
独热编码(一位有效编码)
preprocessing.OneHotEncode:
概念:独热编码,创建哑变量
原理:主要采用N位状态(N个属性)寄存器来对N个状态进行编码,每个状态都由它独立的寄存器位,并且在任意时候只有一位有效
举例:男,女(男:01,女10);中美法国(中:001,美:010,法:100)
分类变量(名义变量):
概念:有两个及以上的分类,但其没有等级顺序之分
两个原则:不同类别互相排斥,所有研究对象均有归属,不可遗落。
举例:性别男女,头发颜色
有序变量:
概念:分类数大于等于3,且类别之间存在序次关系的响应变量
特点:各类型之间的稀疏程度并不均匀,类间距并不相等
例子:经济水平分为低中高
处理方法:
对于名义变量:使用哑变量的方式处理,因此需要使用独热编码,将特征转换成哑变量
data.head()
from sklearn.preprocessing import OneHotEncoder
x=data.iloc[:,1:-1]
enc=OneHotEncoder(categories='auto').fit(x)#自动识别属性
result=enc.transform(x).toarray()#将结果转化为数组
result
#依然可以一步到位
OneHotEncoder(categories='auto').fit_transform(x).toarray()
#依然可以还原
pd.DataFrame(enc.inverse_transform(result))
enc.get_feature_names()
result
result.shape
#axis=1,表示表格进行合并,将量表左右相连,axis=0,表示量表上下相连
newdata=pd.concat([data.pd.DataFrame(result)],axis=1)
newdata.head()
newdata.frop(["Sex","Embarked"],axis=1,inplace=True)
newdata.columns=["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
newdata.head()
处理连续性数据:二值化与分段
二值化:
将特征值设置为0或1,用于连续型变量。大于阙值的值映射为1,小于等于阙值映射为0。默认阙值为0时,特征中所有的正值都映射到1
处理代码:
data_2=data.copy()
from sklearn.preprocessing import Binarizer
x=data_2.iloc[:,0].values.reshape(-1,1)#类为特征专用,所以不能使用一维数组
transformer=Binarizer(threshold=30).fit_transform(x)
transformer
preprocessing.KBinsDiscretizer:
概念:将连续型变量划分为分类变量的类,将连续型变量排序后按顺序分箱后编码。
三个重要参数:n_bins 分箱(分类)个数 encode 编码方式 strategy 箱宽的方式(分箱的方式)
from sklearn.preprocessing import KBinsDiscretizer
x=data.iloc[:,0].values.reshape(-1,1)
est=KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='uniform')
est.fit_transform(x)
#查看转换后分的箱,变成了一列中的三箱
set(est.fit_transform(x).ravel())
est=KBinsDiscretizer(n_bins=3,encode='onehot',strategy='uniform')
est.fit_transform(x).toarray()