sklearn学习——数据预处理
模块:sklearn.preprocessing
1 数据归一化处理
归一化之后的数据服从正态分布,公式如下:
在sklearn当中,我们使用preprocessing.MinMaxScaler来实现这个功能。MinMaxScaler有一个重要参数,feature_range,控制我们希望把数据压缩到的范围,默认是[0,1]。
代码:
# 导入库
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import numpy as np
# 建立数据
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
# pandas 进行归一化处理
pd = pd.DataFrame(data) #实现归一化
print("pd:\n", pd)
# 运用sklearn归一化处理
scaler = MinMaxScaler() # 实例化
scaler = scaler.fit(data) # fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data) # 通过接口导出结果
print("sklearn:\n", result)
# 训练和导出结果一步达成
result_ = scaler.fit_transform(data)
print("sklearn2:\n", result_)
# 将归一化后的结果逆转
scaler.inverse_transform(result)
# 使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中
data1 = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5, 10]) # 依然实例化
result1 = scaler.fit_transform(data1) # fit_transform一步导出结果
print("sklearn2:\n", result1)
# 当X中的特征数量非常多的时候,fit会报错并表示,数据量太大了我计算不了
# 此时使用partial_fit作为训练接口
# scaler = scaler.partial_fit(data)
# 使用numpy来实现归一化
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("numpy:\n", X_nor)
# 逆转归一化
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
print("numpy_returned:\n", X_returned)
2数据标准化
数据标准化(Standardization,又称Z-score normalization),公式如下:
- 这种方法基于原始数据的均值(mean)和标准差(standard
deviation)进行数据的标准化。将A的原始值x使用z-score标准化到x’。 - z-score标准化方法适用于属性A的最大值和最小值未知的情况,或有超出取值范围的离群数据的情况。
代码:
# 导入库
from sklearn.preprocessing import StandardScaler
# 导入数据
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
# sklearn标准化处理
scaler = StandardScaler() # 实例化
scaler.fit(data) # fit,本质是生成均值和方差
print(scaler.mean_) # 查看均值的属性mean_
print(scaler.var_) # 查看方差的属性var_
x_std = scaler.transform(data) # 通过接口导出结果
print(x_std.mean()) # 导出的结果是一个数组,用mean()查看均值
print(x_std.std()) # 用std()查看方差
print(x_std) # 标准话结果
scaler.fit_transform(data) # 使用fit_transform(data)一步达成结果
scaler_inverse = scaler.inverse_transform(x_std) # 使用inverse_transform逆转标准化
print(scaler_inverse) # 逆转结果
3 缺失值
数据:链接
提取码:u41l
class sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0,
copy=True)
代码:
# 导入库
import pandas as pd
from sklearn.impute import SimpleImputer
"""
class sklearn.impute.SimpleImputer (missing_values=nan, # 告诉SimpleImputer,数据中的缺失值长什么样,默认空值np.nan
strategy=’mean’, # 我们填补缺失值的策略,默认均值。
输入“mean”使用均值填补(仅对数值型特征可用)
输入“median"用中值填补(仅对数值型特征可用)
输入"most_frequent”用众数填补(对数值型和字符型特征都可用)
输入“constant"表示请参考参数“fill_value"中的值(对数值型和字符型特征都可用
fill_value=None, # 当参数startegy为”constant"的时候可用,可输入字符串或数字表示要填充的值,常用0
verbose=0,
copy=True # 默认为True,将创建特征矩阵的副本,反之则会将缺失值填补到原本的特征矩阵中去
)
"""
# 导入数据
data = pd.read_csv(r"Narrativedata.csv",
index_col=0 # 表示第一列为索引
)
print(data.head()) # 显示前5行数据
print(data.info()) # 显示特征数量情况
# 填补年龄
Age = data.loc[:, "Age"].values.reshape(-1, 1) # sklearn当中特征矩阵必须是二维
print(Age[:20]) # 显示前20行数据
imp_mean = SimpleImputer() # 实例化,默认均值填补
imp_median = SimpleImputer(strategy="median") # 用中位数填补
imp_0 = SimpleImputer(strategy="constant", fill_value=0) # 用0填补
# fit_transform一步完成调取结果
imp_mean = imp_mean.fit_transform(Age)
imp_median = imp_median.fit_transform(Age)
imp_0 = imp_0.fit_transform(Age)
print(imp_mean[:20]) # 在这里我们使用均值填补Age
print(imp_median[:20]) # 在这里我们使用中位数填补Age
print(imp_0[:20]) # 在这里我们使用0填补Age
data.loc[:, "Age"] = imp_median # 填补的放回原来数据中
print(data.info()) # 显示填补后特征数量
# 使用众数填补Embarked
Embarked = data.loc[:, "Embarked"].values.reshape(-1, 1)
imp_mode = SimpleImputer(strategy = "most_frequent")
data.loc[:, "Embarked"] = imp_mode.fit_transform(Embarked)
print(data.info())
# 用Pandas和Numpy进行填补
data.loc[:, "Age"] = data.loc[:, "Age"].fillna(data.loc[:, "Age"].median()) #.fillna 在DataFrame里面直接进行填补
# .dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
# 参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False
data.dropna(axis=0, inplace=True)
4 编码与哑变量
编码:将文字型数据转换为数值型。
导入数据:采用3中的数据,并补好缺失值
# 导入库
from sklearn.preprocessing import LabelEncoder
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import Binarizer
from sklearn.preprocessing import KBinsDiscretizer
# 导入数据
data = pd.read_csv(r"Narrativedata.csv",
index_col=0 # 表示第一列为索引
)
print(data.head()) # 显示前5行数据
print(data.info()) # 显示特征数量情况
# 填补年龄
Age = data.loc[:, "Age"].values.reshape(-1, 1) # sklearn当中特征矩阵必须是二维
imp_mean = SimpleImputer().fit_transform(Age)
data.loc[:, "Age"] = imp_mean # 填补的放回原来数据中
# 使用众数填补Embarked
Embarked = data.loc[:, "Embarked"].values.reshape(-1, 1)
imp_mode = SimpleImputer(strategy = "most_frequent")
data.loc[:, "Embarked"] = imp_mode.fit_transform(Embarked)
4.1标签专用
1 标签专用,能够将分类转换为分类数值
y = data.iloc[:, -1] # 要输入的是标签,不是特征矩阵,所以允许一维
le = LabelEncoder() # 实例化
le = le.fit(y) # 导入数据
label = le.transform(y) # transform接口调取结果
print(le.classes_) # 属性.classes_查看标签中究竟有多少类别
print(label) # 查看获取的结果label
data.iloc[:, -1] = label
print(data)
'''
le.fit_transform(y) # 也可以直接fit_transform一步到位
le.inverse_transform(label) # 使用inverse_transform可以逆转
#如果不需要教学展示的话我会这么写:
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])
'''
4.2 特征专用
# 2 特征专用,能够将分类特征转换为分类数值
# 接口categories_对应LabelEncoder的接口classes_,一模一样的功能
data_ = data.copy()
print(data_.head())
print(OrdinalEncoder().fit(data_.iloc[:, 1:-1]).categories_)
data_.iloc[:, 1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:, 1:-1])
print(data_.head())
4.3 独热编码,创建哑变量
三种不同性质的分类数据:
1) 舱门(S,C,Q)
三种取值S,C,Q是相互独立的,彼此之间完全没有联系,表达的是S≠C≠Q的概念。这是名义变量。
2) 学历(小学,初中,高中)
三种取值不是完全独立的,我们可以明显看出,在性质上可以有高中>初中>小学这样的联系,学历有高低,但是学历取值之间却不是可以计算的,我们不能说小学 + 某个取值 = 初中。这是有序变量。
3) 体重(>45kg,>90kg,>135kg)
各个取值之间有联系,且是可以互相计算的,比如120kg - 45kg = 90kg,分类之间可以通过数学计算互相转换。这是有距变量。
类别OrdinalEncoder可以用来处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息:
代码:
# 3 独热编码,创建哑变量
X = data.iloc[:, 1:-1]
enc = OneHotEncoder(categories='auto').fit(X)
result = enc.transform(X).toarray()
print(result)
# 依然可以直接一步到位,但为了给大家展示模型属性,所以还是写成了三步
OneHotEncoder(categories='auto').fit_transform(X).toarray()
# 依然可以还原
print(pd.DataFrame(enc.inverse_transform(result)))
print(enc.get_feature_names())
# axis=1,表示跨行进行合并,也就是将量表左右相连,如果是axis=0,就是将量表上下相连
newdata = pd.concat([data, pd.DataFrame(result)], axis=1)
print(newdata.head())
newdata.drop(["Sex", "Embarked"], axis=1, inplace=True) # 删除列
newdata.columns = ["Age", "Survived", "Female", "Male", "Embarked_C", "Embarked_Q", "Embarked_S"]
print(newdata.head())
5 二值化与分段
sklearn.preprocessing.Binarizer
根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。
代码:(接4中数据)
# 4 二值化与分段
# 将年龄二值化
data_2 = data.copy()
X = data_2.iloc[:, 0].values.reshape(-1, 1) #类为特征专用,所以不能使用一维数组
transformer = Binarizer(threshold=30).fit_transform(X)
print(transformer)
preprocessing.KBinsDiscretizer
# 5 分段
X = data.iloc[:, 0].values.reshape(-1, 1)
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(X) # 查看转换后分的箱:变成了一列中的三箱
print(set(est.fit_transform(X).ravel()))
est_ = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform') # 查看转换后分的箱:变成了哑变量
print(est_.fit_transform(X).toarray())