机器学习-多项式朴素贝叶斯的应用

2020-12-16  本文已影响0人  今天也是努力的小张

引言:多项式朴素贝叶斯最适合的场景就是文本分类、情感分析和垃圾邮件识别。其中情感分析和垃圾邮件识别都是通过文本来进行判新。但是文本数据通常为英文或者中文字符串,如何提取和表示该类数据的特征呢?

1. sklearn的CountVectorize工具
2. 结巴分词
3. TF-IDF
4. 可视化——词云

一、文本特征提取

对于文本数据,通常使用文本中每个词出现的次数作为其特征。此时就需要处理。

1. 分词

对每个文本进行分词(英文分词简单,有空格作为分界线,中文分词需要借助专门的分词技术)

2. 词频向量化

获取文本数据集的特征矩阵,需要词频向量化(在分词之后,通过统计每个词在文本中出现的次数,我们就可以得到该文本基于词的特征,如果将各个文本样本的这些词与对应的词频放在一起,就是我们常说的向量化)

3. 分类

将词频向量矩阵作为特征,然后利用朴素贝叶斯进行分类。
注意:不同文本数据的长度是不同的,因此还需要将不同文本数据的特征转换为同一长度。

4. 词袋模型(Bag of words,简称BoW)

词袋模型(Bag of words,简称BoW)
词袋模型假设我们不考虑文本中词与词之间的上下文关系,仅仅只考虑所有词的权重。而权重与词在文本中出现的频率有关。

二、文本词频向量化

在sklearn中,可以使用CountVectorize工具进行英文分词和向量化,他可以将文本中的词语转换为词频矩阵。(根据空格或符号进行分词)
导入from sklearn.feature_extraction.text import CountVectorizer
实例化cnt_Vect = CountVectorizer(stop_words=["is"], min_df=2) # 实例化
常用参数:
stop_words 停用词,文本中无意义的词、不想被分的词可以放在里面,例如is、the等
min_df:某些词在不同行中的出现的次数大于n
ngram_range:默认(1, 1),下限是1,上限是1,最少多少个连续的字或者词作为一个整体
方法:
cnt_Vect.fit_transform():计算各个词出现的次数
cnt_Vect.get_feature_names():获取词袋中所有文本的关键字
toarray():看到词频矩阵的结果
注意:一个字母不算词
简单代码示例:

# 词频向量化
from sklearn.feature_extraction.text import CountVectorizer

text = ['This is the first document. a ',
        'This document is the second document.',
        'And this is the third one.',
        'Is this the first document?', ]
# 实例化
# cnt_Vect = CountVectorizer(stop_words=["is"], min_df=2)  # 实例化
cnt_Vect = CountVectorizer(stop_words=["is"])  # 实例化
# 拟合
cnt_Vect.fit(text) 
# 转换
out = cnt_Vect.transform(text)
# print(out, type(out))  # 稀疏矩阵
# 将系数矩阵转换为数组
out = out.toarray()
print(out)
# 关键词
print(cnt_Vect.get_feature_names())  
部分结果展示

三、中文文本向量化——结巴分词

1. 结巴分词是第三方库,需要下载:pip install jieba

2. 结巴分词有三种模式

import jieba

# 分词三种模型

# 参数1:字符串
# 参数2:cut_all="True" 全模型,False 精准模型
str1 = "上海自来水来自海上"
str2 = "我想过过过过儿过过的生活"
str3 = "开开心心,快快乐乐"

text = [str1, str2, str3]

# 精准模型 试图将句子最精准地切开,适合文本分析
# out = jieba.cut(str1, cut_all=False)
out = jieba.cut(str3, cut_all=False)
print(list(out))
# 全模式 不考虑句子含义,切出所有的词语。速度快,不能解决歧义问题
out = jieba.cut(str3, cut_all=True)
print(list(out))
# 搜索引擎模式。在精准模式的基础上,对长词再次切分,提高召回率,使用用于搜索引擎
out = jieba.cut_for_search(str3)
print(list(out))
结果展示

3. 结巴分词的主要作用是将一个句子分成一个一个的词语(字符串),和CountVectorizer结合使用可以实现汉字的文本特征词频向量化

简单代码示例

# 词频向量化
from sklearn.feature_extraction.text import CountVectorizer
import jieba

text = [
    "张三看到李四在抽烟",
    "李四看到张三在抽烟"
]

text_split = []
for tmp in text:
    out = jieba.cut(tmp, cut_all=False)  # 精准模式
    out = " ".join(list(out))
    # print(out)
    text_split.append(out)

print("分词结束\n", text_split)

cnt_Vect = CountVectorizer()  # 实例化
cnt_Vect.fit(text_split)  # 拟合

out = cnt_Vect.transform(text_split)  # 转换
print(out, type(out))  # 稀疏矩阵
# 将系数矩阵转换为数组
out = out.toarray()
print(out)
print(cnt_Vect.get_feature_names())  # 关键词

四、TF-IDF

1. TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。

TF-IDF (Term Frequency-Inverse Document Frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上是:TF*IDF
有些词在文本中尽管词频高,但是并不重要,这个时候就可以用TF-IDF技术。

2. TF-IDF的实现方法

# 词频向量化
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
# 4条评论
text = ['This is the first document. a ',
        'This document is the second document.',
        'And this is the third one.',
        'Is this the first document?', ]

# 方法一:先CountVectorizer在进行转换
cnt = CountVectorizer()
cnt.fit(text)
text_mat = cnt.transform(text).toarray()
print("关键词\n", cnt.get_feature_names())
print("text_mat\n", text_mat)

tf_idf = TfidfTransformer()
# 词重要性
text_important = tf_idf.fit_transform(text_mat).toarray()
print("text_important\n", text_important)
print("text_important\n", text_important.shape)


# 方法二
tf_idf2 = TfidfVectorizer()
tf_idf2.fit(text)
text_important2 = tf_idf2.transform(text)
print(tf_idf2.get_feature_names())
print("text_important2\n", text_important2.toarray())

两种方法的效果一模一样

上一篇 下一篇

猜你喜欢

热点阅读