【机器学习知识整理二】处理分类数据、处理文本、处理日期和时间

系列文章目录

上一篇:机器学习知识整理一:数据加载、数据整理、数值型数据处理



前言

提示:参考资料《Python机器学习手册-从数据预处理到深度学习》以及从网上查找的其他资料

主要内容:处理分类数据、处理文本


一、处理分类数据

这里的分类是针对某一个特征来说的,一个特征可能会被分成几类。比如有一列特征是颜色,颜色可以分为很多类:赤、橙、黄、绿、青、蓝、紫。

1. 对nominal型分类特征编码

什么是nominal型分类特征?

本身没有内在顺序的类别称为nominal。比如颜色:蓝色、红色、橙色,这种特征分类没有内在顺序。

处理nominal型分类特征,需要对特征进行one-hot编码(独热编码),one-hot编码是什么?资料中是这样解释的:
为原特征中的每一个分类都创建一个二元特征,这个方法被称为One-hot编码。

举个例子解释下,假设有一个特征为水果,如下:

水果价格
苹果5
6
橘子7

在对其进行one-hot编码之后,会对水果特征进行分类,分成苹果、梨、橘子三个特征,就变为下表中的样子:

苹果橘子价格
1005
0106
0017

从上面的例子可以看出one-hot编码把一个特征分成了n个特征(二元特征),这些特征的值是0或1。至此对one-hot编码有了一个基本认识。

书中有这样一句话值得思考:值得注意的是,在one-hot编码之后,最好从结果矩阵中删除一个one-hot编码的特征,以避免线性依赖[P86]。这里为什么要删掉一个one-hot编码特征呢?线性依赖又有着什么含义?这里需要探索一下。

代码参考:nominal处理-demo_5_1

2. 对ordinal分类特征编码

本身存在内在顺序的类别称为ordinal。比如:高、中、低,这种分类天然就有内在的顺序。

这种特征的解决方法是对其进行替换映射。

举个例子来说:假设有一个特征为成绩,如下:

成绩
High
High
Medium
Low

从上面的表格中可以看出,成绩其实是有内在顺序的:高、中、低,我们可以对高中低进行数字映射,高-3, 中-2,低-1。进行特征映射之后,变为下表中的样子:

成绩
3
3
2
1

这儿要注意的一点是,针对以上的高、中、低,还比较方便映射数字,如果成绩还有一类是位于高和中之间,这种分类之间的间隔不相等的情况怎么映射数据?设置位于高和中之间-2.5还是映射成其他值,这个就需要留意了。

代码参考:ordinal处理-demo_5_2

3. 对特征字典编码

对特征字典编码做的工作就是将一个字典转换成一个特征矩阵,有助于节省内存。

机器学习算法要求数据是矩阵的形式。

这里有两个概念需要了解下:稀疏矩阵和稠密矩阵。

稀疏矩阵:就是数值为0的元素远多于非0元素的矩阵是系数矩阵。

稠密矩阵:相对稀疏矩阵,非0元素个数远多于数值为0元素的个数的矩阵是稠密矩阵。

怎么界定为0元素和非0元素的多与少,暂时还没有了解。

代码参考:对特征字典编码-demo_5_3

4. 填充缺失的分类值

如果分类特征中包含缺失值,需要用预测值来填充。

有两种方法来填充缺失值:

方法一:利用机器学习算法预测缺失值,将带缺失值的特征作为目标向量,将其他特征作为特征矩阵,实现完成预测。常用的是KNN分类器。

方法二:就是把这个特征中出现次数最多的分类来填充缺失值。

两种方法都最好再创建一个二元特征来标识观察值中是否包含填充值。

代码参考:填充缺失的分类值-demo_5_4

5. 处理不均衡分类

处理极度不均衡分类的目的是什么呢?书中给出了一个例子:假设有一个样本是关于罕见癌症的,正常样本和癌症样本比例差别很大,就当作10000:1,根据这个样本数据训练出的模型预测没有人会得这个癌症的准确率能达到99.5%,但这不是我们想要的结果。就是说样本分类比例对模型训练会有很大影响。

处理不均衡分类常用的方法:

  1. 收集更多的观察值
    尤其是占少数的分类的观察值,但是通常情况下这是很难做到的。

  2. 选择有分类权重参数的模型
    比如随机森林分类器,带有一个权重参数class_weight
    假设有一个样本特征分类情况为0占了0.1,1占了0.9,那么在随机森林分类器中可以通过加权weights = {0: 0.9, 1: 0.1},让类别为0的权重加上0.9到达1,让类别为1的权重加上0.1到达1,以此抵消分类数据不均衡带来的影响。

  3. 下采样
    原理:从占多数的分类中随机抽取观察值,使得抽出来的观察值数量等于占少数的分类的观察值的数量。

  4. 上采样
    原理:从占少数的分类中随机抽取观察值,重复采样,使得抽出来的观察值数量等于占多数的分类的观察值的数量。

代码参考:处理不均衡分类-demo_5_5

二、处理文本

1. 清洗文本

大部分文本数据在被用于特征生成之前都需要进行清洗,比如去除空格、字符串替换、删除特定字符等等。这些清洗操作一般使用python的字符串操作就可以搞定,有时可能需要根据自己的需求对文本进行特定的操作,需要自己写自定义的清洗函数。

代码参考:清洗文本-demo_6_1

2. 解析并清洗HTML

做过爬虫的话,应该都知道python有一个处理HTML文档的库BeautifulSoup,专门用于解析html。功能还是很强大的。这儿给出简单的代码

参考样例:解析并清洗HTML-demo_6_2,后续再对BeautifulSoup的详细使用做下总结。

3. 移除标点

在创建特征的时候难免要删除标点,删除标点的方法不止一种,书中给出的例子是使用translate函数将标点转换为None达到移除标点的目的。

代码参考:移除标点-demo_6_3

4. 文本分词

将文本分离成独立的单词。用到了python的自然语言工具集NLTK, Natural Language Toolkit。

代码参考:文本分词-demo_6_4

如果使用NLTK报错:Resource punkt not found.,可以参考:Resource punkt not found

5. 删除停止词

停止词指的是非常常见但包含的信息又很少的单词。

代码参考:删除停止词-demo_6_5

6. 提取词干

词干提取能识别出一个单词的词缀并将其删除,例如ing, ional等,提取词干后,单词的可读性会变差,不过更接近它的基本意思,因此更适合用于做比较。

代码参考:提取词干-demo_6_6

7. 标注词性

将单词的词性标注出来,比如名词、副词、过去式的动词等。使用NLTK中的Penn Treebank的词性标签进行标注。部分标签例子如下:

标签词性
NNP单数专有名词
NN单数或复数的名词
RB副词
VBD过去式的动词
VBG动名词或动词的现在分词形式
JJ形容词
PRP人称代词

代码参考:标注词性-demo_6_7

8. 将文本编码成词袋

词袋可以理解为有一个特征表,每个特征都是一个单词,记录了每个单词在观察值中的出现次数。

代码参考:将文本编码成词袋-demo_6_8

9. 按单词的重要性加权

理解几个概念:

词频(term frequency, tf):单词在文档中出现的次数。一个词在文档中出现的次数越多,它对这个文档就越重要。

文档频率(document frequency, df):单词出现在多少个文档中。

逆向文档频率(inverse of document frequency, idf):用于计算TF-IDF。

TF-IDF(term frequency-inverse document frequency): 将一个词在某个文档中出现次数和这个词在所有文档中的出现次数进行对比,用于衡量单词对文档的重要性。

将tf和df结合起来,为每个单词确定一个分数,来表示它在某个文档中的重要程度。计算公式如下:

在这里插入图片描述
t表示单词,d表示文档。
在scikit-learn中,idf计算公式如下:
idf计算公式

n d n_d nd是文档的数量, d f ( d , t ) df(d,t) df(d,t)是单词 t t t的文档频率(也就是单词在多少份文档中出现过)。

默认情况下,scikit-learn会使用欧式范数将TF-IDF向量归一化,得到的结果值越大,这个单词对一个文档来说就越重要。

代码参考:按单词的重要性加权-demo_6_9

三、处理日期和时间

1. 把字符串转换成日期

python中有许多工具能将字符串转换成datetime类型,代码例子中使用的是pandas的to_datetime执行转换。

pd.to_datetime(datestr, format='%d-%m-%Y %I:%M %p')

其中format指定了字符串的具体格式,常用的日期和时间的格式化代码:

代码描述例子
%Y完整的年份2022
%m月,首位空缺时需用0填充01
%d日,首位空缺时需用0填充01
%I小时,首位空缺时需用0填充01
%pAM-上午或PM-下午AM
%M分,首位空缺时需用0填充01
%S秒,首位空缺时需用0填充01

把字符串转成日期

代码参考:把字符串转换成日期-demo_7_1

2. 处理时区

设置时区

代码参考:处理时区-demo_7_2

3. 选择日期和时间

使用布尔条件或者索引筛选两个时间段之间的时间记录。
筛选时间

代码参考:选择日期和时间-demo_7_3

4. 将日期数据切分成多个特征

按需要对日期数据进行特征拆分。
将日期数据切分成多个特征

代码参考:将日期数据切分成多个特征-demo_7_4

5. 计算两个日期之间的时间差

计算时间间隔也是常有的情况,所以直接看例子,用到的时候直接借鉴。

计算两个日期之间的时间差

代码参考:计算两个日期之间的时间差-demo_7_5

6. 对一周内的各天进行编码

计算某一天是星期几。
对一周内的各天进行编码

代码参考:对一周内的各天进行编码-demo_7_6

7. 创建一个滞后的特征

创建一个滞后的特征,使用场景:使用历史数据做预测。
创建一个滞后的特征

代码参考:创建一个之后的特征-demo_7_7

8. 使用滚动时间窗口

滚动时间窗口:窗口宽度是固定的,假设窗口宽度是3天,窗口每往前滚动1天,就对窗口内的数据做一次处理。所有窗口移动后处理的数据是很有用的。

下图设置的时间滚动窗口为2:

使用滚动时间窗口

代码参考:使用滚动时间窗口-demo_7_8

9. 处理时间序列中的缺失值

方法一:插值法

插值法的原理,就是利用缺口前后的数据画一条直线或者曲线,利用这条线预测应该插入什么值比较合理。举个例子:缺口的前一个值是2,缺口的后一个值是5,画一条从2到5的线,缺口处的合理值就是3和4。

方法二:向前填充

向前填充就是把缺口前面的值拿过来填充上。

方法二:向后填充

向后填充就是把缺口后面的值拿来填充上。

处理时间序列中的缺失值

代码参考:处理时间序列中的缺失值-demo_7_9


四、总结

1、了解了如何处理数据分类。刚开始还很疑惑:为什么要把特征分类给转换为数字,比如nominal型分类拆成多个0/1二元特征,ordinal分类要映射成具体的数字,后来看到书中有这么一句话:分类信息常常用一个字符串型的向量或列表示(例如:高、中、低),但大部分机器学习算法都要求其输入是数值型的数据。才恍然大悟原来是这样。

2、了解了处理文本的方法。

3、了解了机器学习中对时间的处理方法。

  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值