首页 > 解决方案 > 关于 Python 2.7 中列表列表的 SpaCy 问题

问题描述

我认为我的问题部分与 spaCy 有关,部分与不了解在 python 本身中工作的最优雅方式有关。

我在 python 中上传一个 txt 文件,将其标记为句子,然后使用 nltk 将其标记为单词:

sent_text = nltk.sent_tokenize(text)
tokenized_text = [nltk.word_tokenize(x) for x in sent_text]

这给了我一个列表列表,其中主列表中的每个列表都是一个标记词的句子。到目前为止,一切都很好。

然后我通过 SpaCy 运行它:

text = nlp(unicode(tokenized_text))

仍然是一个列表列表,同样的事情,但它包含所有 SpaCy 信息。

这是我遇到障碍的地方。基本上我要做的是,对于每个句子,只保留名词、动词和形容词,而在其中,也去掉助词和连词。我可以通过创建一个新的空列表并仅附加我想要的内容来做到这一点:

sent11 = []
  for token in sent1:
    if (token.pos_ == 'NOUN' or token.pos_ == 'VERB' or token.pos_ =='ADJ') and (token.dep_ != 'aux') and (token.dep_ != 'conj'):
      sent11.append(token)

这适用于单个句子,但我不想对书本长度文本中的每个句子都这样做。

然后,一旦我有了这些只包含我想要的片段的新列表(或任何最好的方法),我想使用 SpaCy 的“相似性”功能来确定哪个句子在语义上最接近其他句子,更短除了名词、形容词、动词等,我对所有内容都做了同样的剥离。

通过使用以下方法将一个句子与另一个句子进行比较时,我已经使它起作用了:

sent1.similarity(sent2)

所以我想我的问题是

1)将列表列表转换为仅包含我想要的部分的列表列表的最佳方法是什么?

2)我如何循环浏览这个新的列表并将每个列表与一个单独的句子进行比较并返回语义上最相似的句子(使用 SpaCy 附带的向量)?

标签: python-2.7nltkspacy

解决方案


你在这里问了一堆问题,所以我将尝试分解它们。

  1. 通过将每个单词附加到列表中来几乎复制一本书长度的文本是否不好?
  2. 如何有效地消除或删除列表中的元素?
  3. 如何将一个句子与书中的每个句子进行比较,其中每个句子都是一个列表,而书是一个句子列表。

答案:

  1. 通常是的,但在现代系统上,这没什么大不了的。书籍是文本,如果是英文,可能只是 UTF-8 字符,否则它们可能是 Unicode。一个 UTF-8 字符是一个字节,甚至像《战争与和平》这样的长书也只有3.3 Mb 以下。如果您使用 chrome、firefox 或 IE 来查看此页面,则您的计算机有足够的内存来将它的几个副本放入 ram。

  2. 在python中你真的不能。

您可以使用以下方法进行删除:

l = [1,2,3,4]
del l[-2]
print(l)
[1,2,4]

但在后台 python 正在将该列表的每个元素复制到一个之上。不建议用于大型列表。相反,使用将自身实现为双链表的出队会产生一些额外的开销,但可以有效地删除中间的元素。

如果内存是一个问题,那么您也可以尽可能使用生成器。例如,您可能会更改:

tokenized_text = [nltk.word_tokenize(x) for x in sent_text]

它创建了一个包含整本书标记的列表,其中

tokenized_text = (nltk.word_tokenize(x) for x in sent_text)

它创建了一个生成器,可以生成整本书的令牌。生成器几乎没有内存开销,而是在运行时计算下一个元素。

  1. 我不熟悉 SpaCy,虽然这个问题适合所以你不太可能在这里得到关于特定库的好答案。

从外观上看,您可以执行以下操作:

best_match = None
best_similarity_value = 0
for token in parsed_tokenized_text:
    similarity = token.similarity(sent2)
    if similarity > best_similarity_value:
        best_similarity_value = similarity
        best_match = token

如果你想检查多个句子(非连续的),那么你可以放置一个外循环来遍历这些:

for sent2 in other_token_list:

推荐阅读