当前位置:   article > 正文

文本数据处理_文本处理

文本处理

文本数据处理

文本数据处理常见任务

  • 文本分类
    文本分类是按照一定的分类体系,将文档判别为预定的若干类中的某一类或某几类。
  • 信息检索
    指将信息(此处指代文本)按一定的方式组织起来,根据用户的需求将相关信息查找出来
  • 信息抽取
    将文本中包含的结构化或非结构化的信息抽取出来,组成类似表格的形式
  • 自动问答
    用准确、简洁的自然语言回答用户以文本形式提出的问题
  • 机器翻译
    一种自然语言文本自动转换为另一种自然语言文本
  • 自动摘要
    从一份或多份文本中提取出来部分文字,它包含了原文本中的重要信息,且长度不超过或远小于原文本的一半

文本处理的基本步骤

Step1:文本采集
文本提取与整理
Step2:文本预处理
文本分词、去停用词、词性标注、样本标注
Step3:特征选择—>特征提取
Step4:建模分析(分类模型、CRF模型、RNN模型、LSTM模型)

文本预处理—中文分词

  • 词:最小的能够独立活动的有意义的语言成分
    英文单词之间以空格分界
    汉语以字为基本书写单位,词语之间没有明确的区分
  • 分词
    将连续的字序列按照一定的规范重新组合成词序列

Python分词库:jieiba库

  • 精确模式:将句子最精确地且分开,适合文本分析
  • 搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
  • 全模式:把句子中所有的可以成词的词语都扫描出来,速度快但不能解决歧义。

jieba中文分词函数

函数参数说明
lcut(sentence, cut_all= False, HMM= True)sentence:待分词的字符串;cut_all:是否采用全模式;HMM:是否使用HMM模型。直接返回词列表。适用于精确模式和全模式
lcut_for_search (sentence, HMM= True)sentence:待分词的字符串;HMM:是否使用 HMM 模型。直接返回词列表
cut(sentence, cut_all= False, HMM= True)等同于lcut()函数,但不会直接返回词列表,返回的是可迭代的generator。若想直接返回词列表,则需要做其他操作
cut_for_search (sentence, HMM= True)等同于lcut_for_search()函数,但不会直接返回词列表,返回的是可迭代的generator。若想直接返回词列表,则需要做其他操作
详见例题6-1

例题6-1:将文本句子 “2018年世界杯小组赛抽签在莫斯科克里姆林宫举行”进行分词

'''方式一:利用lcut()和lcut_for_search()函数'''
import jieba
print("精确模式切分为:\n",jieba.lcut("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行"))
print("搜索引擎模式切分为:\n",jieba.lcut_for_search("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行"))
print("全模式切分为:\n",jieba.lcut("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行",cut_all= True))
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

'''方式二:利用cut()和cut_for_search()函数,此处仅以精确模式为例'''
import jieba
words= jieba.cut_for_search("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行")
print(words)
for word in words:
	print(word)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

文本预处理—词性标注

jieba库的posseg模块提供词性标注from jieba import posseg as pseg
pseg.lcut()pseg.lcut_for_search()
等同于pseg.cutpseg.cut_for_search()

  • 词性:如名词、动词、形容词、代词等
利用cut()或cut_for_search()函数
from jieba import posseg as pseg
words= pseg.cut("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行")
for word, tag in words:
    print("word:{}, tag:{}".format(word, tag))
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

利用lcut()或lcut_for_search()函数
方式一:
from jieba import posseg as pseg
pseg.lcut("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行")
方式二:
from jieba import posseg as pseg
for word,tag in pseg.lcut("2018年世界杯小组赛抽签在莫斯科克里姆林宫据举行"):
    print("word:{},tag:{}".format(word,tag))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

方式一:
在这里插入图片描述
方式二:
在这里插入图片描述

特征选择与特征提取

  • 作用:将文本内容转换成数字特征向量
  • 有三种模型可供转换:
    词袋模型、TF-IDF模型、词向量模型--------本章只讲前两种模型
    在这里插入图片描述
词袋模型
  • 基本思想:
    将一条文本仅看作一些独立的词语的集合,忽略文本的词序、语法和句法。
    简单讲就是将每条文本都堪看成一个袋子,里面装的是词,成为词袋,分析时用词袋代表整个文本。
    词袋模型统计在一个句子中每个单词出现的频数

在这里插入图片描述

  • 词袋模型构建过程:
    对文档集进行分词—>构造字典—>生成词袋向量
  • 词袋模型实现
    sklean库中的feature_extraction.text模块的CountVectorizer类
    from sklearn.feature_extraction.text import CountVectorizer
    词袋模型初始化:
    cv= CountVectorizer(token_pattern, max_features)
    生成词袋向量
    cv_fit= cv.fit_transform(split_corpus)
    生成特征列表
    cv.get_feature_names()
    生成特征向量
    cv_fit.toarray()

参数说明如下:
在这里插入图片描述
例题6-2文本词袋特征生成。

from sklearn.feature_extraction.text import CountVectorizer
import jieba
'''给出文档集,放在字符串列表中'''
corpus= [
    '我是中国人,我爱中国',
    '我是上海人',
    '我住在上海松江大学城']

'''定义字符串空列表,用来存文档集中每个字符串的词袋'''
split_corpus= []

'''初始化分词结果的列表,循环为corpus中的每个字符串分词,即对文档集进行分词'''
for c in corpus:
    s= ' '.join(jieba.lcut(c))
    split_corpus.append(s)
print(split_corpus)

'''生成词袋'''
'''词袋模型初始化'''
cv= CountVectorizer()
'''构造字典生成词袋向量'''
cv_fit= cv.fit_transform(split_corpus)
'''显示特征列表'''
print(cv.get_feature_names())
'''显示特征向量'''
print(cv_fit.toarray())
  • 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

在这里插入图片描述

TF-IDF模型
  • 定义:
    “词频-逆文本频率”,是词袋模型的一个变种,区别是将词频值改为TF-IDF值,用于评估一个词对于一个文档的重要程度。
  • TF:词频
    某个词在文档中出现的次数或频率
    若某个词在某文档中出现多次,则说明这个词可能比较重要或者是文档常用词
  • IDF:逆文档频率
    计算方法:将文档集中总文档数量除以包含该词语的文档数量,再将得到的商取对数。
    DF主要用来取出文档常用词,如停用词的IDF值就会很低。
    TF-IDF:TF和IDF乘积
    作用:过滤到常见的词语,保留重要的词语。
  • TF-IDF模型构建过程
    对文档集进行分词—>构造字典—>生成TF-IDF向量
    注意:构建过程与词袋模型一致,唯一区别:在构造字典时,将词对应的词频改为TF-IDF值
    TF-IDF模型实现
    方法一
    sklearn库中的feature_extraction.text模块中的TfidfTransformer类。
    在词袋向量的基础上TfidTransformer类完成TF-IDF计算。
    from sklearn.feature_extraction.text import TfidfTransformer
    TF-IDF模型初始化
    tfidf= TfidfTransformer()
    生成TF-IDF向量
    tfidf_fit= tfidf.fit_transform(cv_fit)—cv_fit为ConubtVectiorizer类生成的词袋向量
    生成TF-IDF特征向量
    tfidf_fit.toarray()
    方法二
    sklearn库中的feature_extraction.text模块中的TfidfVectorizer类完成向量化、TF-IDF计算。
    from sklearn.feature_extraction.text import TfidfVectorizer
    TF-IDF模型初始化
    tfidf= TfidfVectorizer(token_pattern)------参数与词袋模型参数一样
    生成TF-IDF向量
    tfidf_fit= tfidf.fit_transform(split_corpus)
    生成TF-IDF特征向量
    tfidf_fit.toarray()

方法一:feature_extraction.text模块的TfidfTransformer类

import jieba
'''给出文档集,放在字符串列表中'''
corpus= [
    '我是中国人,我爱中国',
    '我是上海人',
    '我住在上海松江大学城']

'''定义字符串空列表,用来存文档集中每个字符串的词袋'''
split_corpus= []

'''初始化分词结果的列表,循环为corpus中的每个字符串分词,即对文档集进行分词'''
for c in corpus:
    s= ' '.join(jieba.lcut(c))
    split_corpus.append(s)
print(split_corpus)
'''生成词袋'''
'''词袋模型初始化'''
from sklearn.feature_extraction.text import CountVectorizer
#(?u)\b\w\w+\b为其默认参数
cv= CountVectorizer(token_pattern= r"(?u)\b\w\w+\b")
'''构造字典生成词袋向量'''
cv_fit= cv.fit_transform(split_corpus)

'''在例题6-2后加如下代码即可变为TF-IDF模型'''
from sklearn.feature_extraction.text import TfidfTransformer
'''TF-IDF模型初始化'''
tfidf_transformer= TfidfTransformer()
'''生成TF-IDF向量'''
tfidf_fit= tfidf_transformer.fit_transform(cv_fit)
'''显示TF-IDF特征向量'''
print(tfidf_fit.toarray())
  • 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

在这里插入图片描述
方法二:直接用分词后得到的列表计算TF-IDF特征表示

import jieba
'''给出文档集,放在字符串列表中'''
corpus= [
    '我是中国人,我爱中国',
    '我是上海人',
    '我住在上海松江大学城']

'''定义字符串空列表,用来存文档集中每个字符串的词袋'''
split_corpus= []

'''初始化分词结果的列表,循环为corpus中的每个字符串分词,即对文档集进行分词'''
for c in corpus:
    s= ' '.join(jieba.lcut(c))
    split_corpus.append(s)
print(split_corpus)
print('-----------------------')
from sklearn.feature_extraction.text import TfidfVectorizer
'''TF-IDF模型初始化'''
tfidf= TfidfVectorizer(token_pattern= r"(?u)\b\w\w+\b")
'''生成TF-IDF向量'''
tfidf_fit= tfidf.fit_transform(split_corpus)
'''显示特征向量'''
print(tfidf_fit.toarray())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述

思考与练习1

在例6-2的文档集中添加2条文本,“松江大学城有很多大学”、“大学城共有15万余大学生”。计算文档集中每条文本的词袋和TF-IDF特征表示。
方法一:feature_extraction.text模块的TfidfTransformer类

import jieba
from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
corpus= [
    '我是中国人,我爱中国',
    '我是上海人',
    '我住在上海松江大学城',
    '松江大学城有很多大学',
    '大学城共有15万余大学生']
split_corpus= []
for c in corpus:
        s= " ".join(jieba.lcut(c))
        split_corpus.append(s)
print("每条文本的词袋为:\n",split_corpus)
print('-------------------------------------------------------------')
from sklearn.feature_extraction.text import CountVectorizer
cv= CountVectorizer(token_pattern= r"(?u)\b\w\w+\b")
cv_fit= cv.fit_transform(split_corpus)
print("词袋模型的特征列表为:\n",cv.get_feature_names())
print("词袋模型的特征向量为:\n",cv_fit.toarray())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer= TfidfTransformer()
tfidf_fit= tfidf_transformer.fit_transform(cv_fit)
'''显示TF-IDF的特征向量'''
print(tfidf_fit.toarray())
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
方法二:直接用分词后得到的列表计算TF-IDF特征表示

'''方式二'''
import jieba 
from sklearn.feature_extraction.text import TfidfVectorizer
corpus= [
    '我是中国人,我爱中国',
    '我是上海人',
    '我住在上海松江大学城',
    '松江大学城有很多大学',
    '大学城共有15万余大学生']
split_corpus= []
for c in corpus:
    s= " ".join(jieba.lcut(c))
    split_corpus.append(s)
print(split_corpus)
print('----------------------------------------------------------')
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf= TfidfVectorizer(token_pattern= r"(?u)\b\w\w+\b")
tfidf_fit= tfidf.fit_transform(split_corpus)
'''显示TF-IDF特征向量'''
print(tfidf_fit.toarray())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

垃圾邮件识别—此处利用分类算法中的SVM模型

  • 垃圾邮件识别技术
    关键词识别
    IP黑名单
    反向DNS查找
    意图分析技术链接URL
    分类算法(最常见)等
分类算法进行垃圾邮件识别
  • 实现步骤:
    收集大量的垃圾邮件和非垃圾邮件
    建立垃圾邮件库和非垃圾邮件库
    提取其中的特征
    训练分类模型

在这里插入图片描述
在这里插入图片描述

  • 使用词袋模型或TF-IDF模型提取特征
    得到m*n的矩阵X。m为10000,n为文本集的字典词条数目
    标签向量y长度为m,元素值为0或1
import jieba
#从文本中读取文本,放在列表中
mail= open('E:\data\mailcorpus.txt', 'r', encoding= 'utf-8')
corpus= mail.readlines()#列表中的每个元素为一行文本
split_corpus= []
for c in corpus:
    s= " ".join(jieba.lcut(c))
    split_corpus.append(s)
from sklearn.feature_extraction.text import CountVectorizer
cv= CountVectorizer()
X= cv.fit_transform(split_corpus).toarray()
'''
等同于:
cv_fit= cv.fit_transform(split_corpus)
X= cv_fit.toarray()
'''
#构造标签向量,垃圾标签为0,正常标签为1
y= [0]*5000+[1]*5000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
#将数据集切分为训练集和测试集
from sklearn import model_selection
from sklearn import svm
from sklearn import metrics
X_train, X_test, y_train, y_test= model_selection.train_test_split(X, y, test_size= 0.4, random_state= 0)

#使用SVM训练分类器模型
#利用高斯核函数,并设置其系数为0.7,误差项的惩罚参数为1
svm= svm.SVC(kernel= 'rbf', gamma= 0.7, C= 1.0)
svm.fit(X_train, y_train)
#测试集模型预测
predicted_ytest= svm.predict(X_test)
#测试集的准确率
print("SVM accuracy:\n", svm.score(X_test, y_test))
#SVM分类性能报告
print("SVM report:\n", metrics.classification_report(y_test, predicted_ytest))
#SVM混淆矩阵计算
print("SVM matrix:\n",mean.confusion_matrix(y_test,predicted_ytest))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

思考与练习2

第一题:将邮件特征提取从词袋模型改为TF-IDF模型,比较使用不同的特征计算模型的分类性能。

import jieba
mail= open('E:\data\mailcorpus.txt', 'r', encoding= 'utf-8')
corpus= mail.readlines()
split_corpus= []
for c in corpus:
    s= " ".join(jieba.lcut(c))
    split_corpus.append(s)
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf= TfidfVectorizer(token_pattern= r"(?u)\b\w+\b")
tfidf_fit= tfidf.fit_transform(split_corpus)
X= tfidf_fit.toarray()
y= [0]*5000+[1]*5000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
from sklearn import model_selection, metrics, svm

X_train, X_test, y_train, y_test= model_selection.train_test_split(X, y, test_size= 0.4, random_state= 0)
svm= svm.SVC(kernel= 'rbf', gamma= 0.7, C= 1.0)
svm.fit(X_train, y_train)
predicted_ytest= svm.predict(X_test)
print("SVM accuracy:\n",svm.score(X_test, y_test))
print("SVM report:\n",metrics.classification_report(y_test, predicted_ytest))
print("SVM matrix:\n", metrics.confusion_matrix(y_test, predicted_ytest))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
第二题:使用Scikit-learn的CountVectorizer()函数初始化词袋模型时,设置不同的特征个数生成邮件的特征表示向量,比较训练分类模型所耗费的时间,以及分类模型分类的准确性。特征个数越多是否意味分类性能越好?

import jieba
from sklearn import metrics,svm,model_selection

def svmm(a,b):
    X_train, X_test, y_train, y_test= model_selection.train_test_split(a, b, test_size= 0.7, random_state= 0)
    svm= svm.SVC(kernel= 'rbf', gamma= 0.7, C= 1.0)
    svm.fit(X_train, y_train)
    predicted_ytest= svm.predict(X_train)
    print("SVM accuracy:\n",svm.score(X_test, y_test))
    print("SVM report:\n",metrics.classification_report(y_test, predicted_ytest))
    print("SVM matrix:\n", metrics.confusion_matrix(y_test, predicted_ytest))
    return

mail= open('E:\data\mailcorpus.txt', 'r', encoding= 'utf-8')
corpus= mail.readlines()
split_corpus= []
for c in corpus:
    s= " ".join(jieba.lcut(c))
    split_corpus.append(s)
from sklearn.feature_extraction.text import CountVectorizer
cv= CountVectorizer(token_pattern= r"(?u)\b\w+\b")
cv_fit= cv.fit_transform(split_corpus)
for i in range(500,10000,500):
    X= cv_fit.toarray()[0:i]
    y= [0]*i+[1]*i
    svmm(X, y)
  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/372635
推荐阅读
相关标签
  

闽ICP备14008679号