机器学习过程中的数据预处理和特征选择方法

1、数据清洗

数据清洗(data cleaning)是在机器学习过程中一个不可缺少的环节,其数据的清洗结果直接关系到模型效果以及最终的结论。在实际的工作中,数据清洗通常占开发过程的50%-80%左右的时间。
数据清洗过程:
(1)数据预处理
在数据预处理过程主要考虑两个方面,如下:

  • 选择数据处理工具:关系型数据库或者Python
  • 查看数据的元数据以及数据特征:一是查看元数据,包括字段解释、数据来源等一切可以描述数据的信息;另外是抽取一部分数据,通过人工查看的方式,对数据本身做一个比较直观的了解,并且初步发现一些问题,为之后的数据处理做准备。

(2)缺省值清洗
缺省值是数据中最常见的一个问题,处理缺省值有很多方式,主要包括以下四个步骤进行缺省值处理:

  • 确定缺省值范围
    在进行确定缺省值范围的时候,对每个字段都计算其缺失比例,然
    后按照缺失比例和字段重要性分别指定不同的策略。
    机器学习过程中的数据预处理和特征选择方法
  • 去除不需要的字段
    在进行去除不需要的字段的时候,需要注意的是:删除操作最好不要直接操作与原始数据上,最好的是抽取部分数据进行删除字段后的模型构建,查看模型效果,如果效果不错,那么再到全量数据上进行删除字段操作。总而言之:该过程简单但是必须慎用,不过一般效果不错,删除一些丢失率高以及重要性低的数据可以降低模型的训练复杂度,同时又不会降低模型的效果。
  • 填充缺省值内容
    填充缺省值内容是一个比较重要的过程,也是我们常用的一种缺省值解决方案,一般采用下面几种方式进行数据的填充:
  1. 以业务知识或经验推测填充缺省值
  2. 以同一字段指标的计算结果(均值、中位数、众数等)填充缺省值
  3. 以不同字段指标的计算结果来推测性的填充缺省值,比如通过身份证号码计算年龄、通过收货地址来推测家庭住址、通过访问的IP地址来推测家庭/公司/学校的家庭住址等等
  • 重新获取数据
    如果某些指标非常重要,但是缺失率有比较高,而且通过其它字段没法比较精准的计算出指标值的情况下,那么就需要和数据产生方(业务人员、数据收集人员等)沟通协商,是否可以通过其它的渠道获取相关的数据,也就是进行重新获取数据的操作。

(3)格式内容清洗
一般情况下,数据是由用户/访客产生的,也就有很大的可能性存在格式和内容上不一致的情况,所以在进行模型构建之前需要先进行数据的格式内容清洗操作。格式内容问题主要有以下几类:

  • 时间、日期、数值、半全角等显示格式不一致:直接将数据转换为一类格式即可,该问题一般出现在多个数据源整合的情况下。
  • 内容中有不该存在的字符:最典型的就是在头部、中间、尾部的空格等问题,这种情况下,需要以半自动校验加半人工方式来找出问题,并去除不需要的字符。
  • 内容与该字段应有的内容不符:比如姓名写成了性别、身份证号写成手机号等问题。

(4)逻辑错误清洗
主要是通过简单的逻辑推理发现数据中的问题数据,防止分析结果走偏,主要包含以下几个步骤:

  • 数据去重
  • 去除/替换不合理的值
  • 去除/重构不可靠的字段值(修改矛盾的内容)

(5)去除不需要的数据
一般情况下,我们会尽可能多的收集数据,但是不是所有的字段数据都是可以应用到模型构建过程的,也不是说将所有的字段属性都放到构建模型中,最终模型的效果就一定会好,实际上来讲,字段属性越多,模型的构建就会越慢,所以有时候可以考虑将不要的字段进行删除操作。在进行该过程的时候,要注意备份原始数据。
(6)关联性验证
如果数据有多个来源,那么有必要进行关联性验证,该过程常应用到多数据源合并的过程中,通过验证数据之间的关联性来选择比较正确的特征属性,比如:汽车的线下购买信息和电话客服问卷信息,两者之间可以通过姓名和手机号进行关联操作,匹配两者之间的车辆信息是否是同一辆,如果不是,那么就需要进行数据调整。

2、特征转换

特征转换主要指将原始数据中的字段数据进行转换操作,从而得到适合进行算法模型构建的输入数据(数值型数据),在这个过程中主要包括但不限于以下几种数据的处理:

  • 文本数据转换为数值型数据
  • 缺省值填充
  • 定性特征属性哑编码
  • 定量特征属性二值化
  • 特征标准化与归一化

机器学习的模型算法均要求输入的数据必须是数值型的,所以对于文本类型的特征属性,需要进行文本数据转换,也就是需要将文本数据转换为数值型数据。常用方式如下:

  • 词袋法(BOW/TF)
  • TF-IDF(Term frequency-inverse document frequency)
  • HashTF
词袋法

词袋法(Bag of words,BOW)是最早应用于NLP和IR领域的一种文本处理模型,该模型忽略文本的语法和语序,用一组无序的单词(words)来表达一段文字或者一个文档,词袋法中使用单词在文档中出现的次数(频数)来表示文档。
机器学习过程中的数据预处理和特征选择方法

词集法

词集法(Set of words,SOW)是词袋法的一种变种,应用的比较多,和词袋法的原理一样,是以文档中的单词来表示文档的一种的模型,区别在于:词袋法使用的是单词的频数,而在词集法中使用的是单词是否出现,如果出现赋值为1,否则为0。
机器学习过程中的数据预处理和特征选择方法

TF-IDF

在词袋法或者词集法中,使用的是单词的词频或者是否存在来进行表示文档特征,但是不同的单词在不同文档中出现的次数不同,而且有些单词仅仅在某一些文档中出现(例如专业名称等等),也就是说不同单词对于文本而言具有不同的重要性,那么,如何评估一个单词对于一个文本的重要性呢?
单词的重要性随着它在文本中出现的次数成正比增加,也就是单词的出现次数越多,该单词对于文本的重要性就越高。同时单词的重要性会随着在语料库中出现的频率成反比下降,也就是单词在语料库中出现的频率越高,表示该单词与常见,也就是该单词对于文本的重要性越低。
TF-IDF(Item frequency-inverse document frequency)是一种常用的用于信息检索与数据挖掘的常用加权技术,TF的意思是词频(Item Frequency),IDF的意思是逆向文件频率(Inverse Document Frequency)。TF-IDF可以反映语料中单词对文档/文本的重要程度。
假设单词用t表示,文档用d表示,语料库用D表示,那么N(t,D)表示包含单词t的文档数量,|D|表示文档数量,|d|表示文档d中的所有单词数量。N(t,d)表示在文档d中单词t出现的次数。
TFIDF(t,d,D)=TF(t,d)IDF(t,D)TF(t,d)=N(t,d)dIDF(t,D)=log(D+1N(t,D)+1) \begin{aligned} TFIDF(t, d, D)&=TF(t, d)*IDF(t, D) \\ TF(t, d)&=\frac{N(t, d)}{|d|} \\ IDF(t, D)&=\log(\frac{|D|+1}{N(t, D)+1}) \end{aligned}
TF-IDF除了使用默认的tf和idf公式外,tf和idf公式还可以使用一些扩展之后公式来进行指标的计算,常用的公式有:
机器学习过程中的数据预处理和特征选择方法
有两个文档,单词统计如下,请分别计算各个单词在文档中的TF-IDF值以及这些文档使用单词表示的特征向量。
机器学习过程中的数据预处理和特征选择方法

HashTF-IDF

不管是前面的词袋法还是TF-IDF,都避免不了计算文档中单词的词频,当文档数量比较少、单词数量比较少的时候,我们的计算量不会太大,但是当这个数量上升到一定程度的时候,程序的计算效率就会降低下去,这个时候可以通过HashTF的形式来解决该问题。HashTF的计算规则是:在计算过程中,不计算词频,而是计算单词进行hash后的hash值的数量(有的模型中可能存在正则化操作)。
HashTF的特点:运行速度快,但是无法获取高频词,有可能存在单词碰撞问题(hash值一样)。

Scikit-learn中进行文本特征提取

在Scikit-learn中,对于文本数据主要提供了三种方式将文本数据转换为数值型的特征向量,同时提供了一种对TF-IDF公式改版的公式。所有的转换方式均位于模块:sklearn.feature_extraction.text。

名称 描述
CountVectorizer 以词袋法的形式表示文档
HashingVectorizer 以HashingTF的模型来表示文档的特征向量
TfidfVectorizer 以TF-IDF的模型来表示文档的特征向量,等价于先做CountVectorizer,然后做TfidfTransformer转换操作的结果
TfidfTransformer 使用改进的TF-IDF公式对文档的特征向量矩阵(数值型的)进行重计算的操作,TFIDF=TF*(IDF+1)。备注:该转换常应用到CountVectorizer或者HashingVectorizer之后
Scikit-learn中进行缺省值填充

对于缺省的数据,在处理之前一定需要进行预处理操作,一般采用中位数、均值或者众数来进行填充,在Scikit-learn中主要通过Imputer类来实现对缺省值的填充。

哑编码

哑编码(OneHotEncoder):对于定性的数据(也就是分类的数据),可以采用N位的状态寄存器来对N个状态进行编码,每个状态都有一个独立的寄存器位,并且在任意状态下只有一位有效。哑编码是一种常用的将特征数字化的方式。比如有一个特征属性:[‘male’,‘female’],那么male使用向量[1,0]表示,female使用[0,1]表示。

二值化

二值化(Binarizer):对于定量的数据根据给定的阈值,将其进行转换,如果大于阈值,那么赋值为1;否则赋值为0。

标准化

标准化:基于特征属性的数据(也就是特征矩阵的列),获取均值和方差,然后将特征值转换至服从标准正态分布。计算公式如下:
x=xXS x'=\frac{x-\overline{X}}{S}

区间缩放法

区间缩放法:是指按照数据的方差特性对数据进行缩放操作,将数据缩放到给定区间上,常用的计算方式如下。
X_std=XX.minX.maxX.minX_scaled=X_std(maxmin)+min \begin{aligned} X\_std&=\frac{X-X.min}{X.max-X.min} \\ X\_scaled&=X\_std*(max-min)+min \end{aligned}

归一化

归一化:和标准化不同,归一化是基于矩阵的行进行数据处理,其目的是将矩阵的行均转换为“单位向量”,l2规则转换公式如下:
x=xj=1mx(j)2 x'=\frac{x}{\sqrt{\sum_{j=1}^mx(j)^2}}

数据多项式扩充变换

多项式数据变换主要是指基于输入的特征数据按照既定的多项式规则构建更多的输出特征属性,比如输入特征属性为[a,b],当设置degree为2的时候,那么输出的多项式特征为[1,a,b,a2,ab,b2][1, a, b, a^2, ab, b^2]

3、特征选择

当做完特征转换后,实际上可能会存在很多的特征属性,比如:多项式扩展转换、文本数据转换等等,但是太多的特征属性的存在可能会导致模型构建效率降低,同时模型的效果有可能会变的不好,那么这个时候就需要从这些特征属性中选择出影响最大的特征属性作为最后构建模型的特征属性列表。
在选择模型的过程中,通常从两方面来选择特征:

  • 特征是否发散:如果一个特征不发散,比如方差解决于0,也就是说这样的特征对于样本的区分没有什么作用
  • 特征与目标的相关性:如果与目标相关性比较高,应当优先选择

特征选择的方法主要有以下三种:

  • Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,从而选择特征;常用方法包括方差选择法、相关系数法、卡方检验、互信息法等
  • Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征或者排除若干特征;常用方法主要是递归特征消除法
  • Embedded:嵌入法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权重系数,根据系数从大到小选择特征;常用方法主要是基于惩罚项的特征选择法
方差选择法

先计算各个特征属性的方差值,然后根据阈值,获取方差大于阈值的特征。

相关系数法

先计算各个特征属性对于目标值的相关系数以及相关系数的P值,然后获取大于阈值的特征属性。

卡方检验

检查定性自变量对定性因变量的相关性:
χ2=(AE)2E \chi^2=\sum\frac{(A-E)^2}{E}

递归特征消除法

使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。

基于惩罚项的特征选择法

在使用惩罚项的基模型,除了可以筛选出特征外,同时还可以进行降维操作。

基于树模型的特征选择法

树模型中GBDT在构建的过程会对特征属性进行权重的给定,所以GBDT也可以应用在基模型中进行特征选择。

4、特征选取/降维

当特征选择完成后,可以直接可以进行训练模型了,但是可能由于特征矩阵过大,导致计算量比较大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了基于L1的惩罚模型外,还有主成分析法(PCA)和线性判别分析法(LDA),这两种方法的本质都是将原始数据映射到维度更低的样本空间中,但是采用的方式不同,PCA是为了让映射后的样本具有更大的发散性,LDA是为了让映射后的样本有最好的分类性能。

主成分分析(PCA)

将高维的特征向量合并成为低维度的特征属性,是
一种无监督的降维方法。

  • 二维到一维降维:
    机器学习过程中的数据预处理和特征选择方法
  • 多维情况—协方差矩阵:
    机器学习过程中的数据预处理和特征选择方法
    机器学习过程中的数据预处理和特征选择方法
线性判别分析(LDA)

LDA是一种基于分类模型进行特征属性合并的操作,是一种有监督的降维方法。
机器学习过程中的数据预处理和特征选择方法

5、异常数据处理

机器学习过程中的数据预处理和特征选择方法
机器学习过程中的数据预处理和特征选择方法
机器学习过程中的数据预处理和特征选择方法

6、自然语言处理

  • 自然语言处理:即实现人机间自然语言通信,或实现自然语言理解和自然语言生成。
  • 主要技术:汉字词法分析、句法分析、语义分析、文本生成、语言识别。
  • 应用场景:文本分类和聚类、信息检索和过滤、机器翻译。
  • Python中汉字分词包:jieba,Python开发的中文分词模块。
  • 分词:来把连续的汉字分隔成更具有语言语义学上意义的词。这个过程就叫做分词。
  • 分词的常见方法:
  1. 词典匹配:匹配方式可以从左到右,从右到左。对于匹配中遇到的多种分段可能性,通常会选取分隔出来词的数目最小的
  2. 基于统计的方法:隐马尔可夫模型(HMM)、最大熵模型(ME),估计相邻汉字之间的关联性,进而实现切分
  3. 基于深度学习:神经网络抽取特征、联合建模
Jieba分词原理
  • 字符串匹配:把汉字串与词典中的词条进行匹配,识别出一个词
  • 理解分词法:通过分词子系统、句法语义子系统、总控部分来模拟人对句子的理解
  • 统计分词法:建立大规模语料库,通过隐马尔可夫模型或其他模型训练,进行分词
Jieba分词使用
  • jieba分词模式:全模式:jieba.cut(str,cut_all=True),精确模式:jieba.cut(str),搜索引擎模式:jieba.cut_for_search(str)
  • 分词特征提取:返回TF/IDF权重最大的关键词,默认返回20个,jieba.analyse.extract_tags(str,topK=20)
  • 自定义词典:帮助切分一些无法识别的新词,加载词典jieba.load_userdict(‘dict.txt’)
  • 调整词典:add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。使用 suggest_freq(segment, tune=True) 可调节单个词语的词频