【干货】NLP中“词袋”模型和词嵌入模型的比较(附代码)

2018 年 8 月 4 日 专知

【导读】词袋模型和词向量表示是自然语言处理中最常用的特征表示方法,但这两种方法各适用于哪些不同的任务,有什么区别,作者Edward Ma详细讲解了这两类使用技巧。什么情况下词袋模型比词嵌入更具优势,值得大家学习和收藏!


作者 | Edward Ma

编译 | 专知

翻译 | Mandy


3 basic approaches in Bag of Words which are better than Word Embeddings


现如今大家都在讨论词(或字符、句子、文档)嵌入技术,词袋模型还有使用的价值吗?我们需要在任何场景中都使用词嵌入吗?


读完这篇博文,你将会知道:


  • 为什么人们说词嵌入可以直接而轻松地解决问题?


  • 什么情况下词袋模型比词嵌入更具优势?


  • 词袋模型中的三种基本方法


  • 我们如何通过几行代码就可以建立词袋模型?


一. 为什么词嵌入可以直接而轻松地解决问题?





在最近的NLP领域中,嵌入技术(Embedding)是解决文本相关问题的成功方法,并且其效果优于词袋模型(BoW)。确实,词袋模型在应用上是有一些限制的,比如巨大的特征维数,稀疏表示等等,词嵌入可以很好地解决这些问题。


那么,我们是否还需要词袋模型呢?实际上,在某些情况下,词袋模型会表现地更好。


二. 何时词袋模型比词嵌入更具优势?





在以下情况下,您更倾向使用词袋模型而不是词嵌入:

1. 建立一个基线(baseline)模型。通过使用scikit-learn,只需要几行代码就可以构建模型。之后可以用深度学习的方法来改进它。


2. 如果你的数据集很小并且上下文是特定领域的,那么词袋模型会比词嵌入更有效。上下文是非常特定的领域,这意味着你无法从预先训练好的词嵌入模型(比如GloVe, fastText等)中找到相应的向量。


三. 我们如何通过几行代码就可以建立词袋模型?





通过使用传统的机器学习库,有三种简单的方式可以构建词袋模型。


1. Count Occurrence

计算单词出现的次数。使用这种方法的原因是关键字或重要信息会反复出现。所以如果出现的次数代表了单词的重要性。更高的频率意味着更高的重要性。


doc = "In the-state-of-art ofthe NLP field, Embedding is the \

success way to resolve text relatedproblem and outperform \

Bag of Words ( BoW ). Indeed, BoWintroduced limitations \

large feature dimension, sparserepresentation etc."

count_vec = CountVectorizer()

count_occurs =count_vec.fit_transform([doc])

count_occur_df = pd.DataFrame(

(count, word) for word, count in

   zip(count_occurs.toarray().tolist()[0],

  count_vec.get_feature_names()))

count_occur_df.columns = ['Word','Count']

count_occur_df.sort_values('Count',ascending=False, inplace=True)

count_occur_df.head()


输出结果:

Word: "of", Occurrence: 3

Word: "bow", Occurrence: 2

Word: "way", Occurrence: 1

 

2. Normalized Count Occurrence

如果你认为一些出现频率极高的词可能会影响结果并导致模型偏差。运用归一化(Normalization)可以解决这个问题。


doc = "In the-state-of-art ofthe NLP field, Embedding is the \

success way to resolve text relatedproblem and outperform \

Bag of Words ( BoW ). Indeed, BoWintroduced limitations \

large feature dimension, sparserepresentation etc."

norm_count_vec = TfidfVectorizer(use_idf=False,norm='l2')

norm_count_occurs =norm_count_vec.fit_transform([doc])

norm_count_occur_df = pd.DataFrame(

(count, word) for word, count in zip(

norm_count_occurs.toarray().tolist()[0],

  norm_count_vec.get_feature_names()))

norm_count_occur_df.columns =['Word', 'Count']

norm_count_occur_df.sort_values(

'Count', ascending=False, inplace=True)

norm_count_occur_df.head()

 

输出结果:

Word: "of", Occurrence:0.4286

Word: "bow", Occurrence:0.4286

Word: "way", Occurrence:0.1429

 

3. Term Frequency-Inverse Document Frequency (TF-IDF) 词频-逆文档频率算法

 


TF-IDF采取另一种方法,认为高频率可能无法提供大量信息增益。换句话说,罕见的词语为模型贡献了更多的权重。


在同一文档中(即同一训练record),词的重要性会随着出现次数的增加而提高。另一方面,如果在语料库中(即其他的训练record),词的重要性会随着出现次数的增加而降低。

doc = "In the-state-of-art ofthe NLP field, Embedding is the \

success way to resolve text relatedproblem and outperform \

Bag of Words ( BoW ). Indeed, BoWintroduced limitations \

large feature dimension, sparserepresentation etc."

tfidf_vec = TfidfVectorizer()

tfidf_count_occurs =tfidf_vec.fit_transform([doc])

tfidf_count_occur_df = pd.DataFrame(

(count, word) for word, count in zip(

tfidf_count_occurs.toarray().tolist()[0],  

  tfidf_vec.get_feature_names()))

tfidf_count_occur_df.columns =['Word', 'Count']

tfidf_count_occur_df.sort_values('Count',ascending=False, inplace=True)

tfidf_count_occur_df.head()


输出结果(结果与归一化计数(normalized count occurrence)完全相同,因为演示代码仅包含一个文档)

 

Word: "of", Occurrence:0.4286

Word: "bow", Occurrence:0.4286

Word: "way", Occurrence:0.1429


四. 代码




此示例代码将在Count Occurrence,Normalized Count Occurrence和TF-IDF之间进行比较。


如下的示例函数通过使用不同的矢量化方法来构建模型

def build_model(mode):

# Intent to use default paramaters for show case

  vect = None

  if mode == 'count':

vect = CountVectorizer()

elif mode == 'tf':

vect = TfidfVectorizer(use_idf=False,norm='l2')

elif mode == 'tfidf':

vect = TfidfVectorizer()

else:

raise ValueError('Mode should be eithercount or tfidf')



return Pipeline([

('vect', vect),

       ('clf' ,LogisticRegression(solver='newton-cg',n_jobs=-1))

])


有另一个示例函数来构建一个端到端的pipeline


def pipeline(df, mode):

x = preprocess_x(df)

y = preprocess_y(df)



model_pipeline = build_model(mode)

cv = KFold(n_splits=10, shuffle=True)



scores = cross_val_score(

model_pipeline, x, y, cv=cv,scoring='accuracy')

print("Accuracy: %0.4f (+/- %0.4f)" % (

scores.mean(), scores.std() * 2))



return model_pipeline


让我们检查一下我们需要处理的总的单词数量


x = preprocess_x(x_train)

y = y_train



model_pipeline =build_model(mode='count')

model_pipeline.fit(x, y)

print('Number of Vocabulary: %d'%(len(model_pipeline.named_steps
['vect'].get_feature_names())))


输出结果

Number of Vocabulary: 130107

 

通过传递不同的参数mode = “count” (Count Occurrence), “tf”(Normalized Count Occurrence) 或者 “tfidf”(TF-IDF)来调用pipeline模型。

print('Using Count Vectorizer------')

model_pipeline = pipeline(x_train,y_train, mode='count')

print('Using TF Vectorizer------')

model_pipeline = pipeline(x_train,y_train, mode='tf')

print('Using TF-IDFVectorizer------')

model_pipeline = pipeline(x_train,y_train, mode='tfidf')


结果是:

Using Count Vectorizer------

Accuracy: 0.8892 (+/- 0.0198)

Using TF Vectorizer------

Accuracy: 0.8071 (+/- 0.0110)

Using TF-IDF Vectorizer------

Accuracy: 0.8917 (+/- 0.0072)


五. 结论




您可以在GitHub查看所有的代码。

https://github.com/makcedward/nlp/blob/master/sample/nlp-bag_of_words.ipynb


根据以往的经验,我试图通过简短的描述来解决产品类别分类的问题。例如,给出“FreshApple”,期望分配的类别是“Fruit”。通过仅使用计数出现次数的方法就已经能够达到80%以上的准确率。


在这种情况下,由于每个训练记录的单词数量只是几个单词(从2个单词到10个单词)。使用词嵌入可能不是一个好方法,因为没有太多的上下文(单词)来训练词向量。


另一方面,scikit-learn提供了其他参数来进一步优化模型输入。您可能需要查看以下特征:


  • ngram_range: 除了使用单个单词,也可以定义ngram


  • binary: 除了计数出现的次数之外,还可以选择二元表示。


  • max_features: 不使用单词表的所有单词,可以选择最大数量的单词来减少模型的复杂性和大小。


此外,还可以在上面的scikit-learn库中执行一些预处理步骤,不需要自己处理。例如,删除停止词(stop word),单词变为小写等等。为了获得更好的灵活性,我将使用自己的代码来完成预处理步骤(参见GitHub)。


原文链接:

https://towardsdatascience.com/3-basic-approaches-in-bag-of-words-which-are-better-than-word-embeddings-c2cbc7398016


Github 链接:

https://github.com/makcedward/nlp/blob/master/sample/nlp-bag_of_words.ipynb


-END-

专 · 知

人工智能领域主题知识资料查看与加入专知人工智能服务群

专知AI知识技术服务会员群加入与人工智能领域26个主题知识资料全集获取欢迎微信扫一扫加入专知人工智能知识星球群,获取专业知识教程视频资料和与专家交流咨询


请PC登录www.zhuanzhi.ai或者点击阅读原文,注册登录专知,获取更多AI知识资料

请加专知小助手微信(扫一扫如下二维码添加),加入专知主题群(请备注主题类型:AI、NLP、CV、 KG等)交流~

 AI 项目技术 & 商务合作:bd@zhuanzhi.ai, 或扫描上面二维码联系!


关注专知公众号,获取人工智能的专业知识!

点击“阅读原文”,使用专知

登录查看更多
11

相关内容

词袋模型是自然语言处理和信息检索(IR)中使用的简化表示。 在此模型中,文本(例如句子或文档)表示为其单词的包(多集),而忽略了语法甚至单词顺序,但保持了多重性。 词袋模型也已用于计算机视觉。词袋模型通常用于文档分类方法中,其中每个单词的出现频率用作训练分类器的功能。
专知会员服务
171+阅读 · 2020年6月4日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
338+阅读 · 2020年3月17日
Sklearn 与 TensorFlow 机器学习实用指南,385页pdf
专知会员服务
129+阅读 · 2020年3月15日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
【干货】用BRET进行多标签文本分类(附代码)
专知会员服务
84+阅读 · 2019年12月27日
计算机视觉最佳实践、代码示例和相关文档
专知会员服务
17+阅读 · 2019年10月9日
不懂 word2vec,还敢说自己是做 NLP 的?
AI研习社
8+阅读 · 2018年5月4日
干货|自然语言处理中的词向量 — word2vec!
全球人工智能
7+阅读 · 2018年1月25日
专栏 | 技术干货:一文详解LDA主题模型
机器之心
28+阅读 · 2017年12月1日
教程 | 在Python和TensorFlow上构建Word2Vec词嵌入模型
机器之心
6+阅读 · 2017年11月20日
干货|10分钟快速入门PyTorch (7) 词向量
机器学习研究会
8+阅读 · 2017年9月26日
字词的向量表示
黑龙江大学自然语言处理实验室
4+阅读 · 2016年6月13日
Arxiv
6+阅读 · 2020年4月14日
Universal Transformers
Arxiv
5+阅读 · 2019年3月5日
Embedding Logical Queries on Knowledge Graphs
Arxiv
3+阅读 · 2019年2月19日
Music Transformer
Arxiv
5+阅读 · 2018年12月12日
Arxiv
22+阅读 · 2018年8月30日
Arxiv
4+阅读 · 2017年10月30日
VIP会员
相关VIP内容
专知会员服务
171+阅读 · 2020年6月4日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
338+阅读 · 2020年3月17日
Sklearn 与 TensorFlow 机器学习实用指南,385页pdf
专知会员服务
129+阅读 · 2020年3月15日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
【干货】用BRET进行多标签文本分类(附代码)
专知会员服务
84+阅读 · 2019年12月27日
计算机视觉最佳实践、代码示例和相关文档
专知会员服务
17+阅读 · 2019年10月9日
相关资讯
不懂 word2vec,还敢说自己是做 NLP 的?
AI研习社
8+阅读 · 2018年5月4日
干货|自然语言处理中的词向量 — word2vec!
全球人工智能
7+阅读 · 2018年1月25日
专栏 | 技术干货:一文详解LDA主题模型
机器之心
28+阅读 · 2017年12月1日
教程 | 在Python和TensorFlow上构建Word2Vec词嵌入模型
机器之心
6+阅读 · 2017年11月20日
干货|10分钟快速入门PyTorch (7) 词向量
机器学习研究会
8+阅读 · 2017年9月26日
字词的向量表示
黑龙江大学自然语言处理实验室
4+阅读 · 2016年6月13日
相关论文
Arxiv
6+阅读 · 2020年4月14日
Universal Transformers
Arxiv
5+阅读 · 2019年3月5日
Embedding Logical Queries on Knowledge Graphs
Arxiv
3+阅读 · 2019年2月19日
Music Transformer
Arxiv
5+阅读 · 2018年12月12日
Arxiv
22+阅读 · 2018年8月30日
Arxiv
4+阅读 · 2017年10月30日
Top
微信扫码咨询专知VIP会员