7

Pythonを使用して、特定の部分文字列を含む文字列から文を取得しようとしています。

文字列(学術抄録)と、開始インデックスと終了インデックスを含むハイライトのリストにアクセスできます。例えば:

{
  abstract: "...long abstract here..."
  highlights: [
    {
      concept: 'a word',
      start: 1,
      end: 10
    }
    {
      concept: 'cancer',
      start: 123,
      end: 135
    }
  ]
}

私は各ハイライトをループして、要約の開始インデックスを見つけ(文内の場所を取得する必要があるため、終了は実際には重要ではありません)、インデックスが発生する文を何らかの方法で識別する必要があります。

を使用して要約を文にトークン化することはできnltk.tonenize.sent_tokenizeますが、そうすることで、インデックスの場所が役に立たなくなります。

この問題をどのように解決すればよいですか?正規表現はオプションだと思いますが、nltkトークナイザーはそれを使用しないのは残念なことですが、それを行うにはとても良い方法のようです。感嘆符/疑問符?

4

3 に答える 3

6

確かに、NLTKトークナイザーは、「引用符」で文を終了することを含め、ほとんどすべての文の区切りを処理するのに十分堅牢であるため、この状況で実際に使用する必要があります。あなたはこのようなことをすることができます(paragraphランダムジェネレーターから):

皮切りに、

from nltk.tokenize import sent_tokenize

paragraph = "How does chickens harden over the acceptance? Chickens comprises coffee. Chickens crushes a popular vet next to the eater. Will chickens sweep beneath a project? Coffee funds chickens. Chickens abides against an ineffective drill."
highlights = ["vet","funds"]
sentencesWithHighlights = []

最も直感的な方法:

for sentence in sent_tokenize(paragraph):
    for highlight in highlights:
        if highlight in sentence:
            sentencesWithHighlights.append(sentence)
            break

しかし、この方法を使用すると、実際には3倍のネストされたforループができます。これは、最初にそれぞれをチェックしsentence、次にそれぞれをチェックしhighlight、次にの各サブシーケンスをチェックするsentenceためhighlightです。

各ハイライトの開始インデックスがわかっているため、パフォーマンスを向上させることができます。

highlightIndices = [100,169]
subtractFromIndex = 0
for sentence in sent_tokenize(paragraph):
    for index in highlightIndices:
        if 0 < index - subtractFromIndex < len(sentence):
            sentencesWithHighlights.append(sentence)
            break
    subtractFromIndex += len(sentence)

どちらの場合でも、次のようになります。

sentencesWithHighlights = ['Chickens crushes a popular vet next to the eater.', 'Coffee funds chickens.']
于 2013-03-20T19:01:35.120 に答える
1

私はあなたのすべての文がこれらの3つの文字の1つで終わると思います:!?.

ハイライトのリストをループして、正規表現グループを作成するのはどうですか?

(?:list|of|your highlights)

次に、要約全体をこの正規表現と照合します。

/(?:[\.!\?]|^)\s*([^\.!\?]*(?:list|of|your highlights)[^\.!\?]*?)(?=\s*[\.!\?])/ig

このようにして、各一致の最初のサブグループ( RegExr )のハイライトの少なくとも1つを含む文を取得します。

于 2013-03-20T17:42:37.413 に答える
0

別のオプション(さまざまに定義されたテキストでどれほど信頼できるかを言うのは難しいですが)は、テキストを文のリストに分割し、それらに対してテストすることです。

re.split('(?<=\?|!|\.)\s{0,2}(?=[A-Z]|$)', text)
于 2013-03-20T17:59:30.023 に答える