13085


数万～数十万語規模の単語が含まれた英語のテキストファイルがあり、そのテキストに含まれる全単語の出現頻度を求めたいと考えています。

ただし動詞の時制や三単現、名詞の複数形などの理由により単語に変化があっても、それらは同一視した上での頻度を求めたいです。

例えばテキスト中に以下の単語がそれぞれ

[code]

    go : 3
    gone : 6
    went : 2
    goes : 1
    going : 4
    
[/code]

の回数だけ出現したとして、これらを全て巻き上げて基本型`go : 16`とカウントしたいということです（さすがに have gone
などまでは同一視しなくてよいです）。また動詞だけでなく名詞の複数形、形容詞の比較級なども同一視してカウントしたいです。文脈を見ないと区別の付かない lie
- lay / lay - laid のような単語の問題はありますが、それについては考慮せずにどちらかに寄せてしまって構いません。

何も考慮しなくてよければ shell
でワンライナーで書けてしまう処理であることは理解しています。しかし単語の変化まで考慮するとなると、すぐに思いつく手では、別途単語辞書を持った上でマッピングしていくような処理が必要となりそうで、結構ごりごりと力技が要りそうに思われます。

しかしこのような要求ははるか昔からありそうに思われるので、もしすでに同様の処理を行うスクリプトなりツールなりが存在するなら助かるのですが、どなたかご存知ないでしょうか。  
あるいは、このような処理を簡便に行うアプローチが他にありますでしょうか。

条件としては

  * Linux / FreeBSD / Windows のいずれかの環境で動作するもの
  * できれば無償で手に入るもの

であることが望ましいです。


CC BY-SA 3.0
2015-08-05T16:36:34.930
13083
2015-08-29T03:43:49.630
2015-08-06T00:16:11.860
10492
10492
question
テキストファイル 自然言語処理
動詞の不規則変化などを考慮しながら英単語の出現頻度を求めたい


信用度足りずコメントできないので曖昧ですが回答欄に失礼。  
[TreeTagger](http://www.cis.uni-
muenchen.de/~schmid/tools/TreeTagger/)という形態素解析ツールで得られたlemma([基本形…？](https://ja.wikipedia.org/wiki/%E8%AA%9E%E5%BD%99%E7%B4%A0))を使って分類すれば目標は達成できそうです。


CC BY-SA 3.0
2015-08-05T21:17:08.387
13085
2015-08-05T21:17:08.387
10685
13083
answer


いくつかのツールやライブラリの使用を検討しましたが、最終的に @user10685 さんからご紹介いただいた
[TreeTagger](http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/)
で前処理を行うことにしました。

以下に実行手順を示します。実行は Linux (Fedora22) 環境です。

## 1\. tree-tagger のインストール

上記リンク先の Download に記載の手順をそのまま行います。  
今回は処理対象が英語であるため、パラメータファイルには [English parameter file](http://www.cis.uni-
muenchen.de/~schmid/tools/TreeTagger/data/english-par-linux-3.2-utf8.bin.gz)
を利用しました。

## 2\. tree-tagger の実行結果をsedスクリプトに変換する

[code]

    $ cat input.txt | ./cmd/tree-tagger-english | sort | uniq | awk '$3 != "@card@" { if ($1 != $3) printf("s/\\b%s\\b/%s/g\n", $1, $3) }' | uniq > command.txt
    
[/code]

単語をカウントしたい英文ファイルを`input.txt`としています。  
上記のワンライナーでいったんsedのスクリプトファイル`command.txt`を生成します。  
`command.txt`の内容は次のようにひたすら置換コマンドが並んだものとなります。

[code]

    s/\bexposed\b/expose/g
    s/\bexpressed\b/express/g
    s/\bexpressions\b/expression/g
    s/\bextended\b/extend/g
    s/\bextends\b/extend/g
    s/\beyelids\b/eyelid/g
    s/\beyes\b/eye/g
    s/\bfacilitated\b/facilitate/g
    s/\bfacilitates\b/facilitate/g
    s/\bfacilitating\b/facilitate/g
    s/\bfacilities\b/facility/g
    
[/code]

## 3\. sedスクリプトで英文ファイルをlemmatizeする

[code]

    $ sed -f command.txt input.txt > output.txt
    
[/code]

生成したsedスクリプトで不規則変化等している箇所をすべてlemma形式に一括変換します。

たとえばこんな文章が

> No, I am not aware. I know of three different instances when he has bought
> ropes; he bought two ropes on one occasion, and one on another.

こんな風に変換されます。

> no, I be not aware. I know of three different instance when he have buy
> rope; he buy two rope on one occasion, and one on another.

## 4\. lemmatizeしたファイルを元にして単語出現数を数える

[code]

    $ cat output.txt | tr -d ',.;:()"\t' | tr ' ' '\n' | sort | uniq -c | sort -dr > count.txt
    
[/code]

これで単語ごとの出現数を求めることができました。

[code]

       4938 the
       3207 
       2999 be
       2211 of
       1675 to
       1465 that
       1349 I
       1152 a
       1095 and
       1084 you
         :   :
    
[/code]


CC BY-SA 3.0
2015-08-28T14:45:45.243
14974
2015-08-29T03:43:49.630
2015-08-29T03:43:49.630
10492
10492
13083
answer