文本表示方法
one-hot
这里的One-hot与数据挖掘任务中的操作是一致的,即将每一个单词使用一个离散的向量表示。具体将每个字/词编码一个索引,然后根据索引进行赋值。
import jieba
import pandas as pd
text = "我爱北京天安门,也喜欢上海"
jieba.add_word("天安门")
corpus = " ".join(jieba.cut(text)).split(" ")
corpus
output:
['我', '爱', '北京', '天安门', ',', '也', '喜欢', '上海']
one_hot = pd.get_dummies(corpus)
one_hot
Bag of Words
Bag of Words(词袋表示),也称为Count Vectors,每个文档的字/词可以使用其出现次数来进行表示。
思考:中文的词袋表示,有没有可以表示的
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
'This is the first document.',
'This document is the second document.',
'And this is the third one.',
'Is this the first document?',
]
vectorizer = CountVectorizer()
vec = vectorizer.fit_transform(corpus).toarray()
columns = [i[0] for i in sorted(vectorizer.vocabulary_.items(),key = lambda x:x[1],reverse = True)[::-1]]
pd.DataFrame(vec,columns=columns)
N-gram
句子1:我爱北京天安门
句子2:我喜欢上海
N-gram与Count Vectors类似,不过加入了相邻单词组合成为新的单词,并进行计数。
如果N取值为2,则句子1和句子2就变为:
句子1:我爱 爱北 北京 京天 天安 安门
句子2:我喜 喜欢 欢上 上海
TF-IDF
TF-IDF 分数由两部分组成:
第一部分是词语频率(Term Frequency)
第二部分是逆文档频率(Inverse Document Frequency)。
其中计算语料库中文档总数除以含有该词语的文档数量,然后再取对数就是逆文档频率。
TF(t)= 该词语在当前文档出现的次数 / 当前文档中词语的总数
IDF(t)= log_e(文档总数 / 出现该词语的文档总数)
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
'This is the first document.',
'This document is the second document.',
'And this is the third one.',
'Is this the first document?',
]
tfidf = TfidfVectorizer()
tfidf_model = tfidf.fit(corpus)
tfidf = tfidf.fit_transform(corpus)
vec = tfidf.todense()
output:
[[0. 0.46979139 0.58028582 0.38408524 0. 0.
0.38408524 0. 0.38408524]
[0. 0.6876236 0. 0.28108867 0. 0.53864762
0.28108867 0. 0.28108867]
[0.51184851 0. 0. 0.26710379 0.51184851 0.
0.26710379 0.51184851 0.26710379]
[0. 0.46979139 0.58028582 0.38408524 0. 0.
0.38408524 0. 0.38408524]]
tfidf_model.vocabulary_
output:
{'this': 8, 'is': 3, 'the': 6, 'first': 2, 'document': 1, 'second': 5, 'and': 0, 'third': 7, 'one': 4}
columns = [i[0] for i in sorted(tfidf_model.vocabulary_.items(),key = lambda x:x[1],reverse = True)[::-1]]
columns
output:
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
pd.DataFrame(vec,columns=columns)
基于机器学习的文本分类
对比Bag of Words(词袋表示)和 TF-IDF 两种文本表示方法【模型:岭回归算法(RidgeClassifier)】
评分指标:f1
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score
train_df = pd.read_csv('train_set.csv', sep='\t', nrows=15000)
Bag of Words(词袋表示): 0.74
vectorizer = CountVectorizer(max_features=3000)
train_test = vectorizer.fit_transform(train_df['text'])
clf = RidgeClassifier()
clf.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))
output:
0.74
TF-IDF:0.87
tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=3000)
train_test = tfidf.fit_transform(train_df['text'])
clf = RidgeClassifier()
clf.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))
output:
0.87
Bag of Words(词袋表示)只考虑了句内。
TF-IDF考虑了局内,也考虑了全文。
思考:中文句子怎么处理?
1、建立字典
2、将句子的索引映射到字符串里。
3、将该字符串进行TfidfVectorizer().fit_transform(corpus)处理,得到词向量。