3

約 40,000 フレーズのリスト L と約 1,000 万語のドキュメントがあります。私が確認したいのは、これらのフレーズのどのペアが 4 単語のウィンドウ内に出現するかということです。たとえば、L=["茶色のキツネ","怠惰な犬"] を考えてみましょう。この文書には、「怠惰な犬を飛び越える素早い茶色のキツネ」という言葉が含まれています。茶色のキツネと怠惰な犬が 4 つの単語のウィンドウ内に何回出現するかを確認し、それをファイルに保存します。これを行うための次のコードがあります。

content=open("d.txt","r").read().replace("\n"," ");
for i in range(len(L)):
 for j in range(i+1,len(L)):
  wr=L[i]+"\W+(?:\w+\W+){1,4}"+L[j]
  wrev=L[j]+"\W+(?:\w+\W+){1,4}"+L[i]
  phrasecoccur=len(re.findall(wr, content))+len(re.findall(wrev,content))
  if (phrasecoccur>0):
    f.write(L[i]+", "+L[j]+", "+str(phrasecoccur)+"\n")

基本的に、リスト L 内のフレーズの各ペアについて、これらのフレーズが 4 単語のウィンドウ内に何回出現するかをドキュメント コンテンツでチェックしています。ただし、この方法は、リスト L が 40K 要素のようにかなり大きい場合、計算効率が低下します。これを行うより良い方法はありますか?

4

3 に答える 3

1

40000 のフレーズを大きな正規表現パターンに組み立て、それを使用してドキュメントと照合できるはずです。ジョブ固有のものほど高速ではないかもしれませんが、機能します。これが私がそれを行う方法です:

import re

class Matcher(object):
    def __init__(self, phrases):
        phrase_pattern = "|".join("(?:{})".format(phrase) for phrase in phrases)
        gap_pattern = r"\W+(?:\w+\W+){0,4}?"
        full_pattern = "({0}){1}({0})".format(phrase_pattern, gap_pattern)

        self.regex = re.compile(full_pattern)

    def match(self, doc):
        return self.regex.findall(doc) # or use finditer to generate match objs

使用方法は次のとおりです。

>>> L = ["brown fox", "lazy dog"]
>>> matcher = Matcher(L)
>>> doc = "The quick brown fox jumps over the lazy dog."
>>> matcher.match(doc)
[('brown fox', 'lazy dog')]

このソリューションにはいくつかの制限があります。1 つは、重複するフレーズのペアが検出されないことです。したがって、この例では、フレーズ"jumps over"をフレーズ リストに追加しても、一致するペアは 1 つしか得られません("brown fox", "jumps over")。同じ単語がいくつか含まれているため、("brown fox", "lazy dog")との両方が欠落します。("jumps over", "lazy dog")

于 2013-04-13T08:24:35.633 に答える