web-dev-qa-db-ja.com

Python(NLTK)-名詞句を抽出するより効率的な方法?

大量のテキストデータを含む機械学習タスクがあります。トレーニングテキスト内の名詞句を識別して抽出し、後でパイプラインの特徴構築に使用できるようにしたいと考えています。テキストから必要な名詞句のタイプを抽出しましたが、NLTKはかなり新しいので、以下に示すように、リスト内包表記の各ステップを分類できる方法でこの問題に取り組みました。

しかし、私の本当の質問は、私はここで車輪を再発明しているかどうかです。これを実行するより速い方法はありませんか?

import nltk
import pandas as pd

myData = pd.read_Excel("\User\train_.xlsx")
texts = myData['message']

# Defining a grammar & Parser
NP = "NP: {(<V\w+>|<NN\w?>)+.*<NN\w?>}"
chunkr = nltk.RegexpParser(NP)

tokens = [nltk.Word_tokenize(i) for i in texts]

tag_list = [nltk.pos_tag(w) for w in tokens]

phrases = [chunkr.parse(sublist) for sublist in tag_list]

leaves = [[subtree.leaves() for subtree in tree.subtrees(filter = lambda t: t.label == 'NP')] for tree in phrases]

結局タプルのリストのリストのリストを、タプルのリストのリストにフラット化します

leaves = [tupls for sublists in leaves for tupls in sublists]

抽出された用語を1つのバイグラムに結合します

nounphrases = [unigram[0][1]+' '+unigram[1][0] in leaves]
6
Silent-J

DataFrameの処理時にNLTK関数が遅いのはなぜですか? を確認してください。中間ステップが必要ない場合は、すべての行を複数回繰り返す必要はありません。

ne_chunkおよびソリューション

[コード]:

from nltk import Word_tokenize, pos_tag, ne_chunk
from nltk import RegexpParser
from nltk import Tree
import pandas as pd

def get_continuous_chunks(text, chunk_func=ne_chunk):
    chunked = chunk_func(pos_tag(Word_tokenize(text)))
    continuous_chunk = []
    current_chunk = []

    for subtree in chunked:
        if type(subtree) == Tree:
            current_chunk.append(" ".join([token for token, pos in subtree.leaves()]))
        Elif current_chunk:
            named_entity = " ".join(current_chunk)
            if named_entity not in continuous_chunk:
                continuous_chunk.append(named_entity)
                current_chunk = []
        else:
            continue

    return continuous_chunk

df = pd.DataFrame({'text':['This is a foo, bar sentence with New York city.', 
                           'Another bar foo Washington DC thingy with Bruce Wayne.']})

df['text'].apply(lambda sent: get_continuous_chunks((sent)))

[でる]:

0                   [New York]
1    [Washington, Bruce Wayne]
Name: text, dtype: object

カスタムRegexpParserを使用するには:

from nltk import Word_tokenize, pos_tag, ne_chunk
from nltk import RegexpParser
from nltk import Tree
import pandas as pd

# Defining a grammar & Parser
NP = "NP: {(<V\w+>|<NN\w?>)+.*<NN\w?>}"
chunker = RegexpParser(NP)

def get_continuous_chunks(text, chunk_func=ne_chunk):
    chunked = chunk_func(pos_tag(Word_tokenize(text)))
    continuous_chunk = []
    current_chunk = []

    for subtree in chunked:
        if type(subtree) == Tree:
            current_chunk.append(" ".join([token for token, pos in subtree.leaves()]))
        Elif current_chunk:
            named_entity = " ".join(current_chunk)
            if named_entity not in continuous_chunk:
                continuous_chunk.append(named_entity)
                current_chunk = []
        else:
            continue

    return continuous_chunk


df = pd.DataFrame({'text':['This is a foo, bar sentence with New York city.', 
                           'Another bar foo Washington DC thingy with Bruce Wayne.']})


df['text'].apply(lambda sent: get_continuous_chunks(sent, chunker.parse))

[でる]:

0                  [bar sentence, New York city]
1    [bar foo Washington DC thingy, Bruce Wayne]
Name: text, dtype: object
8
alvas