すべて動詞である文字列のリストがあります。動詞ごとに単語の頻度を取得する必要がありますが、「want」、「wants」、「wanting」、「wanted」などの動詞を 1 つの動詞として数えたいと考えています。正式には、「動詞」は、{X、Xs、Xed、Xing} の形式または {X、Xes、Xed、Xing} の形式の 4 つの単語のセットとして定義されます。ここで、X は動詞です。リストから動詞を抽出して、「X」と語幹の出現回数を取得するにはどうすればよいですか? どういうわけか正規表現を使用できると思いましたが、正規表現は初めてで、完全に迷っています。
2 に答える
テキスト処理用の非常識な関数の配列を持つnltkというライブラリがあります。関数のサブセットの 1 つに があります。これはstemmers
、必要なことだけを行います (この分野で豊富な経験を持つ人々によって開発されたアルゴリズム/コードを使用します)。Porter Stemmingアルゴリズムを使用した結果は次のとおりです。
In [3]: import nltk
In [4]: verbs = ["want", "wants", "wanting", "wanted"]
In [5]: for verb in verbs:
...: print nltk.stem.porter.PorterStemmer().stem_word(verb)
...:
want
want
want
want
これを a と組み合わせて使用defaultdict
すると、次のようなことができます (注: Python 2.7 以降では、 aCounter
も同様に便利/優れています)。
In [2]: from collections import defaultdict
In [3]: from nltk.stem.porter import PorterStemmer
In [4]: verbs = ["want", "wants", "wanting", "wanted", "running", "runs", "run"]
In [5]: freq = defaultdict(int)
In [6]: for verb in verbs:
...: freq[PorterStemmer().stem_word(verb)] += 1
...:
In [7]: freq
Out[7]: defaultdict(<type 'int'>, {'run': 3, 'want': 4})
注意すべき点: ステマーは完璧ではありません。たとえば、ran
上記に追加すると、結果として次のようになります。
defaultdict(<type 'int'>, {'ran': 1, 'run': 3, 'want': 4})
しかし、うまくいけば、それはあなたが望むものに近づくでしょう.
純粋にパターン マッチングによってベース ワードを取得するには、次のコードを使用できます。
import re
for word in verblist:
mtch = re.match(r"([a-zA-Z]*)((ed)|(ing)|(s))", word)
if mtch:
base = mtch.group(1)
else:
base = word
#process the base word here
これは不規則動詞をうまく処理できないことに注意してください。また、動詞のみを含むリストに依存しています。さて、実際にカウントを追跡するには、辞書がおそらく最適です。を使用して、ループの前に dict を作成できますcounts = {}
。次に、単語ごとにインクリメントするには、各反復の最後に次の操作を実行できます。
if base in counts:
counts[base] += 1
else:
counts[base] = 1
入力中にRocketDonkeyが私を打ち負かしました.彼の答えはうまくいくようですが、追加のライブラリをインストールする必要がないので、とにかく投稿します.