深度卷积神经网络用于情感分析(文本分类)

开发一个深度学习模型来自动分类电影评论
使用 Keras 和 Python 将电影评论分类为正面或负面,一步一步进行。

词嵌入是一种文本表示技术,其中意义相似的不同单词具有相似的实值向量表示。

这是促使神经网络模型在许多具有挑战性的自然语言处理问题上取得优异性能的关键突破。

在本教程中,您将了解如何为神经网络开发词嵌入模型来对电影评论进行分类。

完成本教程后,您将了解:

  • 如何使用深度学习方法准备用于分类的电影评论文本数据。
  • 如何在拟合深度学习模型的过程中学习词嵌入。
  • 如何学习独立的词嵌入以及如何在神经网络模型中使用预训练的嵌入。

开始您的项目,阅读我的新书《深度学习在自然语言处理中的应用》,其中包含分步教程以及所有示例的Python源代码文件。

让我们开始吧。

  • 更新(2019年11月):修正了准备训练数据集时代码中的一个拼写错误(感谢 HSA)。
  • 2020 年 8 月更新:更新了电影评论数据集的链接。
How to Develop a Word Embedding Model for Predicting Movie Review Sentiment

如何开发词嵌入模型来预测电影评论情感
照片作者:Katrina Br*?#*!@nd,部分权利保留。

教程概述

本教程分为5个部分,它们是:

  1. 电影评论数据集
  2. 数据准备
  3. 训练嵌入层
  4. 训练 word2vec 嵌入
  5. 使用预训练嵌入

Python 环境

本教程假设您已安装 Python SciPy 环境,最好是 Python 3。

您必须安装 Keras(2.2 或更高版本),并使用 TensorFlow 或 Theano 后端。

本教程还假设您已安装 scikit-learn、Pandas、NumPy 和 Matplotlib。

如果您需要环境方面的帮助,请参阅本教程

本教程不需要 GPU,但您可以在 Amazon Web Services 上廉价地访问 GPU。在本教程中学习如何操作。

让我们开始吧。

需要深度学习处理文本数据的帮助吗?

立即参加我的免费7天电子邮件速成课程(附代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

1. 电影评论数据集

电影评论数据是 Bo Pang 和 Lillian Lee 在 2000 年代初期从 imdb.com 网站检索的电影评论集合。这些评论是作为他们自然语言处理研究的一部分而收集和提供的。

这些评论最初发布于 2002 年,但于 2004 年发布了更新和清理的版本,称为“v2.0”。

该数据集包含 1,000 条正面和 1,000 条负面电影评论,这些评论取自托管在 imdb.com 上的 rec.arts.movies.reviews 新闻组的存档。作者称此数据集为“极性数据集”。

我们的数据包含 1000 条褒义和 1000 条贬义评论,所有评论均在 2002 年之前撰写,每个作者(共 312 位作者)每个类别最多 20 条评论。我们将此语料库称为极性数据集。

—— 《情感教育:基于最小割的主观性摘要情感分析》,2004 年。

数据已经过一些清理,例如

  • 数据集仅包含英文评论。
  • 所有文本都已转换为小写。
  • 标点符号(如句号、逗号和括号)周围有空格。
  • 文本已分成每行一句。

该数据已被用于一些相关的自然语言处理任务。对于分类任务,机器学习模型(如支持向量机)在该数据集上的性能在 78%-82% 之间。

更复杂的数据准备可能会在 10 折交叉验证下达到 86% 的结果。如果我们希望在现代方法实验中使用此数据集,这为我们提供了一个大致的范围,即 80% 的中低水平。

...根据下游极性分类器的选择,我们可以实现高度统计学意义的改进(从 82.8% 提高到 86.4%)

—— 《情感教育:基于最小割的主观性摘要情感分析》,2004 年。

您可以从此处下载数据集

解压文件后,您将得到一个名为“txt_sentoken”的目录,其中包含两个子目录,用于存储负面和正面的文本,分别为“neg”和“pos”。评论以文件名 cv000 到 cv999 的格式存储,每个 neg 和 pos 目录下都有相应的评论。

接下来,我们来看看如何加载和准备文本数据。

2. 数据准备

在本节中,我们将探讨 3 件事

  1. 将数据分为训练集和测试集。
  2. 加载并清理数据以去除标点符号和数字。
  3. 定义一个常用词汇表。

拆分为训练集和测试集

我们假装正在开发一个系统,可以预测电影评论文本的情感是褒义还是贬义。

这意味着模型开发完成后,我们需要对新的文本评论进行预测。这将需要对这些新评论执行与模型训练数据相同的全部数据准备。

通过在进行任何数据准备之前拆分训练集和测试集,我们将确保此约束内嵌到模型的评估中。这意味着测试集中的任何有助于我们更好地准备数据(例如,使用的单词)的知识,在用于模型训练的数据准备过程中都不可用。

话虽如此,我们将使用最后 100 条褒义评论和最后 100 条贬义评论作为测试集(200 条评论),其余 1,800 条评论作为训练数据集。

这是 90% 训练,10% 拆分的数据。

通过使用评论的文件名可以轻松地施加这种分割,其中文件名 000 到 899 的评论用于训练数据,而文件名 900 及之后的评论用于测试。

加载和清理评论

文本数据本身已经相当干净;不需要太多准备。

如果您不熟悉文本数据清理,请参阅此帖子

在不纠缠于太多细节的情况下,我们将按以下方式准备数据:

  • 按空格分割标记。
  • 从单词中删除所有标点符号。
  • 删除所有不纯粹由字母字符组成的单词。
  • 删除所有已知停用词。
  • 删除所有长度小于等于 1 个字符的单词。

我们可以将所有这些步骤放入一个名为 clean_doc() 的函数中,该函数以从文件中加载的原始文本作为参数,并返回一个清理过的标记列表。我们还可以定义一个 load_doc() 函数,该函数从文件加载文档,以便与 clean_doc() 函数一起使用。

下面列出了清理第一条正面评论的示例。

运行该示例会打印出一长串清理过的标记。

我们可以探索更多清理步骤,并将它们留作进一步的练习。

我很想看看你们的成果。
请在底部的评论区分享你们的方法和发现。

定义词汇表

在使用词袋模型或嵌入模型时,定义一个已知词汇表非常重要。

词汇量越大,文档的表示就越大,因此将单词限制在仅那些被认为具有预测性的单词很重要。这一点很难提前知道,而且通常测试关于如何构建有用词汇表的各种假设很重要。

我们已经在上一节中看到了如何去除标点符号和数字。我们可以将此过程应用于所有文档,并构建一个包含所有已知单词的集合。

我们可以将词汇表开发为一个 Counter,它是一个单词及其计数的字典映射,使我们能够轻松地更新和查询。

每个文档都可以添加到计数器中(一个名为 add_doc_to_vocab() 的新函数),我们可以遍历负面目录中的所有评论,然后是正面目录(一个名为 process_docs() 的新函数)。

完整的示例如下所示。

运行该示例显示我们有一个包含 44,276 个单词的词汇表。

我们还可以看到电影评论中使用频率最高的 50 个单词的样本。

请注意,此词汇表仅基于训练数据集中存在的评论构建。

我们可以遍历词汇表,删除出现次数很少的所有单词,例如在所有评论中只使用了一两次的单词。

例如,以下代码片段将只检索在所有评论中出现 2 次或更多次的标记。

在上面运行示例时添加此部分,显示词汇量大小从 44,276 减少到 25,767 个单词,减少了一半多。

最后,可以将词汇表保存到一个名为 vocab.txt 的新文件中,我们稍后可以加载它并用于在对电影评论进行编码以进行建模之前进行过滤。我们定义了一个名为 save_list() 的新函数,该函数将词汇表保存到文件中,每行一个单词。

例如

对词汇表应用最小出现次数过滤器并将其保存到文件后,您现在应该有一个名为 vocab.txt 的新文件,其中只包含我们感兴趣的单词。

您文件中的单词顺序可能会有所不同,但应与以下内容类似

现在我们准备好学习评论的特征了。

3. 训练嵌入层

在本节中,我们将在训练神经网络进行分类问题时学习词嵌入。

词嵌入是一种文本表示方式,其中词汇表中的每个单词都由高维空间中的实值向量表示。这些向量在训练时被学习,使得具有相似意义的单词在向量空间中具有相似的表示(在向量空间中靠近)。这比传统的词袋模型更具表现力,词袋模型会忽略单词或标记之间的关系,或者强制使用二元组和三元组方法。

单词的实值向量表示可以在训练神经网络时学习。在 Keras 深度学习库中,我们可以使用 Embedding layer 来实现。

如果您不熟悉词嵌入,请参阅此帖子。

如果您不熟悉 Keras 中的词嵌入层,请参阅此帖子。

第一步是加载词汇表。我们将使用它来过滤掉我们不感兴趣的电影评论中的单词。

如果您已完成上一节,您应该有一个名为“vocab.txt”的本地文件,其中每行一个单词。我们可以加载该文件并构建一个集合作为词汇表,以检查标记的有效性。

接下来,我们需要加载所有训练数据的电影评论。为此,我们可以改编上一节中的 process_docs() 来加载文档,清理它们,并将它们作为字符串列表返回,每行一个文档。我们希望每个文档都是一个字符串,以便以后可以轻松地将其编码为整数序列。

清理文档包括按空格拆分每条评论,去除标点符号,然后过滤掉词汇表中不存在的所有标记。

更新后的 clean_doc() 函数如下所示。

更新后的 process_docs() 然后可以调用 clean_doc() 来处理我们训练数据集中的“pos”和“neg”目录中的每个文档。

下一步是将每篇文档编码为整数序列。

Keras 嵌入层需要整数输入,其中每个整数映射到一个特定的实值向量表示的单个标记。这些向量在训练开始时是随机的,但在训练过程中会变得对网络有意义。

我们可以使用 Keras API 中的 Tokenizer 类将训练文档编码为整数序列。

首先,我们必须构建该类的一个实例,然后在一个实例上训练它,该实例将在训练数据集中的所有文档上进行训练。在这种情况下,它将开发训练数据集中所有标记的词汇表,并开发一个从词汇表中的单词到唯一整数的一致映射。我们也可以自己使用词汇表文件来开发这个映射。

现在已经准备好了单词到整数的映射,我们可以使用它来编码训练数据集中的评论。我们可以通过调用 Tokenizer 上的 texts_to_sequences() 函数来实现。

我们还需要确保所有文档的长度都相同。

这是 Keras 实现高效计算的要求。我们可以将评论截断到最短长度,或者将评论(用值“0”填充)填充到最大长度,或者采用混合方式。在本例中,我们将所有评论填充到训练数据集中最长评论的长度。

首先,我们可以使用训练数据集上的 max() 函数找到最长的评论并获取其长度。然后,我们可以调用 Keras 的 pad_sequences() 函数,通过在末尾添加 0 值将序列填充到最大长度。

最后,我们可以为训练数据集定义类别标签,这对于拟合监督神经网络模型以预测评论情感是必需的。

然后,我们可以对测试数据集进行编码和填充,这将在训练模型后用于评估模型。

我们现在准备定义我们的神经网络模型。

该模型将使用一个Embedding层作为第一个隐藏层。Embedding层需要指定词汇量大小、实值向量空间的维度以及输入文档的最大长度。

词汇量大小是我们词汇表中单词的总数,再加上一个用于未知单词。这可以是词汇集合的长度,或者是用于将文档整数编码的分词器中词汇的大小,例如:

我们将使用一个100维的向量空间,但您可以尝试其他值,例如50或150。最后,最大文档长度已在之前的填充过程中使用的max_length变量中计算得出。

完整的模型定义如下,包括Embedding层。

我们使用卷积神经网络(CNN),因为它们已被证明在文档分类问题上取得了成功。使用一种保守的CNN配置,包含32个滤波器(用于处理单词的并行字段)和8个核大小,并使用修正线性(‘relu’)激活函数。之后是一个池化层,将卷积层的输出减半。

接下来,CNN部分模型的2D输出被展平成一个长2D向量,以表示CNN提取的“特征”。模型的后端是标准的。多层感知器层,用于解释CNN特征。输出层使用sigmoid激活函数,输出一个介于0和1之间的值,分别代表评论中的负面和正面情绪。

有关文本分类的有效深度学习模型配置的更多建议,请参阅此博文

运行这段代码可以得到所定义网络的摘要。

我们可以看到,Embedding层期望的输入是长度为442个单词的文档,并将文档中的每个单词编码为一个100维的向量。

接下来,我们在训练数据上拟合网络。

由于我们学习的问题是一个二元分类问题,因此我们使用二元交叉熵损失函数。使用了随机梯度下降的高效Adam实现,并在训练过程中除了损失之外,我们还跟踪准确率。模型训练10个epochs,即10次遍历训练数据。

网络配置和训练计划是经过一些试错发现的,但绝不是针对此问题的最优配置。如果您能通过不同的配置获得更好的结果,请告诉我。

模型拟合后,将在测试数据集上进行评估。此数据集包含我们以前未见过的单词以及在训练期间未见过的评论。

我们可以将所有这些结合起来。

完整的代码列表如下。

运行示例会在每个训练epoch结束时打印损失和准确率。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。可以考虑运行几次示例并比较平均结果。

我们可以看到,模型非常快速地在训练数据集上达到了100%的准确率。在运行结束时,模型在测试数据集上达到了84.5%的准确率,这是一个很好的分数。

我们刚刚看到了一个示例,说明如何将词嵌入作为神经网络模型拟合的一部分进行学习。

接下来,让我们看看如何有效地学习一个独立的嵌入,然后可以在我们的神经网络中使用。

4. 训练word2vec嵌入

在本节中,我们将了解如何使用一种称为word2vec的高效算法来学习一个独立的词嵌入。

作为网络一部分学习词嵌入的一个缺点是它可能非常慢,特别是对于非常大的文本数据集。

word2vec算法是一种从文本语料库中以独立方式学习词嵌入的方法。该方法的优点在于它可以在空间和时间复杂度方面非常高效地生成高质量的词嵌入。

第一步是准备好用于学习嵌入的文档。

这包括与上一节相同的 数据清理步骤,即按空格分割文档、删除标点符号,以及过滤掉不在词汇表中的标记。

word2vec算法是逐句处理文档的。这意味着我们在清理过程中将保留基于句子的结构。

我们像以前一样开始加载词汇表。

接下来,我们定义一个名为doc_to_clean_lines()的函数,该函数逐行清理加载的文档并返回清理后的行列表。

接下来,我们调整process_docs()函数以加载和清理文件夹中的所有文档,并返回所有文档行的列表。

此函数的结果将是word2vec模型的训练数据。

然后,我们可以加载所有训练数据,并将其转换为一个长长的“句子”列表(标记列表),为拟合word2vec模型做好准备。

我们将使用Gensim Python库中提供的word2vec实现。特别是Word2Vec类

有关使用Gensim训练独立词嵌入的更多信息,请参阅此博文

模型在构造类时进行拟合。我们将训练数据中的干净句子列表传入,然后指定嵌入向量空间的大小(我们再次使用100),在学习如何嵌入训练句子中的每个单词时要查看的邻近单词数量(我们使用5个邻近词),拟合模型时使用的线程数(我们使用8个,但如果您的CPU核心数不同,请相应更改),以及考虑在词汇表中使用的单词的最小出现次数(我们将此设置为1,因为我们已经准备好了词汇表)。

模型拟合后,我们打印学习到的词汇量大小,它应该与vocab.txt中的词汇量大小25,767个标记匹配。

最后,我们使用模型“wv”(词向量)属性上的save_word2vec_format()方法将学习到的嵌入向量保存到文件中。嵌入以ASCII格式保存,每行一个单词和向量。

完整的示例如下所示。

运行示例加载了58,109个训练数据句子,并为25,767个单词的词汇量创建了嵌入。

您现在应该在当前工作目录中有一个文件“embedding_word2vec.txt”,其中包含学习到的向量。

接下来,让我们看看如何在模型中使用这些学习到的向量。

5. 使用预训练的嵌入

在本节中,我们将使用在非常大的文本语料库上准备的预训练词嵌入。

我们可以使用上一节准备的预训练词嵌入和前一节开发的CNN模型。

第一步是将词嵌入加载为单词到向量的目录。词嵌入以所谓的“word2vec”格式保存,其中包含一个标题行。加载嵌入时,我们将跳过此标题行。

下面名为load_embedding()的函数加载嵌入,并返回一个将单词映射到NumPy格式向量的目录。

现在我们将所有向量加载到内存中,然后按照与Keras Tokenizer的整数编码相匹配的方式来组织它们。

回想一下,我们在将审查文档传递给Embedding层之前对其进行了整数编码。整数映射到嵌入层中特定向量的索引。因此,重要的是我们要将向量放在Embedding层中,以便编码的单词映射到正确的向量。

下面定义了一个名为get_weight_matrix()的函数,该函数以加载的嵌入和tokenizer.word_index词汇表作为参数,并返回一个在正确位置具有词向量的矩阵。

现在我们可以使用这些函数为我们的模型创建新的Embedding层。

请注意,准备好的权重矩阵embedding_vectors作为参数传递给新的Embedding层,并且我们将‘trainable‘参数设置为‘False‘,以确保网络在训练网络时不会尝试调整预先学习到的向量。

我们现在可以将此层添加到我们的模型中。我们还有一个略有不同的模型配置,在CNN模型中有更多的滤波器(128个),以及一个匹配开发word2vec嵌入时使用的5个邻近词的核。最后,模型的后端被简化了。

这些更改是通过一些试错得出的。

完整的代码列表如下。

运行示例显示性能没有提高。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。可以考虑运行几次示例并比较平均结果。

事实上,性能差了很多。结果表明训练数据集得到了成功学习,但测试数据集上的评估非常差,准确率仅略高于50%。

测试性能差的原因可能是所选的word2vec配置或所选的神经网络配置。

嵌入层中的权重可以用作网络的起点,并在网络训练期间进行调整。我们可以通过在创建嵌入层时设置‘trainable=True‘(默认值)来实现这一点。

重复此更改的实验显示结果略有改善,但仍然很差。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。可以考虑运行几次示例并比较平均结果。

我鼓励您探索嵌入和网络的其他配置,看看您是否能做得更好。告诉我您的进展。

可以使用在非常大的文本数据语料库上准备的预训练词向量。

例如,Google和Stanford都提供了预训练的词向量,您可以下载它们,它们分别使用高效的word2vec和GloVe方法进行训练。

让我们尝试在我们的模型中使用预训练的向量。

您可以从Stanford网页下载预训练的GloVe向量。特别是,在Wikipedia数据上训练的向量

解压该文件,您会发现各种不同维度的预训练嵌入。我们将加载文件中100维的版本“glove.6B.100d.txt”。

Glove文件不包含标题行,因此在将嵌入加载到内存时,我们不需要跳过第一行。下面是更新的、更具防御性的load_embedding()函数。

加载的嵌入可能不包含我们所选词汇表中的所有单词。因此,在创建Embedding权重矩阵时,我们需要跳过在加载的GloVe数据中没有相应向量的单词。下面是更新的、更具防御性的get_weight_matrix()函数版本。

我们现在可以像以前一样加载GloVe嵌入并创建Embedding层。

我们将使用与之前相同的模型。

完整的示例如下所示。

运行示例显示性能有所提高。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能会有所不同。可以考虑运行几次示例并比较平均结果。

同样,训练数据集很容易学习,模型在测试数据集上达到了76%的准确率。这很好,但不如使用学习到的Embedding层。

这可能是因为向量质量更高,它们是在更多数据上训练的,和/或使用了略有不同的训练过程。

在这种情况下,似乎将嵌入作为学习任务的一部分来学习,可能比使用专门训练的嵌入或更通用的预训练嵌入方向更好。

进一步阅读

如果您想深入了解此主题,本节提供了更多资源。

论文

API

嵌入方法

相关文章

总结

在本教程中,您学习了如何开发词嵌入以用于电影评论的分类。

具体来说,你学到了:

  • 如何使用深度学习方法准备用于分类的电影评论文本数据。
  • 如何在拟合深度学习模型的过程中学习词嵌入。
  • 如何学习独立的词嵌入以及如何在神经网络模型中使用预训练的嵌入。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

注意:此帖子是摘录章节自:“深度学习用于自然语言处理”。如果您想获得更多关于在处理文本数据时充分利用深度学习方法的逐步教程,请看看它。

立即开发文本数据的深度学习模型!

Deep Learning for Natural Language Processing

在几分钟内开发您自己的文本模型

...只需几行python代码

在我的新电子书中探索如何实现
用于自然语言处理的深度学习

它提供关于以下主题的自学教程
词袋模型、词嵌入、语言模型、标题生成、文本翻译等等...

最终将深度学习应用于您的自然语言处理项目

跳过学术理论。只看结果。

查看内容

对“面向情感分析(文本分类)的深度卷积神经网络”的 258 条回复

  1. Alexander 2017年10月30日晚上7:11 #

    感谢您对这项工作的关注。
    杰森,请帮帮我。
    想象一下,我们有一个包含长度差异非常大的评论的数据集(从“好电影”这样的两个词到长描述“我记得这位导演的第一个作品……”)。
    当我们谈论“pad_sequence”时,应该选择哪个长度?

    • Jason Brownlee 2017年10月31日凌晨5:32 #

      所有评论都必须填充到相同的长度。

      您可以使用最长的评论,也可以使用平均长度等。尝试几种,看看哪种效果最好。

  2. JingChunzhen 2017年10月31日凌晨2:37 #

    嗨 Jason
    我认为使用 word2vec 很难区分“好”和“坏”,但它在情感分析中仍然很重要。
    有什么好的方法来解决这个问题吗?谢谢,抱歉我的英语不好。

    • Jason Brownlee 2017年10月31日凌晨5:35 #

      通常,模型会最小化一个损失函数。我们希望损失很低。

      我同意,感觉在某种程度上像是聚类。

  3. Alexander 2017年10月31日晚上10:38 #

    感谢您的反馈。
    Jason,抱歉我有一事不明白。请帮忙。
    我读了您关于“词嵌入”技术的文章。我看到您在使用带有卷积层的嵌入层作为特征提取器时,总是使用一维版本。
    既然机器将句子视为矩阵,为什么我们不基于 Conv2D 呢?

    • Jason Brownlee 2017年11月1日凌晨5:47 #

      好问题。

      词序列是整数的一维向量。嵌入将每个整数映射到一个实向量,所以现在我们有了一个向量序列。它仍然是一维序列,只是碰巧序列中的每个项都有许多特征。

      它不像图像那样在两个维度上具有空间关系。

      这有帮助吗?

  4. Alexander 2017年11月1日晚上6:19 #

    感谢 Jason 清晰的解释。
    我试图找到一种方法来最好地利用我们拥有的嵌入层中的知识。

  5. Ramesh Subrahmanyam 2017年11月5日凌晨9:12 #

    极好的帖子。谢谢。

  6. Amit Adesara 2017年11月15日晚上9:54 #

    感谢您的精彩文章。热切期待您的新书发布。我有一个关于测试/训练集分割的问题。与其定义 X 和 Y 测试/训练集,难道我们不能直接使用 sklearn 的 split 模型吗?它不会自动将整个数据集分割成训练集和测试集吗?谢谢。

    • Jason Brownlee 2017年11月16日凌晨10:30 #

      谢谢 Amit!

      是的,您可以根据需要使用 sklearn。

  7. Abdur Rehman Nadeem 2017年12月15日凌晨8:50 #

    你好 jason,

    抱歉,我又问了一个在其他博客中提到过的问题:如果我使用自己的数据集怎么办?如何使我的数据集与上面预构建的数据集兼容?我有一个推文数据集,那么如何制作我的正面和负面推文数据集,然后将它们用作测试和训练集?

  8. Vladimir 2018年1月23日凌晨1:14 #

    感谢 Jason 的宝贵文章!它本身就是一次探索。
    我也发现,将嵌入层作为模型的一部分进行学习,比使用预定义的嵌入效果更好。

    起初我对使用 GloVe 嵌入非常兴奋,但它效果很差。我认为这是因为真实世界的文本包含不同的词形(例如:cat,cats),而 GloVe 只为每个词的单个词形提供嵌入(例如:cat)。即使是很小的偏差也被视为不同的词,因此被忽略。也许如果解决了这个“词形”问题,GloVe 就能显示出巨大的结果……

    • Jason Brownlee 2018年1月23日凌晨8:04 #

      在一般情况下,您可能是对的。词汇/词语使用/等是否与要解决的问题很好地匹配也至关重要。

  9. Michelle 2018年2月27日下午2:05 #

    你好,

    我正在遵循这个例子来分类恶意 URL。我能够过滤单词,对训练和测试数据进行编码和填充。但是,当我将训练数据应用到模型时,会出现错误。

    您的代码是否已上传到 GitHub?我想运行代码进行调试。

    谢谢!

  10. A.S 2018年3月13日晚上7:56 #

    你好,这非常有帮助,谢谢!有 Java 版本吗?
    谢谢

  11. pANTHER 2018年3月24日晚上9:48 #

    这个函数如何

    “encoded_docs = tokenizer.texts_to_sequences(test_docs)”

    在未调用时索引测试词汇

    “tokenizer.fit_on_texts(train_docs)”

    在 test_docs 上。

    • Jason Brownlee 2018年3月25日凌晨6:29 #

      它使用从训练数据中学到的词汇来索引测试中的词。如果有新词,它们将被标记为零。

      • pANTHER 2018年4月1日凌晨1:31 #

        谢谢,非常感谢您的帮助。

  12. pANTHER 2018年3月24日晚上11:35 #

    我们可以将 CNN 用于多类别问题吗?

    • Jason Brownlee 2018年3月25日凌晨6:30 #

      是的。

      • Harini V 2021年1月26日晚上11:24 #

        为什么要使用 CNN,因为有很多深度学习算法?

        • Jason Brownlee 2021年1月27日凌晨6:07 #

          CNN 对某些问题很有效,例如,在文本分类任务中,与其他方法相比,它的效果非常好(平均而言)。

  13. Jin 2018年4月23日凌晨3:32 #

    Jason,感谢您的分享。对于 Keras 中的词嵌入层,窗口大小是多少?例如,在 word2vec 中,我们可以将窗口大小设置为 5,但在 Keras 嵌入层中,没有这个参数。

    • Jason Brownlee 2018年4月23日凌晨6:23 #

      窗口大小是指在构建模型时,考虑每个词周围的词数量,即上下文。

      Keras 不需要这个,因为嵌入是通过在训练过程中反向传播误差来构建的,理想情况下使用 BPTT,它会在输入时间步长中累积误差。

      根据我的实验,我发现 Keras 方法比使用预构建模型效果更好。直觉上应该相反,但在我的经验中并非如此。

      • Jin Zhou 2018年4月23日上午10:45 #

        我读了您关于使用 LSTM 构建语言模型的博客,并且尝试使用预训练的嵌入权重,实际上得到了较低的困惑度,但 BLEU 分数略低。所以,我很难说哪一个更好。

        感谢您的博客!我从中学到了很多。

  14. Anam 2018年5月8日下午4:15 #

    亲爱的 Jason,
    在上面的帖子中,您使用了 CNN 模型进行数据准备和嵌入层训练任务。请问,您能否指导我如何执行
    (i) .数据准备
    (ii).训练嵌入层
    在 LSTM 循环神经网络中使用,而不是 CNN?或者在完成这两项任务后,我该如何使用 LSTM 循环神经网络而不是 CNN?
    感谢您的时间!

  15. Anam 2018年5月9日下午2:59 #

    谢谢先生的指导。

  16. Maryam 2018年6月13日凌晨8:04 #

    嗨,Jason,
    我非常感谢这个实用的教程。我是 Keras 和深度学习的初学者。我应用了一个关于 2 种疾病的数据集。我想通过 GloVe 训练 RNN 以进行分类,但输出结果如下:
    精确率 0.0
    FPR 0.9999999999807433
    TPR 0.0
    FNR 0.999999999980609
    特异度 0.0
    准确率 0.0
    F 分数 0.0

    我认为这是因为 GloVe 没有针对疾病数据集进行预训练?
    我说对了吗?还是需要训练很多个 epoch?
    谢谢您的指导。
    祝好
    Maram

  17. Sarah 2018年6月21日凌晨9:51 #

    嗨,Jason,
    这太棒了,就像其他的教程一样。我没有单独的训练数据集和测试数据集,因为我想每次都随机选择测试数据集。所以我已经通过这个语句完成了:
    ‘from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(x_datasetpad,y_datasetpad,stratify=y_datasetpad,test_size=0.25)’
    根据您的教程,您是这样设置 ytest 的:
    ytest = array([0 for _ in range(100)] + [1 for _ in range(100)])

    我已经创建了 x_dataset,但我不知道如何创建 ydataset??
    请指引我,Jason,我真的需要它。

    Sarah

    • Jason Brownlee 2018年6月21日下午4:50 #

      输出将是每个输入评论的情感,或者代表情感类别的整数。

  18. Hegg 2018年6月21日晚上11:59 #

    你好 Jason,

    我一直在关注您精彩的教程,但在最后我自问:如何预测一个表示为字符串的新句子来获取它的情感?我认为会有更多的人想测试他们训练的网络用于一些示例输入。您能否为本教程添加这样一个部分,或者简要说明一下如何精确地做到这一点?例如

    exampleSentence = ‘The weather is very good today’
    prediction = trainedModel.predict(exampleSentence)

    print(sentimentForPrediction(prediction))

    诚挚的问候

    Hegg

    • Jason Brownlee 2018年6月22日凌晨6:10 #

      是的,您可以使用:;

      • Srijan Verma 2018年7月18日凌晨12:35 #

        嗨,Jason,
        我尝试实现您的一段代码来预测句子的情感。
        首先,我按照您的方式训练了模型。我在测试数据上获得了 86% 的准确率。
        这是我用来预测新句子的函数。

        # 将评论分类为负面(0)或正面(1)
        def predict_sentiment(review, vocab, tokenizer, model)
        # 清理
        tokens = clean_doc(review)
        # 按词汇过滤
        tokens = [w for w in tokens if w in vocab]
        # 转换为一行
        line = ‘ ‘.join(tokens)
        #print(line)
        # 编码
        tokenizer.fit_on_texts(line)
        encoded = tokenizer.texts_to_sequences(line)
        #print(encoded)
        # 预测
        max_length = max([len(s.split()) for s in line])
        pred = pad_sequences(encoded, maxlen=1317, padding=’post’)
        #print(pred)
        yhat = model.predict(pred, verbose=0)
        return round(yhat[0,0])

        # 测试正面文本
        text = ‘this is a good movie’
        print(predict_sentiment(text, vocab, tokenizer, model))
        # 测试负面文本
        text = ‘This is a bad movie.’
        print(predict_sentiment(text, vocab, tokenizer, model))

        不知何故,我在两种情况下都得到了“0”。我也尝试了其他测试用例,但结果总是为零。

        我找不到我哪里出错了。

        任何见解都会非常有帮助。

        谢谢!

        • Jason Brownlee 2018年7月18日凌晨6:37 #

          抱歉,我没有能力调试您的代码。也许可以试试 Stack Overflow?

          • Srijan 2018年7月18日晚上7:08 #

            假设我有一段原始文本,我想用 model.predict() 进行预测。
            第一步是将模型训练时使用的相同索引值分配给原始文本中的每个单词。
            然后,我们将需要将其转换为序列(使用 texts_to_sequences())。
            然后是填充(max_length 将与训练集相同)。
            然后将其输入到 model.predict()。

            这是正确的吗?^

          • Jason Brownlee 2018年7月19日凌晨7:48 #

            是的。对训练数据执行的所有准备工作,在您想用训练好的模型进行预测时,也必须对任何新数据执行。

          • Nanda Kishor M pai 2020年4月11日下午4:13 #

            我尝试以与上面相同的方式进行预测,无论评论如何,我的值都在 0.5100 左右……该怎么办?

          • Jason Brownlee 2020年4月12日凌晨6:14 #

            也许可以尝试从头开始重新拟合模型?
            也许可以尝试模型的不同配置或训练方式?
            也许可以尝试在进行预测时使用不同的数据?

  19. Sara 2018年6月26日凌晨12:25 #

    嗨,Jason,

    非常感谢您的精彩帖子。我一直很喜欢您的作品,它们对我有很大帮助。

    我的问题是如何同时处理其他特征和文本特征进行分类?我的意思是,如果每个评论都有其他特征,如词数、标点符号数、类别等,我该如何将其用于分类?

    祝好

  20. Anjali Batra 2018年7月31日凌晨2:18 #

    Jason,您好,精彩的文章。您能告诉我可以使用哪个 Python 版本来运行代码吗?
    因为 nltk 不能在 python 2.7 上运行,而 Keras 不能用于 python 3.6。

    期待您的回复。

    谢谢,
    Anjali Batra

    • Jason Brownlee 2018年7月31日凌晨6:10 #

      Python 3.5 或 3.6。我相信 Python 2.7 也可以工作,也许需要一些小的调整。

  21. Shreyas Jeet 2018年7月31日晚上7:28 #

    嗨,Jason,
    很棒的教程,非常有帮助。
    我正在做一个多类分类项目,您能否帮助我如何调整网络以支持 8 类分类器?

    谢谢你

    • Jason Brownlee 2018年8月1日凌晨7:42 #

      将输出层的节点数更改为 8,激活函数更改为 softmax,损失函数更改为 categorical cross entropy。

  22. Alberto 2018年8月27日凌晨1:15 #

    嗨,Jason,
    我有一个问题。为了开发词汇表,我需要同时使用训练和测试评论吗?
    非常感谢。

    • Jason Brownlee 2018年8月27日凌晨6:11 #

      理想情况下,您应该只使用训练数据来开发词汇表,并在评估模型时使用。

      在准备最终模型时,您将使用所有数据。

      这实际上取决于您的项目目标。

  23. Arghyadeep Giri 2018年9月20日下午1:38 #

    亲爱的 Jason,

    绝对喜欢这个教程。不过,我对卷积有一个疑问。您已经回答了一个关于它的问题,但我仍然有一个疑问。您提到嵌入层的输出是一维序列。
    但嵌入层的输出形状是 (None, 1317, 100)。我知道“None”指的是训练样本数量的批次大小。但是,如何用一维滤波器大小为 8 的卷积处理 (1317, 100) 形状?我想深入了解一下。这些值是如何相乘的?由于卷积层的输出形状是 (1310, 32),我唯一能理解的方式是,对于每个滤波器,有 100 个值与某些词的每个序列相乘。如果我错了,请纠正我。

    此致,
    Arghyadeep

    • Jason Brownlee 2018年9月20日下午2:28 #

      不,输入是整数序列。输出是向量序列。

      • Arghyadeep Giri 2018年9月20日下午3:04 #

        是的,绝对!但我相信那是针对嵌入层的。

        但我的问题是关于卷积层的。输入形状 (None, 1317, 100) 是如何转换为 (None, 1310, 32) 的?

        32 来自滤波器的数量。
        1317 转换为 1310 是因为 (1317-8+1),这是核大小。
        数字 100 呢?

        • Jason Brownlee 2018年9月21日凌晨6:22 #

          100 是每个词向量的长度。

          • Arghyadeep Giri 2018年9月21日早上10:05 #

            谢谢 🙂

  24. Ikib Kilam 2018年11月16日下午6:28 #

    Jason,

    在“训练嵌入层”代码中,为什么在将词汇表大小传递给嵌入层之前要加 1?您说:“……加上未知词的一个”,但根据定义,训练数据中没有未知词。当我运行您的代码而不加 1 时,它在拟合训练数据时会出错。当我加上 1 时,它运行正常。我不确定为什么,希望您能详细说明。

    • Jason Brownlee 2018年11月17日凌晨5:44 #

      使用模型时可能会出现未知词,例如测试数据或新数据。

      • ikib 2018年11月17日早上9:46 #

        谢谢 Jason。如果我正确理解您的回答……在测试数据或任何新数据中的未知词,不会被分配整数编码,因为我们在处理这些新数据集时也使用了用于训练数据的相同分词器。所以未知词在我们运行这些新数据集时不会出现。我仍然不确定为什么需要加 1,因为根据定义,训练数据中没有未知词。我遗漏了什么,特别是当不加 1 时,代码在拟合训练数据阶段就会出错,并且远在我们处理测试/其他数据集之前。与您的代码的一个区别是,我使用的是 MLP 而不是 CNN 进行训练。我将尝试进一步研究这个问题,但如果您有额外的见解,请回复。

        • Jason Brownlee 2018年11月18日凌晨6:35 #

          是的。我们加 1 是因为已知词以 1 开头而不是 0,例如,1 偏移量。

  25. Ikib Kilam 2018年11月18日 下午2:00 #

    谢谢。当然。我早就该注意到这个偏移量了。

  26. Johnny 2018年11月23日 下午2:50 #

    嗨,Jason,

    感谢您的分享。我训练了一个使用预训练的Glove向量的CNN模型,用于简历数据的文本分类。我已经得到了向量形式的结果,我想知道如何将其转换回文本,以便我们可以用实际含义来解释它。或者有更好的方法吗?

    谢谢,

    • Jason Brownlee 2018年11月24日 上午6:28 #

      我不确定我是否理解。你可以绘制词嵌入中的词,但这并不能告诉你太多关于简历的信息。

  27. chakib arsalan 2018年11月27日 上午2:05 #

    你好,我有两个疑问,
    – 你解释了(3.训练嵌入层)和(4.训练word2vec嵌入),
    我们必须选择其中一种方法,还是其中一种是另一种的补充?

    – 另外,如果我想输入一个新句子并对其进行分类(正面或负面),我该怎么做?

    • Jason Brownlee 2018年11月27日 上午6:36 #

      您可以使用最终模型进行如下预测:

      yhat = model.predict([asdasdasd])

      • chakib arsalan 2018年11月29日 上午10:17 #

        当我为新句子进行预测时,例如

        phrase = “very bad feeling”
        tokens = tokenizer.texts_to_sequences([phrase])
        model.predict(np.array(tokens))

        它返回
        array([[0.99999934]], dtype=float32)

        我怎么知道这是(正面或负面)情绪?

        • Jason Brownlee 2018年11月29日 下午2:39 #

          您可以使用 `predict_class()` 来获取 0/1 值,或者直接解释概率。

          我认为接近 0 的值表示负面,接近 1 的值表示正面。

          • chakib arsalan 2018年12月11日 上午12:17 #

            word2Vec 是否优于简单的 Embedding Layer?

          • Jason Brownlee 2018年12月11日 上午7:45 #

            它们是不同的,也许可以都尝试一下,看看哪种最适合您的特定数据集。

  28. Avir 2018年12月30日 下午8:16 #

    你好,
    这是一个非常好的教程,但我需要一些澄清。
    在本例中,您使用 word2vec 模型来用于 rnn 模型。该 rnn 模型用于预测词语的情绪。您创建的 word2vec 模型的确切用途(目的)是什么?为什么这些词嵌入对这些分析如此有帮助?

  29. Sam Donaldson 2019年1月18日 上午9:39 #

    嗨 Jason,写得很好。我正在尝试直观地理解这些高维表示如何有效地聚类。目前看来有点神奇。这是因为不断地训练以最小化损失吗?反向传播会向下作用于嵌入层并相应地修改这些词向量的权重吗?如果这是正确的,我将如何理解这会导致聚类?

    • Jason Brownlee 2019年1月18日 上午10:17 #

      结果是相似的导入映射到 n 维空间中的相似向量或点。

      训练会为了效率而将相似的事物推到一起——将向量分组可以降低损失函数的成本。

      这太神奇了。真的!

      • Sam Donaldson 2019年1月19日 上午7:01 #

        非常有帮助。最后几个问题,以便更深入地理解正在发生的事情。

        问题 1:为了让这种魔法真正起作用,训练样本必须包含彼此相关的数据吗?其中一些数据需要与其他训练样本共享吗?我可以想象一个数据图,其中相似的数据已经相互连接,算法通过拟合函数来填充向量值,告诉我们它们是如何聚类的以及它们的强度。我方向对了吗?

        问题 2:从更高层面来看,当我们想查找相似性或围绕数据创建集群/分组时,是否应该考虑使用嵌入?我正在尝试理解何时最好将分类字段转换为嵌入。例如,在结构化数据中,您将如何处理日期或类别,使用深度学习?

        谢谢 Jason。

        • Jason Brownlee 2019年1月19日 上午8:16 #

          是的,通常需要更丰富的数据才能让模型理解。这很难,所以我们通过大量的、成千上万甚至数百万的例子来解决。

          是的,当你希望模型学习类别在您正在解决的问题的上下文中如何分组/最佳分组时。天、月、商店等。这些都是嵌入可以帮助的很好的例子。这是一个新兴的领域,除了随机的 Kaggle 报告外,论文很少。我希望在今年晚些时候深入研究这个主题。

          • Sam Donaldson 2019年1月25日 上午6:21 #

            谢谢 Jason。再问几个问题,以便我能学到更多。

            — 到目前为止,我看到的创建嵌入的例子有两种形式

            1) 协同过滤(Netflix 等),它接收两个嵌入,对它们进行点积,然后将它们通过一些层和一些输出。然后将输出与标签进行比较,反向传播通过调整嵌入权重来拟合输出。

            2) 在本例中,任务是计算例如销售预测,但模型将一些代表分类变量(如月份中的某一天或年份等)的嵌入作为输入。

            我需要一些帮助来理解 2) 中这些分类变量的嵌入是如何学习有意义的权重的。我之所以这样问,是因为 2) 中的损失函数直接与销售预测相关,而不是像 1) 中那样,目标是将嵌入的点积尽可能地接近标签。

            您能否阐明 2) 以及在更结构化的神经网络问题中这些分类变量的嵌入是如何学习的?权重是如何变得有意义的?

          • Jason Brownlee 2019年1月25日 上午8:49 #

            它会根据特定任务的损失来学习如何最好地对天或月进行分组。没什么复杂的。

            也许可以先制作一个原型示例,看看效果如何?

  30. Ratha 2019年1月21日 下午10:37 #

    可以读取印度语言来创建 word2vec 吗?

  31. Radifan 2019年1月27日 下午6:47 #

    Jason 先生您好

    您的文章对我的学习非常有帮助,所以我有一个问题

    在使用嵌入层之后的 Conv1D 层的 CNN 模型中,Conv1D 层的输出是什么?我的意思是,这一层的输出是值、模式、情感还是其他什么?

    • Jason Brownlee 2019年1月28日 上午7:13 #

      它将是对输入分布式表示的卷积。

      也许我没有完全理解你的问题?

      • Radifan 2019年1月29日 下午3:18 #

        我的意思是,输入分布式表示的卷积是否代表输入推文的情感特征还是其他什么?

        • Radifan 2019年1月29日 下午4:23 #

          哦,抱歉……在我提出的问题中,那不是输入推文,而是输入文本评论。

        • Jason Brownlee 2019年1月30日 上午8:05 #

          是的,每个词的分布式表示的聚合或连接就是“文本”,然后对其应用卷积。但这并没有真正意味着什么。

  32. congmin 2019年1月28日 下午7:04 #

    Jason:本教程中使用的 IMDB 数据集是否与斯坦福大学的 IMDB 数据集不同?

  33. congmin 2019年1月29日 下午6:41 #

    但是斯坦福的数据集有 50000 条评论,而这个数据集只有 2000 条。

    • Jason Brownlee 2019年1月30日 上午8:06 #

      也许是其中的一部分,您可以在此处了解更多信息
      https://keras.org.cn/datasets/#imdb-movie-reviews-sentiment-classification

      • congmin 2019年1月30日 下午1:49 #

        “评论已预处理,每条评论都编码为单词索引序列(整数)。为了方便起见,单词按数据集中整体频率索引,因此例如整数“3”编码数据中第三个最频繁的单词。”。关于“关于这一点,我想知道如何对频率相同的单词进行编码,因为在实践中,大型语料库中的许多单词出现的次数都相同。但是数组索引不允许重复。在 Keras 中如何处理这个问题?

        • Jason Brownlee 2019年1月30日 下午2:43 #

          它们仍然按排名排序并分配唯一的整数。

          • congmin 2019年1月30日 下午5:18 #

            例如,如果两个单词“dog”和“cat”都出现 3 次,它们会得到不同的索引吗?但文档说“单词按整体频率索引”。相同的频率计数“3”如何索引两个不同的单词?仍然感到困惑……

          • Jason Brownlee 2019年1月31日 上午5:27 #

            不,词汇表中 dog 的所有实例都将具有相同的索引。

  34. congmin 2019年1月29日 下午6:43 #

    使用 Glove 嵌入,我获得了 86% 的准确率,使用稍微复杂一些的模型和更小的批次大小=8

    # 定义模型
    model = Sequential()
    model.add(embedding_layer)
    model.add(Conv1D(filters=32, kernel_size=8, activation=’relu’))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(12, activation=’relu’))
    model.add(Dropout(0.4))
    model.add(Dense(1, activation=’sigmoid’))# 编译网络
    model.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])
    # 拟合网络
    model.fit(Xtrain, ytrain, epochs=10, batch_size=8, verbose=2)

    • Jason Brownlee 2019年1月30日 上午8:06 #

      干得好!

    • Congmin 2019年1月31日 上午6:36 #

      “不,词汇表中 dog 的所有实例都将具有相同的索引。” dog 的索引呢?它也出现 3 次。

      • Jason Brownlee 2019年1月31日 下午2:13 #

        我不明白,您能详细说明一下您的问题吗?

        • congmin 2019年1月31日 下午3:01 #

          在这里:如果两个单词“dog”和“cat”都出现 3 次,它们会得到不同的索引吗?但文档说“单词按整体频率索引”。我的问题是,具有相同频率的两个不同单词是如何索引的?

          • Jason Brownlee 2019年2月1日 上午5:31 #

            很抱歉造成困惑。

            会计算每个单词的频率,然后对单词进行排名排序,并根据其排名顺序分配索引。

            dog = 1
            cat = 2

        • congmin 2019年2月1日 下午2:10 #

          dog = 1
          cat = 2

          如果两个单词的频率相同,即 100,那么它们是如何排名的?

          • Jason Brownlee 2019年2月2日 上午6:06 #

            一个在前,一个在后,但排序算法选择的具体顺序并不重要。就像对任何列表进行排序时,两个项目的数值相同一样。最终必须选择一个顺序,通常是排序算法首先遇到的顺序。

  35. congmin 2019年1月30日 下午5:21 #

    “ytest = array([0 for _ in range(100)] + [1 for _ in range(100)])”,@Jason,这是“0”表示正面,“1”表示负面吗?通常是相反的。只是好奇

  36. Ratha 2019年2月18日 下午4:13 #

    如何在 CNN 模型中使用 word2vec 和形容词数量作为特征?如何将形容词数量添加为一个层?

    • Jason Brownlee 2019年2月19日 上午7:20 #

      也许它是一个独立的输入,与 word2vec 的输出合并?

  37. Ratha 2019年2月18日 下午4:37 #

    嗨,Jason,
    感谢这个精彩的教程。
    我为我的数据集尝试了您的 word2vec 模型。
    我对这一行有一个疑问

    # 创建嵌入层
    embedding_layer = Embedding(vocab_size, 100, weights=[embedding_vectors], input_length=max_length, trainable=False)

    我用 fasttext 模型替换了 weights=[embedding_vectors]。我得到了相同的准确率。为什么会这样?显然有些地方出了问题。我使用了和您一样的代码。

    此外,如何在 CNN 中使用形容词数量作为特征,并与 word2vec 一起使用?

  38. Radifan 2019年2月20日 下午11:04 #

    嗨,Jason 先生
    感谢这个精彩的解释。

    我目前正在做一个情感分析项目,提取推特上的正面和负面情绪。
    我尝试使用上述教程作为我项目的指南,即使用词嵌入和卷积神经网络进行推特情感分析。
    但当将其应用于多个数据集时,准确率结果很低,即约 66.6%、67.6% 和 69%。
    问题是,我应该怎么做才能提高我项目的准确率?需要做哪些更改才能提高其准确率?

  39. Steve 2019年3月3日 下午2:12 #

    尊敬的Jason先生,

    谢谢!这是一个很棒的教程。
    我需要一些关于我目前正在做的事情的小帮助。

    我正在尝试构建一个神经网络,该网络可以为给定的评论预测 1 到 5 的分数。
    我目前使用的数据集有两个字段——评论文本 | 评分。
    评分范围是 1 到 5(浮点数)

    我遵循了您的步骤,但在您的实例中,y 值是 1 和 0。但我的数据集的评分范围是 1 到 5。
    我的模型应该预测 1 到 5 范围内的单个值。

    您知道我应该如何将 y 值传递给模型的正确方法吗?

    我期待您的回复。

    谢谢。

    • Jason Brownlee 2019年3月4日 上午6:57 #

      也许可以尝试将其建模为回归,然后尝试多类分类并比较性能?

  40. Steve 2019年3月4日 上午9:39 #

    尊敬的Jason先生,

    我只是检查一下我是否做对了,因为当我用真实数据预测时,我得到了所有的 4 类预测 🙁
    准确率真的很低——大约 50-65。
    以下是我配置的方式。

    如果您发现任何可以改进的地方,请分享 🙂

    我期待您的回复。

    谢谢。

    • Jason Brownlee 2019年3月4日 下午2:18 #

      我有一些关于诊断和改进模型性能的建议
      https://machinelearning.org.cn/start-here/#better

      • Steve 2019年3月4日 下午4:22 #

        非常感谢,修改后会向您汇报 🙂
        谢谢!🙂

        • Steve 2019年3月20日 下午10:32 #

          尊敬的Jason先生,

          我已经尝试了您的建议,它们确实很有帮助。
          现在我的模型看起来如下。

          model = Sequential()
          model.add(Embedding(vocab_size, 100, input_length=max_length))
          model.add(Conv1D(filters=32, kernel_size=8, activation=’relu’))
          model.add(MaxPooling1D(pool_size=2))
          model.add(Flatten())
          model.add(Dense(100, activation=’relu’))
          model.add(Dropout(0.5))
          model.add(Dense(50, activation=’relu’))
          model.add(Dropout(0.5))
          model.add(Dense(5, activation=’softmax’))

          model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])

          callback = [PrintDot(), tensorboard]

          # 拟合网络
          model.fit(final_X_train, final_Y_train, epochs=5, batch_size=128, validation_split=0.1, callbacks=callback)

          *我正在构建一个模型来为给定的评论输出一个 1-5 的评分。我正在用超过 400,000 条评论训练模型,但在下采样后,每类减少到 35,000 条评论。

          *我的问题是,在训练时,训练准确率在增加,训练损失在减少,但尽管验证准确率在增加,验证损失在 2-3 个 epoch 后仍在下降。这是其中一个训练记录。

          ## 5 个 epoch – 128 批次大小
          # loss: 1.0795 – acc: 0.5098 – val_loss: 0.8838 – val_acc: 0.6141
          # loss: 0.8516 – acc: 0.6331 – val_loss: 0.8025 – val_acc: 0.6596
          # loss: 0.7026 – acc: 0.7108 – val_loss: 0.7508 – val_acc: 0.7037
          # loss: 0.5383 – acc: 0.7922 – val_loss: 0.7744 – val_acc: 0.7265
          # loss: 0.4082 – acc: 0.8505 – val_loss: 0.8536 – val_acc: 0.7405
          # 总准确率是:0.6314016726089743

          这肯定是一种过拟合行为。
          **但当我尝试增加数据,增加另外 200,000 个数据样本时,验证准确率在第 2 个 epoch 后也开始下降。

          您对这个问题有什么看法吗?非常感谢您的帮助。

          我期待您的回复。

          谢谢。

  41. Liangqun 2019年3月6日 下午1:45 #

    在示例中,学习到的权重比预训练权重表现更好。有什么方法可以从模型中获取学习到的权重吗?以及通过可视化它们有何不同?

    • Jason Brownlee 2019年3月6日下午2:47 #

      是的,您可以保存嵌入层并使用它来获取单词的向量。

      它们将特定于神经网络模型,例如,针对最小化损失。

  42. sun 2019年3月22日晚上11:29 #

    theano_compilation_error_qi7q8r0_

    —————————————————————————

  43. sun 2019年3月25日下午3:19 #

    WARNING (theano.gof.compilelock): Overriding existing lock by dead process ‘45020’ (I am process ‘13088’)

    您可以在此临时文件中找到 C 代码:C:\Users\DES\AppData\Local\Temp\theano_compilation_error_yr3062kk

    —————————————————————————
    异常回溯(最近一次调用)
    in ()
    127 # define model
    128 model = Sequential()
    --> 129 model.add(embedding_layer)
    130 model.add(Conv1D(filters=128, kernel_size=5, activation=’relu’))
    131 model.add(MaxPooling1D(pool_size=2))

    G:\anaconda\lib\site-packages\keras\engine\sequential.py in add(self, layer)
    163 # and create the node connecting the current layer
    164 # to the input layer we just created.
    --> 165 layer(x)
    166 set_inputs = True
    167 else

    G:\anaconda\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    429 ‘You can build it manually via: ‘
    430 ‘layer.build(batch_input_shape)‘)
    --> 431 self.build(unpack_singleton(input_shapes))
    432 self.built = True
    433

    G:\anaconda\lib\site-packages\keras\layers\embeddings.py in build(self, input_shape)
    107 regularizer=self.embeddings_regularizer,
    108 constraint=self.embeddings_constraint,
    --> 109 dtype=self.dtype)
    110 self.built = True
    111

    G:\anaconda\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
    89 warnings.warn(‘Update your ' + object_name + ' call to the ‘ +
    90 ‘Keras 2 API: ‘ + signature, stacklevel=2)
    —> 91 return func(*args, **kwargs)
    92 wrapper._original_function = func
    93 return wrapper

    G:\anaconda\lib\site-packages\keras\engine\base_layer.py in add_weight(self, name, shape, dtype, initializer, regularizer, trainable, constraint)
    247 if dtype is None
    248 dtype = K.floatx()
    --> 249 weight = K.variable(initializer(shape),
    250 dtype=dtype,
    251 name=name,

    G:\anaconda\lib\site-packages\keras\initializers.py in __call__(self, shape, dtype)
    110 def __call__(self, shape, dtype=None)
    111 return K.random_uniform(shape, self.minval, self.maxval,
    --> 112 dtype=dtype, seed=self.seed)
    113
    114 def get_config(self)

    G:\anaconda\lib\site-packages\keras\backend\theano_backend.py in random_uniform(shape, minval, maxval, dtype, seed)
    2598 seed = np.random.randint(1, 10e6)
    2599 rng = RandomStreams(seed=seed)
    -> 2600 return rng.uniform(shape, low=minval, high=maxval, dtype=dtype)
    2601
    2602

    G:\anaconda\lib\site-packages\theano\sandbox\rng_mrg.py in uniform(self, size, low, high, ndim, dtype, nstreams, **kwargs)
    870 if nstreams is None
    871 nstreams = self.n_streams(size)
    --> 872 rstates = self.get_substream_rstates(nstreams, dtype)
    873
    874 d = {}

    G:\anaconda\lib\site-packages\theano\configparser.py in res(*args, **kwargs)
    115 def res(*args, **kwargs)
    116 with self
    --> 117 return f(*args, **kwargs)
    118 return res
    119

    G:\anaconda\lib\site-packages\theano\sandbox\rng_mrg.py in get_substream_rstates(self, n_streams, dtype, inc_rstate)
    777 # If multMatVect.dot_modulo isn’t compiled, compile it.
    778 if multMatVect.dot_modulo is None
    --> 779 multMatVect(rval[0], A1p72, M1, A2p72, M2)
    780
    781 # This way of calling the Theano fct is done to bypass Theano overhead.

    G:\anaconda\lib\site-packages\theano\sandbox\rng_mrg.py in multMatVect(v, A, m1, B, m2)
    60 o = DotModulo()(A_sym, s_sym, m_sym, A2_sym, s2_sym, m2_sym)
    61 multMatVect.dot_modulo = function(
    ---> 62 [A_sym, s_sym, m_sym, A2_sym, s2_sym, m2_sym], o, profile=False)
    63
    64 # This way of calling the Theano fct is done to bypass Theano overhead.

    G:\anaconda\lib\site-packages\theano\compile\function.py in function(inputs, outputs, mode, updates, givens, no_default_updates, accept_inplace, name, rebuild_strict, allow_input_downcast, profile, on_unused_input)
    315 on_unused_input=on_unused_input,
    316 profile=profile,
    --> 317 output_keys=output_keys)
    318 return fn

    G:\anaconda\lib\site-packages\theano\compile\pfunc.py in pfunc(params, outputs, mode, updates, givens, no_default_updates, accept_inplace, name, rebuild_strict, allow_input_downcast, profile, on_unused_input, output_keys)
    484 accept_inplace=accept_inplace, name=name,
    485 profile=profile, on_unused_input=on_unused_input,
    --> 486 output_keys=output_keys)
    487
    488

    G:\anaconda\lib\site-packages\theano\compile\function_module.py in orig_function(inputs, outputs, mode, accept_inplace, name, profile, on_unused_input, output_keys)
    1839 name=name)
    1840 with theano.change_flags(compute_test_value=”off”)
    -> 1841 fn = m.create(defaults)
    1842 finally
    1843 t2 = time.time()

    G:\anaconda\lib\site-packages\theano\compile\function_module.py in create(self, input_storage, trustme, storage_map)
    1713 theano.config.traceback.limit = theano.config.traceback.compile_limit
    1714 _fn, _i, _o = self.linker.make_thunk(
    -> 1715 input_storage=input_storage_lists, storage_map=storage_map)
    1716 finally
    1717 theano.config.traceback.limit = limit_orig

    G:\anaconda\lib\site-packages\theano\gof\link.py in make_thunk(self, input_storage, output_storage, storage_map)
    697 return self.make_all(input_storage=input_storage,
    698 output_storage=output_storage,
    --> 699 storage_map=storage_map)[:3]
    700
    701 def make_all(self, input_storage, output_storage)

    G:\anaconda\lib\site-packages\theano\gof\vm.py in make_all(self, profiler, input_storage, output_storage, storage_map)
    1089 compute_map,
    1090 [],
    -> 1091 impl=impl))
    1092 linker_make_thunk_time[node] = time.time() – thunk_start
    1093 if not hasattr(thunks[-1], ‘lazy’)

    G:\anaconda\lib\site-packages\theano\gof\op.py in make_thunk(self, node, storage_map, compute_map, no_recycling, impl)
    953 try
    954 return self.make_c_thunk(node, storage_map, compute_map,
    --> 955 no_recycling)
    956 except (NotImplementedError, utils.MethodNotDefined)
    957 # We requested the c code, so don’t catch the error.

    G:\anaconda\lib\site-packages\theano\gof\op.py in make_c_thunk(self, node, storage_map, compute_map, no_recycling)
    856 _logger.debug(‘Trying CLinker.make_thunk’)
    857 outputs = cl.make_thunk(input_storage=node_input_storage,
    -> 858 output_storage=node_output_storage)
    859 thunk, node_input_filters, node_output_filters = outputs
    860

    G:\anaconda\lib\site-packages\theano\gof\cc.py in make_thunk(self, input_storage, output_storage, storage_map, keep_lock)
    1215 cthunk, module, in_storage, out_storage, error_storage = self.__compile__(
    1216 input_storage, output_storage, storage_map,
    -> 1217 keep_lock=keep_lock)
    1218
    1219 res = _CThunk(cthunk, init_tasks, tasks, error_storage, module)

    G:\anaconda\lib\site-packages\theano\gof\cc.py in __compile__(self, input_storage, output_storage, storage_map, keep_lock)
    1155 output_storage,
    1156 storage_map,
    -> 1157 keep_lock=keep_lock)
    1158 return (thunk,
    1159 module,

    G:\anaconda\lib\site-packages\theano\gof\cc.py in cthunk_factory(self, error_storage, in_storage, out_storage, storage_map, keep_lock)
    1618 node.op.prepare_node(node, storage_map, None, ‘c’)
    1619 module = get_module_cache().module_from_key(
    -> 1620 key=key, lnk=self, keep_lock=keep_lock)
    1621
    1622 vars = self.inputs + self.outputs + self.orphans

    G:\anaconda\lib\site-packages\theano\gof\cmodule.py in module_from_key(self, key, lnk, keep_lock)
    1179 try
    1180 location = dlimport_workdir(self.dirname)
    -> 1181 module = lnk.compile_cmodule(location)
    1182 name = module.__file__
    1183 assert name.startswith(location)

    G:\anaconda\lib\site-packages\theano\gof\cc.py in compile_cmodule(self, location)
    1521 lib_dirs=self.lib_dirs(),
    1522 libs=libs,
    -> 1523 preargs=preargs)
    1524 except Exception as e
    1525 e.args += (str(self.fgraph),)

    G:\anaconda\lib\site-packages\theano\gof\cmodule.py in compile_str(module_name, src_code, location, include_dirs, lib_dirs, libs, preargs, py_module, hide_symbols)
    2386 # difficult to read.
    2387 raise Exception(‘Compilation failed (return status=%s): %s’ %
    -> 2388 (status, compile_stderr.replace(‘\n’, ‘. ‘)))
    2389 elif config.cmodule.compilation_warning and compile_stderr
    2390 # Print errors just below the command line.

  44. sun 2019年3月25日晚上3:20 #

    我遇到了上面的错误,我复制了你的代码

  45. Drew 2019年4月25日下午3:56 #

    您好 Jason,文章写得很好。

    当我复制粘贴代码来创建用于定义类别标签的数组时,我遇到了以下类型错误。您能帮帮我吗?我正在使用 Python 3。

    from array import array
    from __future__ import unicode_literals

    # 定义训练标签
    ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)])

    —————————————————————————
    TypeError Traceback (most recent call last)
    in ()
    3
    4 # define training labels
    ----> 5 ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)])

    TypeError: must be a unicode character, not list

  46. Avinash 2019年6月21日凌晨12:06 #

    # 定义训练标签
    ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)])
    这行代码是做什么的??

  47. Jeffrey 2019年6月25日凌晨12:36 #

    你好,

    我正试图用它来对存储在多个单独文本文件中的产品评论进行正面或负面情感分类。我该如何使用预训练模型来实现这一点?

  48. Sixto Robayo 2019年7月24日下午3:37 #

    Jason,恭喜,这是一个很好的教程。请帮帮我,我必须对全球变暖进行情感分析,从推特上获取数据,比如 10,000 条推文。这种方法如何应用,也就是说,预训练的词嵌入来确定情感的极性,正面、中性、负面。提前感谢。

    致以最诚挚的问候。

  49. Sixto Robayo 2019年7月29日早上6:48 #

    尊敬的 Jason,

    您建议我使用什么工具或什么程序来获取推文的极性或情感分数,以便继续进行情感分析。我已收集了 10,000 条推文,并按照以下建议进行了清理:https://machinelearning.org.cn/clean-text-machine-learning-python/

    提前感谢。

  50. Arjun Bali 2019年8月22日早上5:45 #

    嗨 Jason,我想向您请教如何将从 word2vec 开发的嵌入模型输入到神经网络以外的分类器中。我曾考虑过,也许我们需要将每个文档表示为一个单独的向量,为此,我们可能需要对我们生成的词嵌入进行平均,或者使用 tf-idf 权重进行加权平均。

    • Jason Brownlee 2019年8月22日早上6:33 #

      您输入的嵌入向量将与其他输入连接起来,然后馈送到模型中。

  51. Rango 2019年9月12日凌晨2:24 #

    首先,感谢您发表了这篇精彩的文章。我想问一些问题。如果我们训练的 word2vec 模型比标签训练集更大的数据集,我们能否获得对标签训练集中不存在的新词的泛化能力?
    例如……
    在训练集中,“My Puppies are small”这些词是存在的。
    测试样本“I have two little puppies”。
    “little”这个词不在训练集中,但在 word2vec 词汇表中。由于“little”和“small”的意思相似,我们能否对两个句子获得相似的结果?如果我们能获得相似的结果,您能解释一下原因吗?
    提前感谢!!

    • Jason Brownlee 2019年9月12日早上5:21 #

      不,模型必须在训练期间看到这些词。它们必须是已知词汇的一部分。

  52. HSA 2019年11月16日早上7:36 #

    我反复阅读了这篇文章,仍然不明白训练嵌入层部分和 word2vec 部分的区别。我的意思是,word2vec 不是训练一个嵌入层吗?
    我希望我的问题清晰明了
    谢谢 Jason 教授

    • Jason Brownlee 2019年11月17日早上7:10 #

      word2vec 是通用方法,也是特定算法的名称。

      我们可以使用 word2vec 算法或神经网络来学习向量。

      这有帮助吗?

  53. HSA 2019年11月17日晚上7:59 #

    您的意思是,第 3 部分(训练嵌入层)与第 4 部分(训练 word2vec 嵌入)和第 5 部分(使用预训练嵌入)具有相同的目的吗?
    当您说(或神经网络)时,是指第三部分(训练嵌入层)吗?
    谢谢

    • Jason Brownlee 2019年11月18日早上6:45 #

      有许多方法可以开发词嵌入,例如独立的算法或作为神经网络的一部分。

      也许我不理解你的问题?

  54. HSA 2019年11月18日早上7:28 #

    上述文章的哪个部分代表了独立的算法,哪个部分代表了神经网络?
    先谢谢了

    • Jason Brownlee 2019年11月18日下午1:46 #

      标题为“Train Embedding Layer”的部分展示了如何在网络中训练嵌入层。

      标题为“Train word2vec Embedding”的部分展示了如何拟合一个 word2vec 独立模型,然后“Use Pre-trained Embedding”部分展示了如何在网络中使用它。

      也许重新阅读一下教程?里面都讲得很清楚了。

  55. HSA 2019年11月18日晚上6:26 #

    我已经读了很多遍了,但我仍然不确定在哪些部分可以独立使用它们(因为它们具有相同的目的)并比较结果。现在您的最后一个回答证实了我的理解。它表明第 3 部分独立于第 4 和第 5 部分,第 4 和第 5 部分必须结合起来才能与第 3 部分进行比较。
    非常感谢您,Jason 教授

  56. HSA 2019年11月19日凌晨1:36 #

    为什么在这段代码中 positive_lines 和 positive_docs 不同?
    # 加载训练数据
    positive_lines = process_docs(‘txt_sentoken/pos’, vocab, True)
    negative_lines = process_docs(‘txt_sentoken/neg’, vocab, True)
    sentences = negative_docs + positive_docs

    对于 negative_lines 和 negative_docs 也是同样的情况,看起来它们应该有相同的名称……我说得对吗?

    我的意思是像这样
    # 加载训练数据
    positive_docs= process_docs(‘txt_sentoken/pos’, vocab, True)
    negative_docs = process_docs(‘txt_sentoken/neg’, vocab, True)
    sentences = negative_docs + positive_docs

    • Jason Brownlee 2019年11月19日早上7:46 #

      我们调用的是相同的代码,但从不同的源目录加载。

  57. HSA 2019年11月19日晚上10:04 #

    也许您误解了问题
    # 加载训练数据
    positive_lines = process_docs(‘txt_sentoken/pos’, vocab, True)
    negative_lines = process_docs(‘txt_sentoken/neg’, vocab, True)
    sentences = negative_docs + positive_docs

    由于 negative_docs 和 positive_docs 未定义,所以会出现错误,因为我复制了整个代码,没有任何更改

  58. Fabien 2019年11月21日早上8:43 #

    嗨,Jason,

    我正在使用通过分词预处理的产品描述产生的数字序列。
    我正试图建立一个基于回归的 RNN 模型来预测产品价格。
    目前,我只添加了一个 LSTM 层和一个 Dense(1) 层作为输出。
    关于不同的层,您会如何设置这种模型?
    此外,在模型配置中,您会使用什么指标进行训练?

    如果我的问题有点含糊不清,我很抱歉
    谢谢你

    附注:我还有其他特征,但不知道如何处理它们(将它们连接起来形成一个完整的特征输入到模型中?还是只用其中一些?)

    • Jason Brownlee 2019年11月21日下午1:27 #

      我建议测试许多不同的模型和配置,并利用结果来指导探索。

      对于回归,MSE 或 RMSE 是一个不错的开始。另外,在拟合之前缩放数据可能有助于。

      如果您有描述,例如文本,词袋模型可以编码文本并由单独的输入馈送到模型中,例如,参见这里
      https://machinelearning.org.cn/keras-functional-api-deep-learning/

  59. martin 2019年11月22日晚上6:12 #

    在这个例子中,tokenizer.fit_on_texts 是在内部进行“独热编码”吗?用户无需担心编码。

  60. Nikolay Oskolkov 2019年11月27日早上8:42 #

    您好 Jason,为什么在这个教程中,Dense 网络 https://machinelearning.org.cn/deep-learning-bag-of-words-model-sentiment-analysis/ 的表现优于 CNN?

    • Jason Brownlee 2019年11月27日下午1:46 #

      很好的问题!

      这些模型仅用于演示(例如,这里是如何实现该方法的),两者都没有针对解决该问题进行优化。

      事实上,这适用于博客上的所有代码。

  61. HSA 2019年11月28日晚上10:09 #

    1-Google word2vec 使用 CBOW 和 skip-gram 来构建模型,我们在这里用什么来构建我们的预训练模型?

    2- 我想知道为什么 Glove 的模型是 .txt 格式文件,而 Google word2vec 是 .bin 格式?如果我使用其中一种格式,它会影响我的代码吗?例如,如果我使用 Google word2vec 而不是 Golve,我是否需要对代码进行一些更改?

    3- .bin 和 .txt 模型格式有相同的目的吗?如果它们有相同的目的但格式不同,哪种更好?

    谢谢,Jason 教授

    • Jason Brownlee 2019年11月29日早上6:49 #

      我们直接在模型中学习了嵌入。

      格式不同——我不知道。研究人员偏好。格式无关紧要。

      是的,两者都包含词向量。

  62. HSA 2019年11月29日晚上7:50 #

    我从阅读 Gensim 网站了解到 .txt 格式的模型称为 KeyedVectors,我的理解正确吗?
    https://radimrehurek.com/gensim/models/keyedvectors.html

  63. Makhloufi lyes 2020年1月2日晚上9:52 #

    你好 Jason,感谢您的教程。我有一个问题,当我将我的词汇表输入 Word2Vec 模型时,学习到的单词数量急剧减少,您能给我解释一下吗?

    • Lyes Makhloufi 2020年1月2日晚上9:53 #

      初始词汇量为 28830,但学习到的单词只有 119 个。

      • Jason Brownlee 2020年1月3日早上7:30 #

        也许您的单词不在预训练模型中。在这种情况下,您可能需要更改您的单词或训练您自己的嵌入。

    • Jason Brownlee 2020年1月3日早上7:29 #

      我不明白。抱歉,问题究竟是什么?

      • Lyes Makhloufi 2020年1月4日凌晨3:18 #

        是的,我正在尝试像您一样训练我的 word2vec 模型。

        model = Word2Vec(sentences, size=100, window=5, workers=8, min_count=1)

        我的 sentences 变量包含 28830 个句子,但我的词汇量长度是 119。

        words = list(model.wv.vocab)
        print(‘Vocabulary size: %d’ % len(words)) *** 这行打印出 119 ***

  64. Prashant Gavali 2020年1月11日凌晨12:44 #

    感谢您发表了如此精彩的帖子。我有一个问题。如果我使用 RNN 进行句子情感分类,是否还需要嵌入层,或者我们可以将每个单词的预训练词向量传递到每个时间步?如果我们必须使用嵌入层,input_length 的大小应该是什么?一个还是其他?提前感谢

    • Jason Brownlee 2020年1月11日早上7:26 #

      也许尝试不同的长度,看看哪种最适合您的数据集。

  65. Eric 2020年1月25日晚上5:48 #

    首先,我赞赏您的辛勤工作。您的内容在我开始这段旅程的每一天都对我非常有帮助。

    我也有一个问题。是否有理由不指定 batch-size?我见过所有书籍中的做法都是如此,但在这里我没有看到,我很想知道原因。

    • Jason Brownlee 2020年1月26日早上5:15 #

      谢谢!

      是的。我经常使用默认的 batch size 32。

  66. HSA 2020年1月30日上午2:58 #

    回溯(最近一次调用)

    raw_embedding = load_embedding(‘glove.6B/glove.6B/glove.6B.100d.txt’)

    embedding[parts[0]] = asarray(parts[1:], dtype=’float32′)

    返回数组(a, dtype, copy=False, order=order)
    ValueError: could not convert string to float: ‘ng’

    有没有人能帮我解释一下为什么这个错误会出现,尽管我复制粘贴的是相同的代码?
    只有当我删除 dtype=’float32′ 时,代码才能运行

  67. HSA 2020年1月31日上午1:51 #

    简单来说,前面提到的问题的解决方案是修复这行代码

    file = open(filename,’r’)

    改为
    file = open(filename,encoding=”utf8″)
    这可能会帮助遇到和我同样问题的人,
    谢谢你

  68. Rony Sharma 2020年2月15日上午1:54 #

    你好,Jason Brownlee,
    我正在使用您的代码,它对我来说非常棒。但遇到了很多问题,比如当我使用 700 个训练数据和 300 个测试数据时,出现了一个问题:

    ValueError: Input arrays should have the same number of samples as target arrays. Found 2700 input samples and 2100 target samples.

    如何解决这个问题?请帮助我。

    • Jason Brownlee 2020年2月15日上午6:35 #

      如果你分割了输入,你必须以相同的方式分割输出/目标数组。

  69. HSA 2020年2月15日晚上11:19 #

    我想知道为什么在分类部分需要使用词汇文本文件?
    我们在特征提取部分(当我们构建预训练模型时)使用它来保存语料库中最频繁的词,但为什么我们在分类部分构建模型时使用它,当我们读取任何数据集并根据预训练模型的特征进行分类时?
    鉴于在我从分类部分移除词汇文件后,f1-score 得到了提升,这让我开始疑惑为什么要在分类部分使用它??

    谢谢

    • Jason Brownlee 2020年2月16日上午6:07 #

      我相信我们用它来将数据修剪到预定义的词汇表中。

  70. Rony Sharma 2020年2月21日上午12:31 #

    亲爱的Jason Brownlee,

    你好吗?希望你一切安好。如何在嵌入层代码中实现 RNN 模型?请给我一些建议。另外,有没有关于如何实现带 RNN 的嵌入层的链接?我将不胜感激

    提前感谢

  71. HSA 2020年2月23日晚上11:04 #

    如何上传图片来阐明我的问题?

    • Jason Brownlee 2020年2月24日上午7:42 #

      网上有很多地方可以上传图片。博客、社交媒体、GitHub、Imgur 等。

      • HSA 2020年2月24日上午9:46 #

        嗯,我不知道你是否理解我的问题,我想在您的文章的评论区上传图片来提问,问题是依赖于图片的?

        • Jason Brownlee 2020年2月24日下午1:25 #

          是的。答案是将其上传到其他地方并链接到它。

  72. Md. Asraful Islam 2020年2月26日下午5:47 #

    亲爱的Jason Brownlee,

    你好吗?希望你一切安好。

    先生,我需要您的帮助。我需要为我的情感分析创建一个 glove 文件,但我不知道如何创建 glove 文件。我看到了您的网站,您在那里使用了预训练的 glove 代码,即 “glove.6B.100d.txt” 文件。但我需要为我的数据集创建 glove 文件。您能否给我一些关于如何创建自己的 glove.txt 文件的建议或代码?

  73. Saifur Rahman 2020年3月23日上午12:15 #

    亲爱的Jason Brownlee,
    在此 CNN 模型中使用了哪种类型的图?请给我一些建议?

    • Jason Brownlee 2020年3月23日上午6:13 #

      抱歉,我不明白。您具体想绘制什么?

      • Saifur Rahman 2020年3月24日上午12:48 #

        散点图。

  74. Rony Sharma 2020年3月27日上午12:24 #

    你好,

    如何在此模型或代码中获得 f1-score?

  75. Saifur Rahman 2020年4月14日上午1:05 #

    你好先生,
    在此代码中,如何获取混淆矩阵的值?请帮助我。

  76. Michael Szczepaniak 2020年4月22日上午3:27 #

    假设每个评论都为 0(负面)或 1(正面),是否有直接的方法可以看到模型为每个评论分配的概率?

    我将使用预训练的嵌入,并在模型根据一组文档进行训练后,我需要能够将模型发送给一个文档,并让它给我一个关于该文档是否与我的训练数据相关的概率(如果相关则接近 1,如果不相关则接近 0)。

  77. Michael Szczepaniak 2020年4月22日上午3:47 #

    是否有办法保存训练好的 CNN 模型本身?我需要创建很多这样的模型并进行版本控制,但现在,我只需要能够保存权重和配置,以便以后可以重新组合。

  78. Ibrahim 2020年5月5日凌晨3:38 #

    在您的模型中,您如何处理 OOV(词汇外)单词?
    我正在寻找实现字符级词嵌入来处理 OOV 单词。并且我在 Kim 的论文中找到了 1D CNN。但我不明白如何训练它们。以及如何找到嵌入矩阵。你能帮我吗?

    • Jason Brownlee 2020年5月5日上午6:35 #

      我们在预处理期间删除它们,或者将它们映射到索引 0 作为“未知”。

  79. Mohammad 2020年5月16日凌晨4:29 #

    嗨,Jason,

    首先,感谢您的精彩帖子!

    我有一个问题。想象一下,我有一个数据集,包含大约 2000 条评论,其中只有 200 条被认为是负面的,这意味着其余评论都显示正面情感。

    如果我在所有数据上训练模型,准确率约为 97%,我认为这有点不真实!但是,如果我选择 200 条负面评论和 200 条随机正面评论,并在 400 条数据上拟合模型,准确率会下降到 85%。哪种方法更具学术性、科学性和准确性?

  80. Mohammad 2020年5月16日上午8:12 #

    谢谢,Jason!这些都非常有帮助。

    我又有一个问题。我发现了这篇关于 CNN 嵌入层所需文本编码的帖子。

    https://machinelearning.org.cn/how-to-prepare-categorical-data-for-deep-learning-in-python/

    独热编码和 Word2Vec 函数之间有什么区别?哪个更强大?

    非常感谢!

    • Jason Brownlee 2020年5月16日上午10:12 #

      它们都是分布式表示。

      独热编码是稀疏且特定的。嵌入是学习到的,并且更灵活——能够适应数据的具体情况和模型。是的,它可以更有用/强大。

      尝试每种方法,并使用能提供最佳性能的方法。

      • Mohammad 2020年5月18日晚上6:43 #

        谢谢,

        我可以使用 Word2Vec 来处理非英语文本或标题吗?

  81. Dilani 2020年6月5日晚上7:18 #

    你好,

    我正在使用 LSTM 和 glove 预训练词嵌入来构建情感分析模型,代码几乎与您在此处编写的代码相似。目前我正在努力寻找一种方法来使用此模型来预测输入纯文本时的情感。我正在加载以 .h5 文件保存的模型,并且我正在对文本进行与训练模型时相同的预处理。除了这些,在调用 model.predict 方法之前我还需要做什么?

    我对机器学习是新手,因此迫切希望找到这个问题的答案。即使我搜索了,也找不到任何合适的解决方案。如果您能指导我,我将不胜感激。

    • Jason Brownlee 2020年6月6日上午7:48 #

      数据准备对象应与模型一起保存,例如,与用于准备训练集的对象相同。

      除此之外,您似乎走在正确的轨道上。也许您需要逐步调试您的代码。

  82. Jay 2020年6月20日下午3:29 #

    您好,假设我使用预训练的 GLove 或 Word2Vec 训练模型。但是当在全新的值上进行测试时,我是否需要获取给定输入的词向量?所以我需要更新嵌入层?

    • Jason Brownlee 2020年6月21日上午6:18 #

      如果文本包含嵌入层不认识的词,它将被映射到值 0,表示“未知”。

  83. Ahmad 2021年1月10日上午11:50 #

    感谢您的精彩帖子!

    如何使用 Python 中的机器学习算法来检测文本中的情感识别?

    • Jason Brownlee 2021年1月10日下午1:09 #

      也许可以从一个可以用来训练模型以识别您感兴趣的情感的数据集开始。

  84. SK 2021年3月26日上午9:08 #

    嗨,Jason,

    感谢您的精彩帖子!

    在您的帖子中,您使用了监督式神经网络模型来自动将电影评论分类为正面或负面。我想知道如何对未标记的电影评论进行分类或聚类为正面或负面,这是无监督方法。

    另外,您是否有关于“正面和负面词数据库”的信息,其中包含与情感分数(介于 -1(最负面)和 1(最正面)之间)相关联的英语单词。如果有,您最推荐哪一个?是免费的还是需要购买?

    谢谢你!!

    • Jason Brownlee 2021年3月29日上午5:48 #

      如果您有带有类标签的历史示例,则可以在可用数据上训练模型,然后使用该模型对新示例进行分类,将其归为两个标签之一。

      如果您没有标签,也许可以手动标记它们?

      如果您不需要/不想要标签,那么我认为这将是一个无监督学习问题。

  85. Sudhakar Vankamamidi 2021年3月29日凌晨2:29 #

    具有情感分析的代码示例会更有帮助

  86. SK 2021年3月29日上午7:22 #

    嗨,Jason,

    感谢您的回复。不,我没有带有类标签的历史示例,并且我希望避免因主观偏见而进行标记。

    是的,我认为这将是一个无监督学习问题,也是聚类方法,这就是为什么我想知道您是否有关于“正面和负面词数据库”的信息,其中包含与情感分数(介于 -1(最负面)和 1(最正面)之间)相关联的英语单词。如果有,您最推荐哪一个?是免费的还是需要购买?然后我就可以根据文档中单词的情感分数分布来对这些文档进行聚类了。谢谢!

    • Jason Brownlee 2021年3月30日上午5:52 #

      如果您没有标记数据并且不想标记它,那么这听起来确实是一个聚类问题。

      如果您想使用已分类数据的感情,那么这听起来像是一个直接的编程问题——而不是机器学习。

  87. Ali Al Bataineh 2021年3月29日上午11:35 #

    嗨,Jason,
    一如既往的精彩文章。
    您使用了分词器将单词映射到整数,这一点我非常理解,因为嵌入层期望输入是整数形式。对于 tf-idf 或独热编码方法,在使用它们之前,它们是否也期望输入是整数形式?最后一个问题是,嵌入层也要求所有输入都具有相同的长度;其他方法如 tf-idf 是否也要求相同?

    非常感谢!你是西部最好的!

    • Jason Brownlee 2021年3月30日上午5:54 #

      通常,词袋模型和独热编码方法允许您直接将文本转换为整数向量。

      嵌入层假定输入是整数,例如,序数编码的单词/类别。

  88. Emran 2021年4月5日凌晨2:52 #

    先生,您好,

    感谢这篇宝贵的文章。

    但是,我有一个问题,如果我想将数据集分成 80% 用于训练,20% 用于测试。那么,我该如何修改代码?

    我尝试了以下操作,但不起作用!

    def process_docs(directory, vocab, is_trian)
    documents = list()
    # 遍历文件夹中的所有文件
    for filename in listdir(directory)
    # 跳过测试集中的任何评论
    if is_trian and filename.startswith(‘cv8’) and filename.startswith(‘cv9’)
    continue
    if not is_trian and not filename.startswith(‘cv8’) and not filename.startswith(‘cv9’)
    continue
    # 创建要打开的文件的完整路径
    path = directory + ‘/’ + filename
    # 加载文档
    doc = load_doc(path)
    # 清理文档
    tokens = clean_doc(doc, vocab)
    # 添加到列表中
    documents.append(tokens)
    return documents

    # 定义训练标签
    ytrain = array([0 for _ in range(800)] + [1 for _ in range(800)])
    # 定义测试标签
    ytest = array([0 for _ in range(200)] + [1 for _ in range(200)])

    如果您能提供帮助,我将非常感激。

    • Jason Brownlee 2021年4月5日上午6:14 #

      您可以更改代码,使 000 到 799 用于训练,800 及之后的用于测试。

      抱歉,我没有精力审查你的代码。

  89. Eslam Khodair 2021年4月7日凌晨12:38 #

    你好 Jason,

    感谢您的清晰解释,
    我们可以为这项任务使用非方形内核大小吗?

  90. Sona Joseph 2021年4月25日晚上8:29 #

    先生,
    感谢您的精彩文章!我们在大学项目中使用了这段代码来对不同作者的文本进行分类。它显示了嵌入层的准确性。但在 word2vec 的情况下,它没有打印任何准确性。它在损失函数中显示 nan 值。您能告诉我原因吗?这将对我们有很大帮助。

  91. Ali 2021年5月8日上午10:35 #

    感谢这篇文章!

    我想问您如何计算预训练迁移学习模型的词汇覆盖率。

    • Jason Brownlee 2021年5月9日上午5:52 #

      我不确定您确切的意思。也许是计算您的词汇表中的单词与现有模型词汇表中的单词的计数?

  92. SURAJ TR 2021年5月23日晚上7:08 #

    我无法打开数据集链接。请帮助。

  93. Okkes 2021年6月13日晚上8:02 #

    嗨,Jason,

    我收到以下错误:

    ValueError: Input 0 of layer dense is incompatible with the layer: expected axis -1 of input shape to have value 342272 but received input with shape (None, 49888)

    这是模型摘要
    _________________________________________________________________
    层(类型) 输出形状 参数 #
    =================================================================
    embedding (Embedding) (None, 21400, 32) 1912864
    _________________________________________________________________
    conv1d (Conv1D) (None, 21393, 32) 8224
    _________________________________________________________________
    max_pooling1d (MaxPooling1D) (None, 10696, 32) 0
    _________________________________________________________________
    flatten (Flatten) (None, 342272) 0
    _________________________________________________________________
    dense (Dense) (None, 10) 3422730
    _________________________________________________________________
    dense_1 (Dense) (None, 1) 11
    =================================================================
    Total params: 5,343,829
    Trainable params: 5,343,829
    不可训练参数: 0

    是什么原因导致了这个错误?您能帮帮我吗?

    提前感谢,
    OKkes

  94. Aklilu 2021年6月15日晚上7:28 #

    请,我有一个项目,我需要帮助获取一个名为“使用深度学习进行文本聚类”的示例代码。
    我一直在阅读和搜索您的书籍和与我的主题相关的不同网站,但不幸的是,我得到的大多是与文本分类相关的。我找不到可以帮助我项目的示例,

    附加问题:如何开发词嵌入与 CNN 来聚类样本数据集?

  95. Aryan Chauhan 2021年10月13日下午5:13 #

    嗨 Jason,这是一篇很棒的文章。但是在使用 word2vec 和 glove 初始化 embedding_weights 后,我在训练时每次都会得到损失“nan”。您能帮我看看为什么我会得到 loss = nan 吗?我无法弄清楚为什么会发生这种情况。

    谢谢

    • Adrian Tam
      Adrian Tam 2021年10月14日凌晨3:16 #

      如果您的损失是 nan,请检查您的数据。很可能有一些缺失的数据导致损失指标无法计算。

  96. Dan 2022年4月5日凌晨4:35 #

    嗨 Jason,感谢这篇令人难以置信的文章,您将如何处理更大的数据集?会有很多需要改变的吗?比如您的预处理方法和模型的维度?我想这次用更大的数据集再次运行模型。

    再次感谢,
    Dan。

    • James Carmichael 2022年4月5日上午7:01 #

      嗨 Dan……我通常建议处理一小部分适合内存的数据集。

      我之所以推荐这样做,是因为它会加速你了解问题。

      测试问题的不同框架速度很快。
      汇总和绘制数据速度很快。
      测试不同的数据准备方法速度很快。
      测试不同类型的模型速度很快。
      测试不同的模型配置速度很快。
      你从较小样本中学到的经验教训通常(但并非总是)可以转化为使用较大数据集进行建模。

      然后,你可以在以后扩展模型以使用整个数据集,也许可以在 Amazon EC2 等云基础设施上进行训练。

      如果您有兴趣使用大型数据集进行训练,还有许多其他选项。我在本帖中列出了 7 个想法

      处理机器学习大型数据文件的 7 种方法

  97. Dan 2022年4月5日晚上11:49 #

    嗨 James,谢谢你的回复,我同意你的观点,但我能够运行 Keras 中使用 IMDB 评论集(25,000 条评论)的其他 CNN 模型,这些模型不耗时且计算量不大。我想看看该数据集在 Jason 的模型下表现如何,以及我需要做哪些更改,我听说拥有更大的数据集是好的做法。
    谢谢

  98. Jacob 2022年6月16日凌晨2:00 #

    嘿,感谢这篇富有启发性的文章。

    我是否可以认为,如果我想训练一个能够评估未知文本(例如用户选择提交以供评估的文本)的模型,那么我应该避免让模型学习自己的嵌入,即使这是评估您在设置期间可以访问的文本的最准确的选择?

    • James Carmichael 2022年6月16日上午10:54 #

      嗨 Jacob……你的理解是正确的。

  99. Luis Mazabuel 2023年12月13日晚上5:11 #

    嗨 James,感谢你的内容。

    我想知道如何将你的博客的第 5 部分(5. 使用预训练嵌入)改编到任何专注于分类的 NN,在一个多类别任务中,使用任何其他预训练嵌入模型对一些西班牙语文本进行分类。

    例如,如果我想使用 TensorFlow 的 Universal Sentence Encoder – Multilingual 或 Google 的 BERT-base-multilingual,或 OpenAI 的任何预训练模型(如 GPTs),或任何其他满足我的任务背景(西班牙语、多类别分类、法律文件背景等)的预训练 LLM 模型。

  100. Luis Mazabuel 2023年12月28日凌晨1:21 #

    但是,在我的情况下,我不想进行情感分析,而是多类别分类任务。我想使用预训练的西班牙语或多语言文档嵌入来训练一个 NN。

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。