基于机器学习的文本分类

基于机器学习的文本分类

学习目标

  • 学会TF-IDF的原理和使用
  • 使用sklearn的机器学习模型完成文本分类

机器学习模型

文本表示方法

One-hot
1
2
3
4
5
6
7
8
9
10
11
句子1:我 爱 北 京 天 安 门
句子2:我 喜 欢 上 海

{
'我': 1, '爱': 2, '北': 3, '京': 4, '天': 5, '安': 6, '门': 7, '喜': 8, '欢': 9, '上': 10, '海': 11
}

我:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
爱:[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
...
海:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
Bag of Words

每个文档的字/词可以使用其出现次数来进行表示。

1
2
3
4
5
句子1:我 爱 北 京 天 安 门
转换为 [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]

句子2:我 喜 欢 上 海
转换为 [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]
1
2
3
4
5
6
7
8
9
10
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
'我爱北京天安门',
'我爱上海的门',
]
vectorizer = CountVectorizer(analyzer ='char')
count = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
print(vectorizer.vocabulary_)
print(count.toarray())

image-20200725173247152

N-gram

相邻单词组合成为新的单词

1
2
3
# N = 2
句子1:我爱 爱北 北京 京天 天安 安门
句子2:我喜 喜欢 欢上 上海
1
2
3
4
5
6
7
8
9
from sklearn.feature_extraction.text import CountVectorizer
data = ['我爱北京天安门',
'我喜欢上海']
vec = CountVectorizer(analyzer ='char',min_df=1, ngram_range=(2,2))
X = vec.fit_transform(data) # transform text to metrix
vec.get_feature_names() # get features
X.toarray()
df = pd.DataFrame(X.toarray(), columns=vec.get_feature_names()) # to DataFrame
df.head()

image-20200725172538480

TF-IDF

TF:词语频率。该词语在当前文档出现的次数 / 当前文档中词语的总数

IDF:逆文档频率:语料库中文档总数除以含有该词语的文档数量,然后再取对数。log_e(文档总数 / 出现该词语的文档总数)

1
2
3
4
5
6
7
8
9
10
from sklearn.feature_extraction.text import TfidfVectorizer, TfidfTransformer
corpus = [
'我爱北京天安门',
'我喜欢上海',
]
tfidf_vec = TfidfVectorizer(analyzer ='char')
tfidf_matrix = tfidf_vec.fit_transform(corpus)
#print(tfidf_vec.get_feature_names())
#print(tfidf_vec.vocabulary_)
print(tfidf_matrix.toarray())

image-20200725173908953

文本分类

RidgeClassifier——岭回归分类器

1
2
3
4
5
6
7
8
9
10
sklearn.linear_model.RidgeClassifier(
alpha=1.0, # 正则化强度;必须是正的浮点数。
fit_intercept=True, # 计算截距
normalize=False, # 当fit_intercept被设置为False时,将忽略该参数。若为真,则回归前将对回归数X进行归一化处理,方法是减去均值再除以l2-范数。
copy_X=True, #
max_iter=None, # 共轭梯度求解器的最大迭代次数
tol=0.001, # 求解的精度
class_weight=None,
solver='auto', # “auto”:根据数据类型自动选择求解器。
random_state=None)

Count Vectors + RidgeClassifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score

train_df = pd.read_csv('../input/train_set.csv', sep='\t', nrows=15000)

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'))
# 0.74

TF-IDF + RidgeClassifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pandas as pd

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.metrics import f1_score

train_df = pd.read_csv('../input/train_set.csv', sep='\t', nrows=15000)

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'))

本文标题:基于机器学习的文本分类

文章作者:ZQ Liu

发布时间:2020年07月25日 - 10:00:15

最后更新:2020年07月27日 - 09:57:12

原始链接:http://yoursite.com/2020/07/25/%E5%9F%BA%E4%BA%8E%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道