0%

《机学一》特征工程1 ——文本处理:sklearn抽取、jieba中文分词、TF和IDF抽取

详情请点阅读全文

零、机器学习整个实现过程:

机器学习整个实现过程

一、机器学习数据组成

  1. 特征值:
  2. 目标值:

    二、特征工程和文本特征提取

    1.概要:

    1、特征工程是什么
    2、特征工程的意义:直接影响预测结果
    3、scikit-learn库 介绍
    4、数据的特征抽取
    5、数据的特征预处理
    6、数据的降维

【特征工程】:特征工程是将原始数据转换为更好地代表预测模型的潜在问题的特征的过程,从而提高了对未知数据的预测准确性
(如图:文章转为数据即是一个特征工程)
文章转为数据即是一个特征工程

2.特征工程工具:

1、pandas:一个数据读取非常方便以及基本的处理格式的工具
2、sklearn:对于 特征的处理 提供了强大的接口,功能如下
在这里插入图片描述

2.1Python语言的机器学习工具:

  • Scikit-learn包括许多知名的【机器学习算法】的实现(使用前提:搞懂算法)
  • Scikit-learn文档完善,容易上手,丰富的API,使其在学术界颇受欢迎。

    2.2Scikit-learn安装

    安装前提:要有pandas、Numpy、等库
    中文文档:https://sklearn.apachecn.org/
    1
    2
    pip install Scikit-learn
    import sklearn

    2.3数据的特征抽取

特征抽取:特征抽取对文本等数据进行特征值化(把一篇文章转换成数值,就是一个特征抽取)
目的:为了计算机更好理解数据

1、特征抽取实例演示:一句话转化为,二维数组
2、sklearn特征抽取API:sklearn.feature_extraction(feature:特征。extraction:抽取)
3、字典特征抽取:

  • 作用:对字典数据进行特征值化
  • 类:sklearn.feature_extraction.DictVectorizer

4、文本特征抽取

2.33DictVectorizer语法

语法:DictVectorizer(sparse=True…)

DictVectorizer.fit_transform(X)

  • X:字典或者包含字典的迭代器
  • 返回值:返回sparse矩阵

DictVectorizer.inverse_transform(X)

  • X:array数 组或者sparse矩阵
  • 返回值:转换之前数据格式

DictVectorizer.get feature_names()

  • 返回类别名称

DictVectorizer.transform(X)

  • 按照原先的标准转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from sklearn.feature_extraction import DictVectorizer

def dictvec():
"""
功能:字典数据抽取
:return:None
"""
#1.实例化类DictVectorizer
dicts=DictVectorizer(sparse=False)
#2.调用fit_transform方法输入数据并转换注意返回格式
data=dicts.fit_transform([{'city': '北京','temperature': 100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature': 30}])
#3.get_feature_names()用法,获取
print(dicts.get_feature_names())
print(data)

if __name__=="__main__":
dictvec()

'''
DicVecorizer不加参数结果:
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
DicVecorizer加参数sparse=False返回:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]] 此处返回的叫one-hot编码
'''

【one-hot编码】:
One-hot编码用于把类别转换为数值如下:
在这里插入图片描述
为防止编号1,2,3,4….有优先级别之分,最终对结果造成影响one-hot编号转换成如下样式:
我们做的是为每个类别生成一个布尔列。这些列中只有- -列可以为每个样本取值1。
因此,术语才叫“一个热”编码。
在这里插入图片描述

2.34文本特征抽取

作用:对文本数据进行特征值化
类:sklearn.feature_extraction.text.CountVectorizer

CountVectorizer语法:

CountVectorizer(max_df=1.0,min_df=1,…)

  • 返回词频矩阵

CountVectorizer.fit_transform(X,y)

  • X:文本或者包含文本字符串的可迭代对象
  • 返回值:返回sparse矩阵

CountVectorizer.inverse_transform(X)

  • X:array数组或者sparse矩阵
  • 返回值:转换之前数据格式

CountVectorizer.get_feature_names()

  • 返回值:单词列表

2.35【英文处理】直接用fit_transform() 统计次数 特征化:

  1. 对文章当中所有的词,重复的只看做一 次词的列表。
  2. 对每篇文章,在词的列表里面进行统计每个词出现的次数
  3. 单个字母不统计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
def countvec():
"""
对文本进行特征值化
:return: None
"""
cv = CountVectorizer()
data = cv.fit_transform(["life is short,i like python","life is too long,i dislike python"])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__ == "__main__":
countvec()
'''
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
[[0 1 1 1 0 1 1 0]
[1 1 1 0 1 1 0 1]]
'''

2.36【中文处理】先jieba分词,再用fit_transform统计次数 特征化:

中文抽取必须要先进行分词处理。英文每个单词间都有空格,因此不用分词处理。中文只有加了空格才能像如下进代码行分词。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
def countvec():
"""
对文本进行特征值化
:return: None
"""
cv = CountVectorizer()
data = cv.fit_transform(["人生 苦短,我 喜欢 python", "人生漫长,不用 python"])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__ == "__main__":
countvec()
'''
结果:
['python', '不用', '人生', '人生漫长', '喜欢', '苦短']
[[1 0 1 0 1 1]
[1 1 0 1 0 0]]
'''

2.37中文分词处理库:jieba

安装:pip3 install jieba
返回值:词语生成器

1
2
3
4
5
6
7
import jieba
con0=jieba.cut('我是一个中国人')
<generator object Tokenizer.cut at 0x00000000066219A8> #返回值:词语生成器
#要想使用需要先转化成列表
con1=list(con0)
#再把列表组成字符串
c = ' '.join(con1)

2.38中文特征值化(抽取)统计词出现次数

首先用cutword()进行分词,然后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def cutword():
#jieba分词:分成一个个用空格隔开的词语
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")

# 先:转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)

# 再:把列表转换成字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
return c1, c2, c3

def hanzivec():
"""
中文特征值化
:return: None
"""
c1, c2, c3 = cutword()
print(c1, c2, c3)
cv = CountVectorizer()
data = cv.fit_transform([c1, c2, c3])
print(cv.get_feature_names())
print(data.toarray())
return None

if __name__=="__main__":
hanzivec()
"""
【打出分好的词看看】:
今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。 我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。 如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。
【特征值化(特征抽取)】:
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '这样']
[[0 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0]]
"""

3、词的重要程度:TF和IDF

常见文档分类原理:【朴素贝叶斯】

  1. 【TF-IDF的主要思想是】:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
  2. 【TF-IDF作用】:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
  3. 【TF-term frequency:词的频率】:词在当前文档出现频率
  4. 【★ IDF-inverse document frequency:逆文档频率】
    公式】: IDF = log ( 总文档数量 / 该词出现的文档数量 )
    【log(数值)】: 输入的数值越小,结果越小
  5. ★ 词在当前文档重要程度 = TF*IDF

【例如】:

  1. 因为、所以、我们、等等,这些词在每一篇文档可能都会出现但它对区分这篇文档类型并无作用;
  2. 可用公式计算该词在当前文档重要程度:TF*IDF

4.词重要程度(TF-IDF)sklearn工具库:

类:sklearn.feature_extraction.text.TfidfVectorizer

  • 【TfidfVectorizer作用】:分类机器学习算法的的重要依据
  • 【最新】:但目前TF-IDF已经比较过时,会有一些新的算法来代替它
    TfidfVectorizer语法:
    TfidfVectorizer(stop_words=None,…)
  • 返回词的权重矩阵
  • stop_words:忽略哪些词
  1. TfidfVectorizer.fit_transform(X,y)
    X:文本或者包含文本字符串的可迭代对象
    返回值:返回sparse矩阵
  2. TfidfVectorizer.inverse_transform(X)
    X:array数组或者sparse矩阵
    返回值:转换之前数据格式
  3. TfidfVectorizer.get_feature_names()
    返回值:单词列表

汉字语句计算词重要程度示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import jieba

def cutword():
# jieba分词:分成一个个用空格隔开的词语
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")

# 转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)

# 吧列表转换成字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)

return c1, c2, c3

def tfidfvec():
"""
中文特征值化
:return: None
"""
#调用汉字分词函数进行分词
c1, c2, c3 = cutword()
print(c1, c2, c3)

#特征化,并计算对应词重要程度
tf = TfidfVectorizer()
data = tf.fit_transform([c1, c2, c3])
print(tf.get_feature_names())
print(data.toarray())

return None

if __name__=="__main__":
tfidfvec()

"""结果:
今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。 我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。 如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。
=============================================
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '这样']
[[0. 0. 0.21821789 0. 0. 0.
0.43643578 0. 0. 0. 0. 0.
0.21821789 0. 0.21821789 0. 0. 0.
0. 0.21821789 0.21821789 0. 0.43643578 0.
0.21821789 0. 0.43643578 0.21821789 0. 0.
=============================================
返回:返回值是对应每个词的重要程度,数值越大,越重要,用的时候排个序即可
"""