赞
踩
目录
1.2.2 使用sklearn中的SimpleImputer进行填补
4.1.2 使用sklearn.preprocessing.MinMaxScaler进行归一化处理
进行数据预处理的第一步是要检查数据是否含有缺失值,并且需要针对不同情况进行填补或者是删除:
- import pandas as pd
- data.dropna(axis=0,inplace=True)
dropna(axis=0)删除所有有缺失值的行,若改为dropna(axis=1)则表示删除所有有缺失值的列
参数inplace默认值为False,当其为True时表示在原数据集上进行修改,若为False表示生成一个副本,不修改原数据。
以下以“Age”为例使用中位数进行填补,如果要使用众数或均值则分别使用mode、mean来替换median的位置。
- #使用fillna直接在dataframe中进行填补
- data.loc[:,"Age"] = data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
相比起直接使用pandas进行填补,使用SimpleImputer进行填补相对来说较为麻烦。以下依旧使用“Age”为例进行填补。
- from sklearn.impute import SimpleImputer
-
- #sklearn中特征矩阵必须是二维的,将Age转化为二维
- Age = data.loc[:,"Age"].values.reshape(-1,1)
-
- #实例化
- imp_mean = SimpleImputer() #默认使用均值进行填补
- imp_median = SimpleImputer(strategy='median') #使用中位数进行填补
- imp_frequent = SimpleImputer(strategy='"most_frequent') #使用众数进行填补
- imp_0 = SimpleImputer(strategy='constant',fill_value=0) #用0进行填补
-
- #训练和导出结果
- imp_mean = imp_mean.fit_transform(Age)
- imp_median = imp_median.fit_transform(Age)
- imp_frequent = imp_frequent。fit_transform(Age)
- imp_0 = imp_0.fit_transform(Age)
-
- #以使用中位数为例,填补Age
- data.loc[:,"Age"] = imp_median
SimpleImputer的具体参数如下:
并不是每种数据都可以使用插值法进行填补,显然案例中的数据在此处均不适用于插值方法进行填补。
可以使用df.interpolate(method='')格式进行线性插值的填补。其中method后来选择依据哪个变量进行插值替换。
多项式插值常使用polyfit()和polyval()函数共同实现,其中polyfit()返回的多项式拟合系数作为polyval()的输入参数,polyval返回插值结果。
使用numpy中的polyfit()函数的基本语法如下:
np.polyfit(x, y, deg, full=False, w=None)
其中,
使用numpy中的polyval()函数的基本语法如下:
np.polyval(p,x)
其中,
可以使用随机森林算法对于缺失值进行填补,此处在之后的文章中进行分析学习。
- import pandas as pd
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.model_selection import train_test_split
- from sklearn.model_selection import GridSearchCV
- from sklearn.model_selection import cross_val_score
- import matplotlib.pyplot as plt
处理重复数据的常见方法有:
一般的,如果重复数据为异常数据则采取直接删除的处理方式,若不是则可不做处理。
data.drop_duplicates() #完全相同数据仅保留一个
异常值是超出或低于正常范围的数据。对于异常值,可以依据之前的方法对其进行替换或者是直接删除。
常见的处理异常值的方法有:
1. 3原则
使用3原则的前提条件是,数据需要服从正态分布,我们可以认为,在三倍的标准差范围外的数据概率极小,可以认为是异常值进行处理。
- def z_outliers(data,t=3):
- mean = np.mean(data)
- std = np.std(data)
- outliers = []
- for i in data:
- score = (i-mean)/std
- if abs(score)>t:
- outliers.append(i)
- return outliers
2. 箱型图法
箱型图通常把数据划分为四分位进行处理,令第一个四分位数为q1,第三个四分位数为q3,此时离群点低于q1-1.5*(q3-q1)或高于q3+1.5*(q3-q1)。
- def zr_outliers(data):
- q1 = np.percentile(data,25,interpolation = 'midpoint')
- q3 = np.percentile(data,75,interpolation = 'midpoint')
- low = q1-1.5*(q3-q1)
- up = q3+1.5*(q3-q1)
- outliers = []
- for i in data:
- if i < low or i > up:
- outliers.append(i)
- return outliers
无量纲化优点:
对于后面即将提到的StandardScaler和MinMaxScaler的fit接口中数组应该至少是二维数组。
数据的归一化处理将数据根据极差进行缩放,使所有数据变幻到[0,1]区间内。归一化后的数据服从正态分布,其具体的计算公式如下:
X’ = (X-Xmin) / (Xmax-Xmin)
- import numpy as np
-
- X = np.array(data)
- X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
若要进行逆转归一化处理(即将归一化的数据还原),只需进行如下的变换:
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
- from sklearn.preprocessing import MinMaxScaler
- data = [[1, 2], [-1, -2], [3, 4]]
-
- scaler = MinMaxScaler(feature_range=[0,1]) #实例化,feature_range默认即为[0,1],可以不填写
- result = scaler.fit_transform(data) #训练并导出结果
其中,feature_range为将数据压缩到什么范围,默认值为[0,1]。
若要进行逆转归一化处理(即将归一化的数据还原),只需进行如下的变换:
scaler.inverse_transform(result)
数据标准化可以使数据服从均值为0,方差为1的正态分布。具体计算公式如下所示:
在sklearn.preprocessing.StandardScaler中可以实现数据的标准化处理:
- from sklearn.preprocessing import StandardScaler
- data = [[1, 2], [-1, -2], [3, 4]]
-
- scaler = StandardScaler()
- scaler.fit(data)
- x_std = scaler.transform(data)
-
- """
- scaler.var_ #查看方差属性
- scaler.mean_ #查看均值属性
- x_std.mean() #均值
- x_std.std() #方差
- """
若要进行逆转归一化处理(即将归一化的数据还原),只需进行如下的变换:
scaler.inverse_transform(x_std)
标准化处理对于异常值非常敏感,在不涉及距离度量、梯度、协方差计算或者需要将数据压缩到一定范围中会选择使用数据的标准化处理。
数据的归一化处理对异常值的敏感性较小,在聚类、支持向量机中经常使用,效果较好。
许多机器学习算法中都只能处理数值型变量,对于文本型变量无法处理。对于文本型分类变量,为了使算法能够处理,我们可以对其进行编码处理,转化为数值型变量。
- from sklearn.preprocessing import LabelEncoder
-
- y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维
-
- lab = LabelEncoder() #实例化
- lab = lab.fit(y) #导入数据
- label = lab.transform(y) #transform接口调取结果
-
- #lab.classes_ #属性.classes_查看标签中究竟有多少类别
- #label #查看获取的结果label
-
- #lab.inverse_transform(label) #使用inverse_transform可以逆转
- from sklearn.preprocessing import OrdinalEncoder
-
- OrdinalEncoder().fit(data.iloc[:,1:-1]).categories_
- data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data.iloc[:,1:-1])
需要注意的是,特征矩阵的维数至少是2维,如果是一维可以使用reshape进行转换。
由于有时不同的分类之间无法进行简单的算术运算。举个例子,如果进行如上转化,把“苹果”记为0,“葡萄”记为1,“桃子”记为2。三种取值之间可以说是毫无关系的,之间更没有算数运算(加、减、乘、除),如果单纯记为0、1、2,则默认可以进行算数运算了。
所以,对于该种情况,我们可以采用独热编码,将其转变为一个向量,也就是哑变量。
还是上面的例子,经过独热编码处理成哑变量后,可以表示为:
“苹果” [1,0,0];“葡萄” [0,1,0];“桃子” [0,0,1]
- from sklearn.preprocessing import OneHotEncoder
- X = data.iloc[:,1:-1]
- enc = OneHotEncoder(categories='auto').fit(X)
- result = enc.transform(X).toarray()
-
- #依然可以还原
- pd.DataFrame(enc.inverse_transform(result))
-
- #axis=1,表示跨行进行合并,也就是将量表左右相连,如果是axis=0,就是将量表上下相连
- newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
- newdata.head()
- newdata.drop(["Sex","Embarked"],axis=1,inplace=True)
- newdata.columns = ["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
- newdata.head()
如果在一个特征中,大多数的取值都一样,或者是所有均相同,那么此时这个特征对于样本的区分则没有太大的差别,可以认为对于样本没有影响。
例如,要预测明天是晴天、阴天还是下雨,那如果“太阳从那个方向升起”(众所周知,太阳都是从东边升起的)也作为一个特征的话,那这个特征对于预测结果是没有帮助的,需要去除。
通常情况下,进行特征选择,首先要删除方差为0的特征。
- from sklearn.feature_selection import VarianceThreshold
- selector = VarianceThreshold() #实例化,不填参数默认方差为0
- X_var0 = selector.fit_transform(X) #获取删除不合格特征之后的新特征矩阵
VarianceThreshold的默认参数为0,即表示删除方差为0的特征。自定义的数值直接填到括号中即可。
选出与标签相关且有意义的特征,如果特征与标签无关,则删除该特征。
卡方过滤是专门针对分类问题的相关性过滤,会计算每个非负特征和标签之间的卡方统计量,依据卡方统计量由高到低进行排序,取前k个特征,认为后面的特征与标签的相关性较小,去除后面的特征。
如果卡方检验检测到某个特征中所有值均相同,会提示我们先进行方差过滤。
- from sklearn.ensemble import RandomForestClassifier as RFC
- from sklearn.model_selection import cross_val_score
- from sklearn.feature_selection import SelectKBest
- from sklearn.feature_selection import chi2
-
- #假设需要300个特征
- X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y)
- X_fschi.shape
卡方过滤有一个很重要的问题,就是如何确定超参数K的取值?
那么如何通过p值来判断K的取值呢?
卡方检验会返回卡方值和P值两个统计量,对于其返回的p值,我们通常认为,其p值小于0.01或者0.05即为两组数据是相关的,而p值大于0.01或者0.05则认为两组数据是相互独立的。
所以,我们可以根据卡方检验返回的p值,保留p值大于0.05的特征,筛选出去p值小于0.05的特征。
- chivalue, pvalues_chi = chi2(X_fsvar,y)
- #chivalue #卡方值
- #pvalues_chi #p值
-
- k = chivalue.shape[0] - (pvalues_chi > 0.05).sum()
- X_fschi = SelectKBest(chi2, k=k).fit_transform(X_fsvar, y)
F检验又称为齐次性检验,用来捕捉每个特征与标签之间的线性关系的过滤方法。既可以用作回归(feature_selection.f_classif F检验分类),也可以做分类(feature_selection.f_regression F检验回归)。
注意,F检验只能寻找两组数据之间的线性关系!!!
和卡方过滤一样,F检验也需要依靠p值来筛选出相关的特征。同样保留p值大于0.05的特征,筛选出去p值小于0.05的特征。
- from sklearn.feature_selection import f_classif
- F, pvalues_f = f_classif(X_fsvar,y)
- k = F.shape[0] - (pvalues_f > 0.05).sum()
- X_fsF = SelectKBest(f_classif, k=k).fit_transform(X_fsvar, y)
互信息法可以捕捉特征与标签的线性或者是非线性关系,既可以做分类(feature_selection.mutual_info_classif 互信息分类),也可以做回归(feature_selection.mutual_info_regression 互信息回归)。
互信息法不返回p值或者F值类似的统计量,它返回“每个特征与目标之间的互信息量估计”,这个估计量在[0,1]之间,为0表示两个变量完全独立,为1表示两个变量完全相关。
- from sklearn.feature_selection import mutual_info_classif as MIC
- result = MIC(X_fsvar,y)
- k = result.shape[0] - sum(result <= 0)
- X_fsmic = SelectKBest(MIC, k=k).fit_transform(X_fsvar, y)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。