简单的数据分析-数据预处理_哔哩哔哩_bilibili的笔记
数据预处理的常用流程:去除唯一属性,处理缺失值,属性编码,数据标准化正则化,特征选择,主成分分析。
数据无量钢化在特征选择之前,一般需要进行数据无量纲化处理,使得表征不同属性的特征具有可比性,数据无量钢化一般采用归一化和正则化方法。
归一化优点:提升模型的收敛速度和精度。
min-max标准化缺陷:新数据加入后可能会影响最大值和最小值,需要重新定义。
实现方法:在sklearn中,使用preprocessing.MinMaxScaler来实现,MinMaxScaler的重要参数feature_range,控制把数据压缩到我们希望的范围,默认是【0,1】
使用pandasimport 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】时,左右两列的结果相同。
使用numpyimport 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()



