零基础入门NLP赛事 - Task3 基于机器学习的文本分类

学习目标

  • 学会常用的文本表示方法原理和使用
  • 使用sklearn的机器学习模型完成文本分类

文本表示方法

在机器学习算法的训练过程中,假设给定
N个样本,每个样本有 M 个特征,这样组成了 N×M 的样本矩阵,然后完成算法的训练和预测。同样的在计算机视觉中可以将图片的像素看作特征,每张图片看作hight×width×3的特征图,一个三维的矩阵来进入计算机进行计算。
但是在自然语言领域,上述方法却不可行:文本是不定长度的。文本表示成计算机能够运算的数字或向量的方法一般称为词嵌入(Word Embedding)方法。词嵌入将不定长的文本转换到定长的空间内,是文本分类的第一步。

Bag of Words

Bag of Words(词袋表示),也称为Count Vectors,每个文档的字/词可以使用其出现次数来进行表示。在sklearn中可以直接CountVectorizer来实现这一步骤,举例如下:

#封装一个函数,CountVectorizer和TruncatedSVD结合实现LSI/LSA(隐含语义分析)
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import CountVectorizer
def count2vec(input_values, output_num, output_prefix, seed=1024):
    count_enc = CountVectorizer()
    count_vec = count_enc.fit_transform(input_values)
    svd_tmp = TruncatedSVD(n_components=output_num, n_iter=20, random_state=seed)
    svd_tmp = svd_tmp.fit_transform(count_vec)
    svd_tmp = pd.DataFrame(svd_tmp)
    svd_tmp.columns = ['{}_countvec_{}'.format(output_prefix, i) for i in range(output_num)]
    return svd_tmp

TF-IDF

定义

TF-IDF 分数由两部分组成:第一部分是词语频率(Term Frequency),第二部分是逆文档频率(Inverse Document Frequency)。其中计算语料库中文档总数除以含有该词语的文档数量,然后再取对数就是逆文档频率。

使用

#构建一个计算词频(TF)的玩意儿,当然这里面不足是可以做这些
vectorizer = CountVectorizer()

#构建一个计算TF-IDF的玩意儿
transformer = TfidfTransformer()

#vectorizer.fit_transform(corpus)将文本corpus输入,得到词频矩阵
#将这个矩阵作为输入,用transformer.fit_transform(词频矩阵)得到TF-IDF权重矩阵
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)

优势

是一种在文本挖掘中广泛使用的特征向量化方法,它可以体现一个文档中词语在语料库中的重要程度。(对比Countvectorizer,训练文本的数量越多,TF-IDF就更有优势。

Word2Vec

定义

from gensim.models import word2vec
把每一个单词表示成一个向量。来计算文档相似度计算等等。用于词向量的获取。即根据“上下文-单词”矩阵进行学习,得到融入了上下文共现特征的词向量。

使用

from gensim.models import word2vec
model=word2vec.Word2Vec(sentences,min_count=5,size=50)
	#min_count,频数阈值,大于等于1的保留,默认值为5;
	#size是神经网络的隐藏层单元数,默认为100;
	#workers=4,default = 1 worker = no parallelization 只有在机器已安装 Cython 情况下才会起到作用。
#结果查看
model.similarity("好", "还行")#计算两个词之间的余弦距离
model.most_similar("滋润", topn=10)#计算余弦距离最接近“滋润”的10个词

#存储和加载模型 (页首)
model.save('/model/word2vec_model') 
new_model=gensim.models.Word2Vec.load('/model/word2vec_model')

优缺点

  • 优点:
    由于Word2vec会考虑上下文,跟之前的Embedding方法相比,效果要更好;比之前的Embedding方法维度更少,所以速度更快;通用性很强,可以用在各种 NLP 任务中。

  • 缺点:
    由于词和向量是一对一的关系,所以多义词的问题无法解决;此外,Word2vec是一种静态的方式,虽然通用性强,但是无法针对特定任务做动态优化。

基于机器学习的文本分类

# Count Vectors + RidgeClassifier

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('../data/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.7422037924439758
# TF-IDF +  RidgeClassifier

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('../data/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'))
0.8721598830546126
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值