3

タスクは、複数の単語 (別名Multi-Word Expressions) で構成される式をグループ化することです。

MWE の辞書が与えられた場合、MWE が検出された入力文にダッシュを追加する必要があります。

**Input:** i have got an ace of diamonds in my wet suit .
**Output:** i have got an ace-of-diamonds in my wet-suit .

現在、ソートされた辞書をループして、MWE が文に表示されるかどうかを確認し、表示されるたびにそれらを置き換えます。しかし、無駄な繰り返しがたくさんあります。

そうするより良い方法はありますか?1 つの解決策は、可能なすべての n-gram を最初に生成することです。つまり、chunker2()

import re, time
mwe_list =set([i.strip() for i in codecs.open( \
            "wn-mwe-en.dic","r","utf8").readlines()])

def chunker(sentence):
  for item in mwe_list:
    if item or item.replace("-", " ") in sentence:
      #print item
      mwe_item =  '-'.join(item.split(" "))
      r=re.compile(re.escape(mwe_item).replace('\\-','[- ]'))
      sentence=re.sub(r,mwe_item,sentence)    
  return sentence

def chunker2(sentence):
    nodes = []
    tokens = sentence.split(" ")
    for i in range(0,len(tokens)):
        for j in range(i,len(tokens)):
            nodes.append(" ".join(tokens[i:j]))
    n = sorted(set([i for i in nodes if not "" and len(i.split(" ")) > 1]))

    intersect = mwe_list.intersection(n)

    for i in intersect:
        print i
        sentence = sentence.replace(i, i.replace(" ", "-"))

    return sentence

s = "i have got an ace of diamonds in my wet suit ."

time.clock()
print chunker(s)
print time.clock()

time.clock()
print chunker2(s)
print time.clock()
4

2 に答える 2

2

私はこのようにしてみます:

  • 文ごとに、指定された長さ(リスト内で最長のMWE)までのn-gramのセットを作成します。
  • 今、それらを実行mwe_nmgrams.intersection(sentence_ngrams)して検索/置換します。

元のセットのすべてのアイテムを繰り返すことで時間を無駄にする必要はありません。


これが少し速いバージョンですchunker2

def chunker3(sentence):
    tokens = sentence.split(' ')
    len_tokens = len(tokens)
    nodes = set()

    for i in xrange(0, len_tokens):
        for j in xrange(i, len_tokens):
            chunks = tokens[i:j]

            if len(chunks) > 1:
                nodes.add(' '.join(chunks))

    intersect = mwe_list.intersection(n)

    for i in intersect:
        print i
        sentence = sentence.replace(i, i.replace(' ', '-'))

    return sentence
于 2013-01-22T05:47:31.247 に答える
2

まず、2 倍の改善: MWE をハイフン付きバージョンに置き換えるため、辞書 (wn-mwe-en.dic) を前処理して、セット内の MWE からすべてのハイフンを除去し、1 つの文字列比較を除去できます。センテンス内でハイフンを許可する場合は、マイナー ペナルティとして、おそらくオンラインで前処理する必要があります。これにより、実行時間が半分になります。

次に、マイナーな改善: 不変のタプルは、通常、セットまたはリスト (可変であり、反復子は各ステップでメモリ内の要素の移動をチェックする必要があります) よりも反復の方が高速です。あなたが意図したように、 set() 変換は重複を排除します。タプル ビットは、Python インタープリターとそのコンパイル済みライブラリによる低レベルの反復最適化を可能にするメモリ内でそれを固めます。

最後に、すべての比較を行う前に、おそらく文と MWE の両方を単語またはトークンに解析する必要があります。これにより、単語の平均長に必要な文字列比較の数が削減されます (単語が 4 文字の長さの場合は 4 倍)。平均)。また、別のループをネストして、最初の単語を共有するすべての MWE のアンカーとして MWE の最初の単語を検索し、必要な文字列比較の長さを短縮することもできます。しかし、実際のデータでの実験のために、この大部分を残しておきます。そして、インタプリタとコンパイル済み lib の効率に応じて、Python レベルでこのすべての分割ネスト ループを実行すると、実際には速度が低下する可能性があります。

これが最初の 2 つの簡単な「確実な」賭けの結果です。文が非常に短い場合を除き、前処理にもかかわらず 2 倍速くなるはずです。

mwe_list = set(i.strip() for i in codecs.open("wn-mwe-en.dic", "r", "utf8").readlines())
mwe_list = tuple(mwe.replace('-', ' ').strip() for mwe in mwe_list)
sentence = sentence.replace('-', ' ').strip()

def chunker(sentence):
  for item in mwe_list:
    if item in sentence:
    ...

システムで .dic ファイルが見つからないか、プロファイルを作成します。

于 2013-01-22T06:25:20.863 に答える