文本数据处理

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

⽂本数据处理
涉及:
⽂本数据的特征提取
中⽂⽂本的分词⽅法
⽤n-Garm模型优化⽂本数据
使⽤tf-idf模型改善特征提取
删除停⽤词
1.使⽤CountVectorizer对⽂本进⾏特征提取
前⾯,⽤来展⽰的数据特征分为:
1. ⽤来表⽰数值的连续特征
2. 表⽰样本所在分类的类型特征
第三种数据类型:⽂本数据
⽂本数据在计算机中往往被存储为字符串类型(String)
中⽂的处理相⽐较英⽂很难,因为在⼀个句⼦中,中⽂的词与词不像英⽂有空格作为分界线——处理中⽂时,先进⾏分词处理如句⼦“The quick brown fos jumps over a lazy dog”:
#导⼊向量化⼯具CountVectorizer
from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer()
#拟合⽂本数据
en = ['The quick brown fos jumps over a lazy dog']
vect.fit(en)
print('单词数:',len(vect.vocabulary_))
print('分词:',vect.vocabulary_)
单词数: 8
分词: {'the': 7, 'quick': 6, 'brown': 0, 'fos': 2, 'jumps': 3, 'over': 5, 'lazy': 4, 'dog': 1}
【结果分析】
'a' 是冠词,没被程序作为⼀个单词
中⽂:
#使⽤中⽂⽂本进⾏实验
cn = ['那只敏捷的棕⾊狐狸跳过了⼀只懒惰的狗']
#拟合中⽂数据
vect.fit(cn)
print('单词数:',len(vect.vocabulary_))
print('分词:',vect.vocabulary_)
单词数: 1
分词: {'那只敏捷的棕⾊狐狸跳过了⼀只懒惰的狗': 0}
【结果分析】
程序⽆法对中⽂语句进⾏分词(没有空格)
2.使⽤分词⼯具对中⽂⽂本进⾏分词
pip install jieba 安装结巴分词
#导⼊结巴分词
import jieba
#对中⽂⽂本分词
cn = jieba.cut('那只敏捷的棕⾊狐狸跳过了⼀只懒惰的狗')
#实验空格‘ ’作为词与词的分界线
cn = [''.join(cn)]
print(cn)
【结果分析】
红底⿊字是“结巴分词”导⼊词典和建⽴模型的信息
分词完成,接着进⾏特征提取:
#使⽤CountVectorizer对中⽂⽂本进⾏向量化
vect.fit(cn)
print('单词数:',len(vect.vocabulary_))
print('分词:',vect.vocabulary_)
单词数: 6
分词: {'敏捷': 2, '棕⾊': 3, '狐狸': 4, '跳过': 5, '⼀只': 0, '懒惰': 1}
【结果分析】
CountVectorizer已经可以从中⽂⽂本中提取若⼲个整型数值,并且⽣成了⼀个字典
接下来,使⽤这个字典将⽂本的特征表达出来,以便训练模型:
3.使⽤词袋模型将⽂本数据转为数组
上⾯的实验中,CountVectorizer给每个词编码为0-5的整型数,结果这样的处理,可以⽤⼀个稀疏矩阵对这个⽂本数据进⾏表⽰#定义词袋模型
bag_of_words = vect.transform(cn)
#打印词袋模型中的数据特征
print('转化为词袋的特征:',repr(bag_of_words))
转化为词袋的特征: <1x6 sparse matrix of type '<class 'numpy.int64'>'
with 6 stored elements in Compressed Sparse Row format>
【结果分析】
原来的语句,被转化成⼀个1⾏16列的稀疏矩阵,类型为64位整型数值,其中有6个元素
6个元素都是什么?
#打印词袋模型的密度表达
print(bag_of_words.toarray())
[[1 1 1 1 1 1]]
换⼀句话看看结果有啥不同:
#输⼊新的中⽂⽂本
cn_1 = jieba.cut('懒惰的狐狸不如敏捷的狐狸敏捷,敏捷的狐狸不如懒惰的狐狸懒惰')
cn2 = [''.join(cn_1)]
print(cn2)
['懒惰的狐狸不如敏捷的狐狸敏捷,敏捷的狐狸不如懒惰的狐狸懒惰']
#建⽴新的词袋模型
new_bag = vect.transform(cn2)
#打印词袋中的数据特征
print('转化为词袋的特征:',repr(new_bag))
#打印词袋的密度表达
print(new_bag.toarray())
转化为词袋的特征: <1x6 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in Compressed Sparse Row format>
[[0 3 3 0 4 0]]
上⽽这种⽤数组表⽰⼀句话中单词出现次数的⽅法,被称为“词袋模型 "
这种⽅法是忽略⼀个⽂本中的词序和语法,仅仅将它看作个词的集合
这种⽅法对于⾃然语⾔进⾏了简化,以便于机器可以读取井进⾏模型的训练
但模型也具有⼀定的局限性
对⽂本类型数据的进⼀步优化处理
1. 使⽤n_Gram算法改善词袋模型
词袋模型劣势——把句⼦看作单词的简单集合,忽略单词的顺序
⽐如:
#随便写
joke = jieba.cut('道⼠看见和尚吻了尼姑的嘴唇')
joke = [''.join(joke)]
#转化为向量
vect.fit(joke)
joke_feature = vect.transform(joke)
#打印⽂本数据特征
print(joke_feature.toarray())
[[1 1 1 1 1]]
顺序打乱:
#将刚才的⽂本打乱
joke2 = jieba.cut('尼姑看见道⼠的嘴唇亲吻了和尚')
joke2 = [''.join(joke2)]
#转化为向量
vect.fit(joke2)
joke2_feature = vect.transform(joke2)
#打印⽂本数据特征
print(joke2_feature.toarray())
[[1 1 1 1 1 1]]
【结果分析】
对于机器来说,意思⼀模⼀样
在CountVectorize 中调节n-Gram函数:
#修改CountVectorizer的ngram参数
vect = CountVectorizer(ngram_range=(2,2))
#重新进⾏⽂本数据的特征提取
cv = vect.fit(joke)
joke_feature = cv.transform(joke)
print('调整ngram参数后的词典:',cv.get_feature_names())
print('新的特征表达:',joke_feature.toarray())
调整ngram参数后的词典: ['和尚尼姑', '尼姑嘴唇', '看见和尚', '道⼠看见']
新的特征表达: [[1 1 1 1]]
【结果分析】
将CountVectorizer的ngram_range参数调节为(2,2),意思是,进⾏组合的单词数量下线是2,上线也是2【即限制CountVectorizer将句⼦中相邻两个单词进⾏组合】
试试另⼀句:
#调整⽂本顺序
joke2 = jieba.cut('尼姑看见道⼠的嘴唇亲吻了和尚')
joke2 = [''.join(joke2)]
#转化为向量
#vect.fit(joke2) //这句书上没有,不知道是否必须
joke2_feature = vect.transform(joke2)
#打印⽂本数据特征
print(joke2_feature.toarray())
[[0 0 0 0]]
2.使⽤tf-idf模型对⽂本数据进⾏处理
使⽤tf-idf模型来进⾏⽂本特征提取的类,称为TfidfVectorizer
tf-idf全称为词频-逆向⽂件频率
tf-idf是⼀种⽤来评估某个词对于⼀个语料库中某⼀份⽂件的重要程度
如果某个词在某个⽂件中出现的次数⾮常⾼,但在其他⽂件中出现的次数⾮常少,那么tf-idf就会认为这个词可以很好的将⽂件进⾏区分,重要程度会较⾼
【注意】tf-idf公式有很多变体
介绍TfidVectorizer⽤法和CountVectorizer的区别:
下载数据集/~amaas/data/sentiment
载⼊影评数据集:
!tree C:\Users\DELL\Desktop\aclImdb
使⽤sklearn载⼊这些⽂本数据:
#导⼊⽂件载⼊⼯具
from sklearn.datasets import load_files
#定义训练集
train_set = load_files('C:/Users/DELL/Desktop/aclImdb/train')
X_train,y_train = train_set.data,train_set.target
print('训练集⽂件数量:',len(X_train))
print('随机选⼀个',X_train[22])
有些评论有<br />的符号,⽤空格替换掉,避免影响模型
#将⽂本的<br />去掉
X_train = [doc.replace(b'<br />',b'') for doc in X_train]
再载⼊数据集:
#载⼊测试集
test = load_files('C:/Users/DELL/Desktop/aclImdb/test')
X_test,y_test = test.data,test.target
X_test = [doc.replace(b'<br />',b'') for doc in X_test]
#测试集⽂件数量
len(X_test)
25000
对⽂本数据进⾏特征提取:
使⽤CountVectorizer
#⽤CountVectorize拟合训练数据
vect = CountVectorizer().fit(X_train)
#将⽂本转化为向量
X_train_vect = vect.transform(X_train)
print('训练集样本特征数量:',len(vect.get_feature_names()))
print('最后10个训练集样本特征:',vect.get_feature_names()[-10:])
训练集样本特征数量: 124255
最后10个训练集样本特征: ['üvegtigris', 'üwe', 'ÿou', 'ıslam', 'ōtomo', 'şey', 'дом', 'книги', '⾊戒', 'rock']使⽤有监督学习算法进⾏交叉验证评分:
看看模型能否较好的拟合训练集
#导⼊线性SVC分类模型
from sklearn.svm import LinearSVC
#导⼊交叉验证⼯具
from sklearn.model_selection import cross_val_score
#使⽤交叉验证对模型评分
scores = cross_val_score(LinearSVC(),X_train_vect,y_train)
print('模型平均分:',scores.mean())。

数据集太⼤,⼗分钟还没好。

就⽤书上截图了.。

0.778
泛化到测试集:
#把测试数据集转化为向量
X_test_vect = vect.transform(X_test)
#使⽤线性SVC拟合训练集
clf = LinearSVC().fit(X_train_vect,y_train)
print('测试集得分:',clf.score(X_test_vect,y_test))
0.58
接下来⽤tf-idf算法处理数据:
#导⼊tfidf转化⼯具
from sklearn.feature_extraction.text import TfidfTransformer
#⽤tfidf⼯具转化训练集和测试集
tfidf = TfidfTransformer(smooth_idf = False)
tfidf.fit(X_train_vect)
X_train_tfidf = tfidf.transform(X_train_vect)
X_test_tfidf = tfidf.transform(X_test_vect)
print('未处理的特征:',X_train_vect[:5,:5].toarray())
print('经tfidf处理的特征:',X_train_tfidf[:5,:5].toarray())
结果处理后的数据集训练的模型评分:
#重新训练线性SVC模型
clf = LinearSVC().fit(X_train_tfidf,y_train)
#使⽤新的数据进⾏交叉验证
scores2 = cross_val_score(LinearSVC(),X_train_tfidf,y_train)
print('经过tfidf处理的训练集交叉验证得分:',scores.mean())
print('经过tfidf处理的测试集得分:',clf.score(X_test_tfidf,y_test))
【结果分析】
继续对模型继续改进——删除“停⽤词”
3.删除停⽤词
停⽤词,指在⽂本处理过程中被筛选出去的,出现频率⾼,但⽆意义,⽐如各种语⽓词、连词、介词⽬前没有通⽤的定义“停⽤词”的规则或⼯具
常见⽅法:
统计⽂本中出现频率最⾼的,然后把他们作为“停⽤词”
使⽤现有的停⽤词表
载⼊sklearn内置的停⽤词表:
#导⼊内置的停⽤词库
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
#打印停⽤词个数
print(len(ENGLISH_STOP_WORDS))
#打印前20和后20个
print(list(ENGLISH_STOP_WORDS)[:20],list(ENGLISH_STOP_WORDS)[:-20:])
在上⽅的影视评语数据集继续停⽤词删除:
#导⼊Tfidf模型
from sklearn.feature_extraction.text import TfidfVectorizer
#激活英语停⽤词参数
tfidf = TfidfVectorizer(smooth_idf=False,stop_words='english')
#拟合训练集
tfidf.fit(X_train)
#将训练集⽂本转化为向量
X_train_tfidf = tfidf.transform(X_train)
#使⽤交叉验证进⾏评分
scores3 = cross_val_score(LinearSVC(),X_train_tfidf,y_train)
clf.fit(X_train_tfidf,y_train)
#将测试集转化为向量
X_test_tfidf = tfidf.transform(X_test)
print('去掉停⽤词后训练集交叉验证平均分:',scores3.mean())
print('去掉停⽤词后测试集模型得分:',clf.score(X_test_tfidf,y_test))
【结果分析】
去掉停⽤词,可以让机器学习模型更好的拟合⽂本数据,并提⾼模型的泛化能⼒。

相关文档
最新文档