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

本文涉及的产品
NLP自然语言处理_高级版,每接口累计50万次
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_基础版,每接口每天50万次
简介: 词袋模型和词向量表示是自然语言处理中最常用的特征表示方法,但这两种方法各适用于哪些不同的任务,有什么区别,作者Edward Ma详细讲解了这两类使用技巧。什么情况下词袋模型比词嵌入更具优势,值得大家学习和收藏!

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) 词频-逆文档频率算法

image

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

原文发布时间为:2018-08-04
本文作者:Edward Ma
本文来自云栖社区合作伙伴“专知”,了解相关信息可以关注“专知

相关文章
|
21天前
|
机器学习/深度学习 自然语言处理 PyTorch
从零开始构建nlp情感分析模型!
本教程介绍了如何使用PyTorch和Hugging Face的Transformers库构建一个情感分析模型。主要内容包括导入所需库、读取训练数据集、加载预训练的BERT模型和分词器、定义情感数据集类、划分训练集和验证集、创建数据加载器、设置训练参数、训练模型、评估模型性能以及定义和测试预测函数。通过这些步骤,可以实现一个简单而有效的情感分析模型。
55 2
|
2月前
|
自然语言处理 PyTorch 算法框架/工具
掌握从零到一的进阶攻略:让你轻松成为BERT微调高手——详解模型微调全流程,含实战代码与最佳实践秘籍,助你应对各类NLP挑战!
【10月更文挑战第1天】随着深度学习技术的进步,预训练模型已成为自然语言处理(NLP)领域的常见实践。这些模型通过大规模数据集训练获得通用语言表示,但需进一步微调以适应特定任务。本文通过简化流程和示例代码,介绍了如何选择预训练模型(如BERT),并利用Python库(如Transformers和PyTorch)进行微调。文章详细说明了数据准备、模型初始化、损失函数定义及训练循环等关键步骤,并提供了评估模型性能的方法。希望本文能帮助读者更好地理解和实现模型微调。
72 2
掌握从零到一的进阶攻略:让你轻松成为BERT微调高手——详解模型微调全流程,含实战代码与最佳实践秘籍,助你应对各类NLP挑战!
|
2月前
|
机器学习/深度学习 自然语言处理 并行计算
探索深度学习中的Transformer模型及其在自然语言处理中的应用
【10月更文挑战第6天】探索深度学习中的Transformer模型及其在自然语言处理中的应用
110 0
|
2月前
|
机器学习/深度学习 自然语言处理 异构计算
【NLP自然语言处理】初识深度学习模型Transformer
【NLP自然语言处理】初识深度学习模型Transformer
|
2月前
|
机器学习/深度学习 自然语言处理 算法
【NPL自然语言处理】带你迅速了解传统RNN模型
【NPL自然语言处理】带你迅速了解传统RNN模型
|
4月前
|
自然语言处理
【NLP】from glove import Glove的使用、模型保存和加载
使用 from glove import Glove 进行词向量训练、保存和加载的基本示例。
57 2
【NLP】from glove import Glove的使用、模型保存和加载
|
4月前
|
机器学习/深度学习 自然语言处理 PyTorch
PyTorch与Hugging Face Transformers:快速构建先进的NLP模型
【8月更文第27天】随着自然语言处理(NLP)技术的快速发展,深度学习模型已经成为了构建高质量NLP应用程序的关键。PyTorch 作为一种强大的深度学习框架,提供了灵活的 API 和高效的性能,非常适合于构建复杂的 NLP 模型。Hugging Face Transformers 库则是目前最流行的预训练模型库之一,它为 PyTorch 提供了大量的预训练模型和工具,极大地简化了模型训练和部署的过程。
197 2
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】探讨最新的深度学习算法、模型创新以及在图像识别、自然语言处理等领域的应用进展
深度学习作为人工智能领域的重要分支,近年来在算法、模型以及应用领域都取得了显著的进展。以下将探讨最新的深度学习算法与模型创新,以及它们在图像识别、自然语言处理(NLP)等领域的应用进展。
128 6
|
4月前
|
机器学习/深度学习 自然语言处理 数据处理
|
4月前
|
自然语言处理
【NLP】如何实现快速加载gensim word2vec的预训练的词向量模型
本文探讨了如何提高使用gensim库加载word2vec预训练词向量模型的效率,提出了三种解决方案:保存模型以便快速重新加载、仅保存和加载所需词向量、以及使用Embedding工具库代替word2vec原训练权重。
220 2
下一篇
无影云桌面