泰迪杯国奖思路分享(二)--数据清洗与特征构造

序言

数据清洗是在数据挖掘当中最重要的一个步骤,“特征决定上限,而模型只是在逼近这个上限。”因此数据的清洗与特征构造都是为后续的模型构建打下坚实的基础。

数据清洗

在这次比赛我们团队将数据清洗分为了五个步骤

  1. 缺失值处理
  2. 离散特征处理
  3. 异常值处理
  4. 回归特征标准化
  5. 特征筛选

缺失值处理

缺失值处理首先要看看缺失的列的缺失比例,再根据缺失值比例进行不同的处理。

queshi_bili=((data_train.isnull().sum())/data_train.shape[0]).sort_values(ascending=False).map(lambda x:"{:.2%}".format(x))
queshi_bili
复制代码

image.png

可以看到有些特征缺失值都快有100%了,这些数据不仅没有作用反而可能带来噪音。因此对于缺失值比例较大的特征我们根据80%法则,对于数据中非空小于80的数据进行成列删除。80%法则 (Bijlsma et al. 2006)认为,当某一物质的非缺失部分低于总样本量的80%时,建议删除该物质。

t = int(0.8*data_train.shape[0])
data_train_shanchu = data_train.dropna(thresh=t,axis=1)#保留至少有 t 个非空的列
data_train_shanchu
复制代码

image.png

而剩下那些缺失值比例为20%以内的我们采取机器学习进行预测,从而达到更高的准确率,更好的填充相应缺失值,为后续做铺垫。由于其他机器学习算法模型训练的时间过长,我们采取了较为简单的机器学习模型,knn算法。

from fancyimpute import KNN
data_train_knn = pd.DataFrame(KNN(k=6).fit_transform(data_train_shanchu), columns=data_train_shanchu.columns)
data_train_knn
复制代码

image.png

离散特征处理

离散特征一般是非数值型数据,需要将其转化为数值型,便于后续的预测。 离散特征处理一般是分为两种,一种是one-hot编码,但是这种会导致特征的维度增加,增加计算量。另外一种是factorize()函数进行处理。 本文采取的是第二种,因为这次数据集维度已经很高了,如果再进行one-hot编码会导致计算量增大,无疑是雪上加霜。

feature_leiduixiang=['报告类型','会计准则','货币代码']
for i in feature_leiduixiang:
    data_train_shanchu[i] = data_train_shanchu[i].map(lambda x: re.compile("([a-zA-Z]+)").search(x).group()) 
    data_train_shanchu[i] = pd.factorize(data_train_shanchu[i])[0]
复制代码

异常值处理

异常值的查找方法有很多,比如箱线图,正态分布等等。比赛中采取的异常值查找是箱线图,但是基于改进的箱线图,本身的箱线图是Q3+1.5IQR或者Q1-1.5IQR。但是因为是财务异常预测,因此只是去除极值,而不是直接去除异常值,避免影响后续的判断。

而查找到异常值,也有多种处理方法,比如用0值代替,或者转化为缺失值,用缺失值的填充方法进行处理,本次比赛我们采取的是截尾法。比如远大于Q3的值用最大值替换,远小于Q1的值用最小值替换。

"""这里包装了一个异常值处理的代码,可以随便调用"""
def outliers_proc(data, col_name, scale=100):
    """
        用于截尾异常值, 默认用box_plot(scale=3)进行清洗
        param:
            data:接收pandas数据格式
            col_name: pandas列名
            scale: 尺度
    """
    data_col = data[col_name]
    Q1 = data_col.quantile(0.25) # 0.25分位数
    Q3 = data_col.quantile(0.75)  # 0,75分位数
    IQR = Q3 - Q1

    data_col[data_col < Q1 - (scale * IQR)] = np.NaN
    data_col[data_col > Q3 + (scale * IQR)] = np.NaN

    return data[col_name]
复制代码

回归特征标准化

为了提升模型的精度和提升收敛速度,我们对数据进行标准化,StandardScaler原理去均值和方差归一化。且是针对每一个特征维度来做的,而不是针对样本。

标准差标准化(standardScale)使得经过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为。

image.png

其中μ为所有样本数据的均值,σ为所有样本数据的标准差

for i in feature_biaozhun:
    scaler = preprocessing.StandardScaler()
    data_train_biaozhunhua[i] = scaler.fit_transform(data_train_biaozhunhua[i].values.reshape(-1,1))  #转化为一列的数据
复制代码

特征构造

特征构造其实一般与代码无关,更多是根据数据所给的数据特征,查找相应的文献进行特征的构造。 比如我们这次比赛就根据文献和特征构建了6个特征。

data_train_xintezheng['固定资产比率']=data_train_xintezheng['固定资产']/data_train_xintezheng['资产总计']
data_train_xintezheng['所有者权益比率']=data_train_xintezheng['所有者权益(或股东权益)合计']/data_train_xintezheng['资产总计']
data_train_xintezheng['流动比率']=data_train_xintezheng['流动资产合计']/data_train_xintezheng['流动负债合计']
data_train_xintezheng['速动比率']=(data_train_xintezheng['流动资产合计']-data_train_xintezheng['存货'])/data_train_xintezheng['流动负债合计']
data_train_xintezheng['资产负债率']=data_train_xintezheng['负债合计']/data_train_xintezheng['资产总计']
data_train_xintezheng['全部现金回收率']=data_train_xintezheng['经营活动产生的现金流量净额']/data_train_xintezheng['资产总计']
复制代码

image.png

总结

其实数据清洗还是那几种步骤和方法,更重要的是根据数据的情况使用不同的方法进行处理,其实还有一些数据处理后续还需要根据模型的需要进行二次处理,目前的处理只是对数据的初步处理。

仅仅是个人的一些思想和看法,有不对的地方希望大家能在评论区指出来,大家互相学习。

猜你喜欢

转载自juejin.im/post/7074513174749249550