1.异常值处理
- 通过箱线图(或 3-Sigma)删除异常值或设置为缺失值;
- 长尾截断;
以下代码是根据箱线图处理异常值封装的函数:
def outliers_proc(data, col_name, scale=3):
"""
用于清洗异常值,默认用 box_plot(scale=3)进行清洗
:param data: 接收 pandas 数据格式
:param col_name: pandas 列名
:param scale: 尺度
:return:
"""
def box_plot_outliers(data_ser, box_scale):
"""
利用箱线图去除异常值
:param data_ser: 接收 pandas.Series 数据格式
:param box_scale: 箱线图尺度,
:return:
"""
iqr = box_scale * (data_ser.quantile(0.75) - data_ser.quantile(0.25))
val_low = data_ser.quantile(0.25) - iqr
val_up = data_ser.quantile(0.75) + iqr
rule_low = (data_ser < val_low)
rule_up = (data_ser > val_up)
return (rule_low, rule_up), (val_low, val_up)
data_n = data.copy()
data_series = data_n[col_name]
rule, value = box_plot_outliers(data_series, box_scale=scale)
index = np.arange(data_series.shape[0])[rule[0] | rule[1]] # 得到异常值得索引
print("Delete number is: {}".format(len(index)))
data_n = data_n.drop(index)
data_n.reset_index(drop=True, inplace=True)
print("Now column number is: {}".format(data_n.shape[0]))
index_low = np.arange(data_series.shape[0])[rule[0]]
outliers = data_series.iloc[index_low]
print("Description of data less than the lower bound is:")
print(pd.Series(outliers).describe())
index_up = np.arange(data_series.shape[0])[rule[1]]
outliers = data_series.iloc[index_up]
print("Description of data larger than the upper bound is:")
print(pd.Series(outliers).describe())
fig, ax = plt.subplots(1, 2, figsize=(10, 7))
sns.boxplot(y=data[col_name], data=data, palette="Set1", ax=ax[0])
sns.boxplot(y=data_n[col_name], data=data_n, palette="Set1", ax=ax[1])
return data_n
data = outliers_proc(data,'power',3)
2.缺失值处理
- 不处理(针对类似 XGBoost 等树模型可自行处理缺失值);
- 删除(缺失数据太多);
- 插值补全,包括均值/中位数/众数/建模预测/多重插补/压缩感知补全/矩阵补全等;
- 分箱,缺失值一个箱
以下代码使用SimpleImputer进行均值/中位数/众数/常数进行插补:
from sklearn.impute import SimpleImputer
# 用众数填充
null_col = ['bodyType','fuelType','gearbox']
si = SimpleImputer(strategy='most_frequent').fit(data[null_col])
data[null_col] = si.transform(data[null_col])
# 用均值填充
si = SimpleImputer(strategy='median').fit(data.power.values.reshape(-1,1))
# sklearn中fit及transform中需使用二维数据
data['power'] = si.transform(data.power.values.reshape(-1,1)).ravel()
# 最后使用ravel()转回一维数据
3.数据变换:
-
标准化(转换为标准正态分布);
-
归一化(转换到 [0,1] 区间);
-
针对幂律分布,可以采用公式:
l o g ( 1 + x 1 + m e d i a n ) log(\frac{1+x}{1+median}) log(1+median1+x) -
box-cox变换(主要针对回归分析中的因变量y变换)
BoxCox 变换方法及其实现运用PPT
from sklearn.preprocessing import MinMaxScaler,StandardScaler
# 归一化
scaler = MinMaxScaler()
result = scaler.fit_transform(data) # 将data归一化
scaler.inverse_transform(result) # 将归一化结果逆转
# 标准化
scaler = StandardScaler()
result = scaler.fit_transform(data) # 将data标准化
scaler.inverse_transform(result) # 将标准化结果逆转
# box-cox变换
from scipy import stats
y_bc,lambda_ = stats.boxcox(y) # 输入一维变量
lambda_ # 自动计算的最优lambda
y_bc # 变换后的数组
4.分类特征编码与哑变量
- 编码:将文字型特征转换为数值型,如性别中将‘男’‘女’转换为0,1表示。
- 哑变量:将有k个取值的列,转换成k列值为0和1的稀疏矩阵表示。
from sklearn.preprocessing import LabelEncoder,OrdinalEncoder,OneHotEncoder
# 标签专用编码 LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1]) # 这个标签专用允许使用一维数据
# 特征专用
data.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
# 独热编号,创建哑变量
OneHotEncoder(categories='auto').fit_transform(X).toarray()
5.连续变量分箱
- 等频/等距/聚类分箱
- 卡方分箱(详见另一篇博文)
- Best-KS分箱
- 决策树分箱
# 等频/等距/聚类分箱
from sklearn.preprocessing import KBinsDiscretizer
KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform').fit_transform(x)
# strategy='uniform'等距,'quantile'等距分箱,'kmeans'表示聚类分箱
# 决策树分箱
from sklearn.tree import DecisionTreeClassifier,DecisionTreeRegressor
clf = DecisonTreeClassifier(crieterion = 'gini', # 划分标准
max_leaf_nodes=8, # 想要分n箱,最大叶子节点数就设为n
min_sample_leaf = 1) # 叶子节点存在所需最小样本量
clf.fit(x,y)
# 通过clf.tree_ 导出可以查看树结构的端口
clf.tree_.node_count # 查看数总共有多少个节点
left = clf.tree_.children_left # 查看左侧节点编号
right = clf.tree_.children_right # 查看右侧节点编号
threshold = clf.tree_.threshold # 查看节点分裂阈值
bins = threshold(left != right) # 获得决策树中的分箱边界
# 实际的边界要取(最小值-0.01)及最大值做两边,或者-inf及inf做两边
bins = sorted(list(bins) + [-np.inf,np.inf])
6.特征构造
- 构造统计量特征,报告计数、求和、比例、标准差等;
- 时间特征,包括相对时间和绝对时间,节假日,双休日等;
- 地理信息,包括分箱,分布编码等方法;
- 非线性变换,包括 log/ 平方/ 根号等;
- 特征组合,特征交叉;
7.特征筛选
-
Filter过滤法:
方差过滤
相关性过滤:卡方、F检验、互信息法 -
Embedded嵌入法,如Lasso
-
Wrapper包裹法,如LVM
好
8.降维
降维也是一种特征选择
- PCA/LDA/ICA
【参考资料】
- 天池入门赛
- 基于sklearn决策树的最优分箱与IV值计算-Python实现
- 菜菜的sklearn课堂