Data Preprocessing

Posted on By Jason Hao

宏观理解

在建模之前我们需要做的就是数据预处理,把raw data变成可以训练的data。那么需要处理的数据包括异常值,空缺值,还有含有矛盾信息的数据,比如一个婚姻状况是未婚的人,却在配偶属性上显示有配偶。如果数据维度过大不仅准确率很难上去,训练速度也会大打折扣,所以也许我们还需要降维。这些等等都是为了可以有一份很优秀的数据传给模型,才可以拿到很优秀的结果。

微观分析

  • 异常值处理

在观察到存在异常值之后,常见的处理办法有把它设置成当前类别的min值,max值,mean值,中位数,还有平方差和25%,50%,75% percentile等等。比如综合起来用下面的公式也是个很好的选择:

value = max(value, q(75%) + 3 * (q(75%) – q(50%)))

  • 空缺值处理

这时候我们有两个选择,一个是我们要补全这个空缺值,另一个是如果这个feature的空缺值很多,干脆直接扔掉这个feature。这就需要具体情况具体分析了,一般空缺值超过当前总数的50%就可以考虑全部丢弃。

如果我们需要补全这个空缺值,可以直接fillna(0),fillna(median),保留空值,或者用非空的数据来额外训练一个模型并且对空缺值进行预测。值得一提的是在补全数据的时候, fillna(median)往往比fillna(mean)更好,因为有空缺值和异常值的影响,mean会受到较大影响,而median相对稳定。

  • 特征分类

我们可以把所有特征分成三类,离散型(categorical),数值型(numerical)和混合型(mixed by categorical and numerical)。

所以在处理上我们也有相应的方法。比如对于离散型特征,我们可以用独热编码(one-hot encoding),数值型特征我们可以用分桶(binning)。最麻烦的就是混合型特征。举个例子,动车车票的座位,比如说19A,就代表了第19排A座。那么这种数据在编码的时候我们可以把它拆分成两个特征,一个是排数,一个是座位号,这样一个是数值的可以分桶,比如15-19分为一类,因为都比较靠车尾,座位A是靠近窗户。假如很不幸这辆车发生事故,那么伤亡率的分类(死亡,重伤,轻伤),就可以通过排数和座位号寻找线性关系。

  • 数据归一化(generalization)

存在这样一种情况,有两列特征,一列是年龄,一列是存款。年龄的取值范围假设[0 ~ 100],而存款的取值范围假设[0 ~ 10000k],那么这样的数据如果不做之前说的分桶,很容易对拟合造成影响。假设有两个参数θ1和θ2分别对应年龄x1和存款x2,最后模型想要找一个线性关系来拟合,那么 结果 y_hat = θ1 * x1 + θ2 * x2。显而易见,在这里y_hat更容易受x2的影响,即使θ2再小,也难免会有比x1更大的波动,而且在存款金额上浮动几千几万并不是什么大的变化不应该对模型造成影响。所以这时候我们需要把这种幅度区间很大的数据进行归一化。常见的有几种方法:Log1p, MinMaxScaler, MaxAbsScaler, RobustScaler和standardScaler。具体用法可以参考sklearn的API。

  • 特征选择(feature selection)

数据那么多,肯定有相关性比较高的,也有相关性比较低的。比如回归一个人的收入,可能他是哪国人并不能很明显的说明问题。这种特征如果也参加了训练并不会对模型的泛化起到积极作用。关于选择相关性的方法,可以基于统计相关性,比如sklearn内置的SelectKBest()。可以基于树的特征重要度,比如基于这个特征导致的分裂次数等等。

  • NLP模型的特征构造

自然语言处理的模型,需要对文字进行一些处理,比如说分词,给出一句话“我喜欢玩游戏”,计算机并不知道这个怪异的语言要表达什么,所以我们要告诉计算机【“我”,“喜欢”,“玩”,“游戏”】你应该这么断句然后从这些词里面寻找潜在关系。这个处理我们可以通过调用Jieba分词的Icut(sentence)来完成。分好词之后,计算机还需要知道每个词的个数,次数太多的词比如“我”、“了”、“的”这种,很可能我们就需要删除,或者可以根据TFIDF的计算来赋给每个单词一个权重,如果它出现的异常频繁,就会得到一个很低的权重。当然并不是说如果一个词出现了一次它的权重就是最大的,TFIDF考虑到了这种情况,所以它是根据这个词在单个文本中出现的频率(TF)、在所有文本中出现的次数(DF)和对于DF进行一个log变换(IDF)综合来决定的。最后那么我们需要构建辞典来统计个数,可以用Genism的Dictionary()来完成。最后我们就需要对这些词进行一个编码了,可以参考word2vec + LSTM或者bagofwords。

注:以上出现的各种方法在以后的各项专题中会有详细介绍