1. 数据无量纲化

将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布
的需求,这种需求统称为将数据“无量纲化”。线性的无量纲化包括中心化(Zero-centered或者Meansubtraction)处理和缩放处理(Scale)。

中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。
缩放的本质是通过除以一个固定值,将数据固定在某个范围之中。

1.1 preprocessing.MinMaxScaler 数据归一化

当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间,这个过程就叫做数据归一化(Normalization)。归一化后的数据服从正态分布。MinMaxScaler有一个重要参数,feature_range,控制我们希望把数据压缩到的范围,默认是[0,1]。

  1. # 数据归一化
  2. from sklearn.preprocessing import MinMaxScaler
  3. data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
  4. #如果换成表是什么样子?
  5. import pandas as pd
  6. pd.DataFrame(data)
  7. #实现归一化
  8. scaler = MinMaxScaler() #实例化
  9. scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x)
  10. result = scaler.transform(data) #通过接口导出结果
  11. result
  12. result_ = scaler.fit_transform(data) #训练和导出结果一步达成
  13. scaler.inverse_transform(result) #将归一化后的结果逆转
  14. #使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中
  15. data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
  16. scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化
  17. result = scaler.fit_transform(data) #fit_transform一步导出结果
  18. result

机器学习:07--sklearn中的数据预处理 - 图1

1.2 preprocessing.StandardScaler 数据标准化

当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布),而这个过程就叫做数据标准化(Standardization,又称Z-score normalization)。

  1. # 数据标准化
  2. from sklearn.preprocessing import StandardScaler
  3. data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
  4. scaler = StandardScaler() #实例化
  5. scaler.fit(data) #fit,本质是生成均值和方差
  6. scaler.mean_ #查看均值的属性mean_
  7. scaler.var_ #查看方差的属性var_
  8. x_std = scaler.transform(data) #通过接口导出结果
  9. x_std.mean() #导出的结果是一个数组,用mean()查看均值 0
  10. x_std.std() #用std()查看方差 1
  11. scaler.fit_transform(data) #使用fit_transform(data)一步达成结果
  12. scaler.inverse_transform(x_std) #使用inverse_transform逆转标准化

机器学习:07--sklearn中的数据预处理 - 图2

对于StandardScaler和MinMaxScaler来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候保持缺失NaN的状态显示。
大多数机器学习算法中,会选择StandardScaler来进行特征缩放,因为MinMaxScaler对异常值非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。

2 缺失值

  1. import pandas as pd
  2. data = pd.read_csv(r"C:\Users\18700\Desktop\03数据预处理和特征工程\Narrativedata.csv",index_col=0) #index_col是将第0列作为索引
  3. data.head()

机器学习:07--sklearn中的数据预处理 - 图3

2.1 impute.SimpleImputer

专门用来填补缺失值的类,sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True),有四个重要参数:
机器学习:07--sklearn中的数据预处理 - 图4
填补年龄

  1. #serise,这是pandas中的一种格式(索引+值),.values就是将其中的值提取出来,reshape(-1,1)将数据升维
  2. Age = data.loc[:,"Age"].values.reshape(-1,1) #sklearn当中特征矩阵必须是二维
  3. Age[:20]
  4. from sklearn.impute import SimpleImputer
  5. imp_mean = SimpleImputer() #实例化,默认均值填补
  6. imp_median = SimpleImputer(strategy="median") #用中位数填补
  7. imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填补
  8. imp_mean = imp_mean.fit_transform(Age) #fit_transform一步完成调取结果
  9. imp_median = imp_median.fit_transform(Age)
  10. imp_0 = imp_0.fit_transform(Age)
  11. imp_mean[:20]
  12. imp_median[:20]
  13. imp_0[:20]
  14. #在这里我们使用中位数填补Age
  15. data.loc[:,"Age"] = imp_median
  16. data.info()

使用众数填补Embarked

  1. Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
  2. imp_mode = SimpleImputer(strategy = "most_frequent") #实例化,使用众数填补,most_frequent可以用来填写字符型数据
  3. data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
  4. data.info()

用pandas和numpy进行数据填补 (均值的填补更为简单)

  1. import pandas as pd
  2. data_ = pd.read_csv(r"C:\Users\18700\Desktop\03数据预处理和特征工程\Narrativedata.csv",index_col=0)
  3. data_.head()
  4. data_.loc[:,"Age"] = data_.loc[:,"Age"].fillna(data_.loc[:,"Age"].median())
  5. #.fillna 在DataFrame里面直接进行填补
  6. data_.dropna(axis=0,inplace=True)
  7. #.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
  8. #参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False
  9. data_.info()

3 处理分类型特征:编码与哑变量

将文字型数据转换为数值型。

3.1 preprocessing.LabelEncoder: 标签专用,能够将分类转换为分类数值

  1. #将标签转换为分类数值
  2. from sklearn.preprocessing import LabelEncoder
  3. y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维 iloc就是取列,取最后一列
  4. le = LabelEncoder() #实例化
  5. le = le.fit(y) #导入数据
  6. label = le.transform(y) #transform接口调取结果
  7. le.classes_ #属性.classes_查看标签中究竟有多少类别
  8. label #查看获取的结果label
  9. le.fit_transform(y) #也可以直接fit_transform一步到位
  10. le.inverse_transform(label) #使用inverse_transform可以逆转
  11. data.iloc[:,-1] = label #让标签等于我们运行出来的结果
  12. data.head()

机器学习:07--sklearn中的数据预处理 - 图5

简化代码

  1. from sklearn.preprocessing import LabelEncoder
  2. data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1]) #实例化,训练和导出放在一起

3.2 preprocessing.OrdinalEncoder: 特征专用,能够将分类特征转换为分类数值

  1. #特征专用
  2. from sklearn.preprocessing import OrdinalEncoder
  3. data_ = data.copy()
  4. data_.head()
  5. #接口categories_对应LabelEncoder的接口classes_,一模一样的功能
  6. OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_ #data_.iloc[:,1:-1]是取第一列到最后一列前,最后一列不取
  7. data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
  8. data_.head()
  9. OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_ #再次查看是否变成数据
  10. data_.loc[:,'Sex'] #取出sex这一列进行查看
  11. data_.iloc[:,1] #也是取出了sex这一列进行查看。只是loc是直接根据列名进行取,iloc是取出所需要列的所有行。
  12. data_.iloc[1,:] #这就是取出第一行的所有数据

3.3 preprocessing.OneHotEncoder:独热编码,创建哑变量

上面两种方式将分类转换成数字的时候,忽略了数字中自带的数学性质,所
以给算法传达了一些不准确的信息,而这会影响我们的建模。
类别OrdinalEncoder可以用来处理有序变量,比如学历;但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。
机器学习:07--sklearn中的数据预处理 - 图6
即三个取值是没有可计算性质的,是“有你就没有我”的不等概念。在我们的
数据中,性别和舱门,都是这样的名义变量。因此我们需要使用独热编码,将两个特征都转换为哑变量。

创建哑变量

  1. data.head()
  2. from sklearn.preprocessing import OneHotEncoder #独热编码
  3. X = data.iloc[:,1:-1] #提取特征性别和年龄
  4. enc = OneHotEncoder(categories='auto').fit(X) #categories='auto'是自动遍历特征中有几类
  5. result = enc.transform(X).toarray() #toarray转化为数组,不转化的话是由0,1组成的sparse matrix
  6. result

机器学习:07--sklearn中的数据预处理 - 图7

  1. #简化的代码
  2. OneHotEncoder(categories='auto').fit_transform(X).toarray()
  3. #依然可以还原
  4. pd.DataFrame(enc.inverse_transform(result))
  5. enc.get_feature_names() #返回每个哑变量指的是哪个特征中的哪个类别
  6. # array(['x0_female', 'x0_male', 'x1_C', 'x1_Q', 'x1_S'], dtype=object)
  7. #axis=1,表示按照列进行合并,也就是将量表左右相连,如果是axis=0,按照行进行合并
  8. newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
  9. newdata.head()
  10. newdata.drop(["Sex","Embarked"],axis=1,inplace=True) #将这两列进行删除,aixs=1就是对列进行操作
  11. newdata.columns =["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
  12. newdata.head()

机器学习:07--sklearn中的数据预处理 - 图8

4 处理连续型特征:二值化与分段

4.1 sklearn.preprocessing.Binarizer 二值化

根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否.

将年龄二值化

  1. data_2 = data.copy()
  2. from sklearn.preprocessing import Binarizer #二值化
  3. X = data_2.iloc[:,0].values.reshape(-1,1) #这个类为特征专用,所以不能使用一维数组
  4. transformer = Binarizer(threshold=30).fit_transform(X) #30岁作为区分,小于等于30为0,大于30为1
  5. data_2.iloc[:,0] = transformer

4.2 preprocessing.KBinsDiscretizer 分箱

将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。包含三个参数:
机器学习:07--sklearn中的数据预处理 - 图9

对年龄进行分箱操作

  1. from sklearn.preprocessing import KBinsDiscretizer
  2. X = data.iloc[:,0].values.reshape(-1,1)
  3. est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
  4. est.fit_transform(X)
  5. #查看转换后分的箱:变成了一列中的三箱
  6. set(est.fit_transform(X).ravel()) #降维ravel,set是将降维后的数据放入集合中,可用来查看到底有几个箱子
  7. est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform')
  8. #查看转换后分的箱:变成了哑变量
  9. est.fit_transform(X).toarray() #因为分了三箱,所以是三列的稀疏矩阵
  10. #shift+tab查看函数怎么使用

机器学习:07--sklearn中的数据预处理 - 图10

参考菜菜的sklearn