web-dev-qa-db-ja.com

pos_tag_sents()をpandasデータフレームに効率的に適用する方法

pandasデータフレームに格納されているテキストの列に1行あたり1文でPOSタグを付ける場合は、SOの実装の大部分でapplyメソッドを使用します。

_dfData['POSTags']= dfData['SourceText'].apply(
                 lamda row: [pos_tag(Word_tokenize(row) for item in row])
_

NLTKドキュメント pos_tag_sents() を使用して、複数の文に効率的にタグを付けることをお勧めします。

それはこの例に当てはまりますか?もしそうなら、コードは_pso_tag_を_pos_tag_sents_に変更するのと同じくらい簡単ですか、それともNLTKは段落のテキストソースを意味しますか?

コメントで述べたように、pos_tag_sents()は毎回プリセプターの負荷を減らすことを目的としていますが、問題はこれをどのように行うかであり、それでもpandas dataframe?

サンプルデータセット20kRowsへのリンク

11
mobcdi

入力

$ cat test.csv 
ID,Task,label,Text
1,Collect Information,no response,cozily married practical athletics Mr. Brown flat
2,New Credit,no response,active married expensive soccer Mr. Chang flat
3,Collect Information,response,healthy single expensive badminton Mrs. Green flat
4,Collect Information,response,cozily married practical soccer Mr. Brown hierachical
5,Collect Information,response,cozily single practical badminton Mr. Brown flat

TL; DR

>>> from nltk import Word_tokenize, pos_tag, pos_tag_sents
>>> import pandas as pd
>>> df = pd.read_csv('test.csv', sep=',')
>>> df['Text']
0    cozily married practical athletics Mr. Brown flat
1       active married expensive soccer Mr. Chang flat
2    healthy single expensive badminton Mrs. Green ...
3    cozily married practical soccer Mr. Brown hier...
4     cozily single practical badminton Mr. Brown flat
Name: Text, dtype: object
>>> texts = df['Text'].tolist()
>>> tagged_texts = pos_tag_sents(map(Word_tokenize, texts))
>>> tagged_texts
[[('cozily', 'RB'), ('married', 'JJ'), ('practical', 'JJ'), ('athletics', 'NNS'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('flat', 'JJ')], [('active', 'JJ'), ('married', 'VBD'), ('expensive', 'JJ'), ('soccer', 'NN'), ('Mr.', 'NNP'), ('Chang', 'NNP'), ('flat', 'JJ')], [('healthy', 'JJ'), ('single', 'JJ'), ('expensive', 'JJ'), ('badminton', 'NN'), ('Mrs.', 'NNP'), ('Green', 'NNP'), ('flat', 'JJ')], [('cozily', 'RB'), ('married', 'JJ'), ('practical', 'JJ'), ('soccer', 'NN'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('hierachical', 'JJ')], [('cozily', 'RB'), ('single', 'JJ'), ('practical', 'JJ'), ('badminton', 'NN'), ('Mr.', 'NNP'), ('Brown', 'NNP'), ('flat', 'JJ')]]

>>> df['POS'] = tagged_texts
>>> df
   ID                 Task        label  \
0   1  Collect Information  no response   
1   2           New Credit  no response   
2   3  Collect Information     response   
3   4  Collect Information     response   
4   5  Collect Information     response   

                                                Text  \
0  cozily married practical athletics Mr. Brown flat   
1     active married expensive soccer Mr. Chang flat   
2  healthy single expensive badminton Mrs. Green ...   
3  cozily married practical soccer Mr. Brown hier...   
4   cozily single practical badminton Mr. Brown flat   

                                                 POS  
0  [(cozily, RB), (married, JJ), (practical, JJ),...  
1  [(active, JJ), (married, VBD), (expensive, JJ)...  
2  [(healthy, JJ), (single, JJ), (expensive, JJ),...  
3  [(cozily, RB), (married, JJ), (practical, JJ),...  
4  [(cozily, RB), (single, JJ), (practical, JJ), ... 

長い間:

まず、Text列を文字列のリストに抽出できます。

texts = df['Text'].tolist()

次に、Word_tokenize関数を適用できます。

map(Word_tokenize, texts)

df.applyを使用すると、@ Boudの提案はほぼ同じであることに注意してください。

df['Text'].apply(Word_tokenize)

次に、トークン化されたテキストを文字列のリストのリストにダンプします。

df['Text'].apply(Word_tokenize).tolist()

次に、pos_tag_sentsを使用できます。

pos_tag_sents( df['Text'].apply(Word_tokenize).tolist() )

次に、列をDataFrameに追加し直します。

df['POS'] = pos_tag_sents( df['Text'].apply(Word_tokenize).tolist() )
9
alvas

各行に_pos_tag_を適用することにより、パーセプトロンモデルが毎回ロードされます(ディスクからピクルスを読み取るため、コストのかかる操作)。

代わりに、すべての行を取得して_pos_tag_sents_(list(list(str))を取ります)に送信すると、モデルは1回ロードされ、すべてに使用されます。

ソース を参照してください。

2
Iulius Curt

代わりに、これを新しい列に割り当てます。

dfData['POSTags'] = pos_tag_sents(dfData['SourceText'].apply(Word_tokenize).tolist())
2
Boud