数据预处理及特征工程

1.异常值处理

  1. 通过箱线图(或 3-Sigma)删除异常值或设置为缺失值;
  2. 长尾截断;
    以下代码是根据箱线图处理异常值封装的函数:
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.缺失值处理

  1. 不处理(针对类似 XGBoost 等树模型可自行处理缺失值);
  2. 删除(缺失数据太多);
  3. 插值补全,包括均值/中位数/众数/建模预测/多重插补/压缩感知补全/矩阵补全等;
  4. 分箱,缺失值一个箱

以下代码使用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.数据变换:

  1. 标准化(转换为标准正态分布);

  2. 归一化(转换到 [0,1] 区间);

  3. 针对幂律分布,可以采用公式:
    l o g ( 1 + x 1 + m e d i a n ) log(\frac{1+x}{1+median}) log(1+median1+x)

  4. 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.连续变量分箱

  1. 等频/等距/聚类分箱
  2. 卡方分箱(详见另一篇博文
  3. Best-KS分箱
  4. 决策树分箱
# 等频/等距/聚类分箱 
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.特征构造

  1. 构造统计量特征,报告计数、求和、比例、标准差等;
  2. 时间特征,包括相对时间和绝对时间,节假日,双休日等;
  3. 地理信息,包括分箱,分布编码等方法;
  4. 非线性变换,包括 log/ 平方/ 根号等;
  5. 特征组合,特征交叉;

7.特征筛选

  1. Filter过滤法:
    方差过滤
    相关性过滤:卡方、F检验、互信息法

  2. Embedded嵌入法,如Lasso

  3. Wrapper包裹法,如LVM

8.降维

降维也是一种特征选择

  1. PCA/LDA/ICA

【参考资料】

  1. 天池入门赛
  2. 基于sklearn决策树的最优分箱与IV值计算-Python实现
  3. 菜菜的sklearn课堂
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值