web-dev-qa-db-ja.com

自然言語処理のための単語頻度アルゴリズム

情報検索の学位を取得せずに、特定のテキスト本文で単語が出現する頻度をカウントするためのアルゴリズムが存在するかどうかを知りたいと思います。目標は、一連のテキストコメントで人々が言っ​​ていることの「一般的な感触」を得ることです。 Wordle の線に沿って。

私が欲しいもの:

  • 冠詞、代名詞などを無視します( 'a'、 'an'、 'the'、 'him'、 'them'など)
  • 固有名詞を保存する
  • ソフトな種類を除いて、ハイフネーションを無視します

星に手を伸ばすと、これらは桃色になります:

  • ステミングと複数形の処理(例:like、likes、liked、likeingは同じ結果に一致します)
  • 形容詞(副詞など)とその主語のグループ化(「素晴らしい」、「サービス」ではなく「素晴らしいサービス」)

私はWordnetを使用していくつかの基本的なことを試みましたが、私は物事を盲目的に微調整していて、それが私の特定のデータで機能することを望んでいます。もっと一般的なものがあれば素晴らしいでしょう。

32
Mark McDonald

次のように、1つではなく、いくつかのNiceアルゴリズムが必要になります。

  • 代名詞の無視は stoplist を介して行われます。
  • 固有名詞を保存しますか?つまり、HooverDamのような名前付きエンティティを検出し、「 1つの単語」またはプログラミング言語のような複合名詞?ヒントをお伝えします。それは難しいことですが、両方のライブラリが存在します。 NER(固有表現抽出)と字句チャンクを探します。 OpenNLP は、両方を実行するJavaツールキットです。
  • ハイフネーションを無視しますか?つまり、改行のように?正規表現を使用し、辞書検索を介して結果の単語を確認します。
  • 複数形/ステミングの処理: スノーボールステマー を調べることができます。それはうまくトリックを行います。
  • 形容詞を名詞で「グループ化」することは、一般的に 浅い構文解析 のタスクです。しかし、特に定性的な形容詞(良い、悪い、くだらない、素晴らしい...)を探しているなら、 感情分析 に興味があるかもしれません。 LingPipe これを実行します。

申し訳ありませんが、KISSを希望しているとのことですが、残念ながら、ご要望にお応えするのは簡単ではありません。それでも、これらすべてに対応するツールが存在します。必要がなければ、それらを結び付けるだけで、自分でタスクを実行する必要はありません。自分でタスクを実行したい場合は、ステミングを検討することをお勧めします。これが最も簡単です。

Javaを使用する場合は、 LuceneOpenNLP ツールキットを組み合わせてください。 Luceneにはすでにステマーが組み込まれており、多くのチュートリアルがあるため、非常に良い結果が得られます。一方、OpenNLPツールキットは十分に文書化されていませんが、それほど多くを必要とすることはありません。 Pythonで書かれた [〜#〜] nltk [〜#〜] にも興味があるかもしれません。

最後の要件は、浅い構文解析を含み、明らかに結果を損なうことはないため、削除すると思います。

ああ、ところで。あなたが探していたそのdocument-term-frequency-thingの正確な用語は tf-idf と呼ばれます。これは、用語のドキュメント頻度を探すためのほぼ最良の方法です。それを適切に行うために、多次元ベクトル行列を使用することは避けられません。

... はい、知っています。 IRに関するセミナーを受講した後、Googleに対する私の敬意はさらに高まりました。 IRでいくつかのことをした後、しかし、それらに対する私の尊敬は同じくらい速く落ちました。

70

NLPの世界へようこそ^ _ ^

必要なのは、少し基本的な知識といくつかのツールだけです。

文中の単語が名詞、形容詞、動詞のいずれであるかを示すツールはすでにあります。それらは 品詞タガー と呼ばれます。通常、彼らは平文の英語を入力として受け取り、単語、その基本形式、および品詞を出力します。投稿の最初の文で人気のあるUNIXの品詞タガーの出力は次のとおりです。

$ echo "Without getting a degree in information retrieval, I'd like to know if there exists any algorithms for counting the frequency that words occur in a given body of text." | tree-tagger-english 
# Word  POS     surface form
Without IN  without
getting VVG get
a   DT  a
degree  NN  degree
in  IN  in
information NN  information
retrieval   NN  retrieval
,   ,   ,
I   PP  I
'd  MD  will
like    VV  like
to  TO  to
know    VV  know
if  IN  if
there   EX  there
exists  VVZ exist
any DT  any
algorithms  NNS algorithm
for IN  for
counting    VVG count
the DT  the
frequency   NN  frequency
that    IN/that that
words   NNS Word
occur   VVP occur
in  IN  in
a   DT  a
given   VVN give
body    NN  body
of  IN  of
text    NN  text
.   SENT    .

ご覧のとおり、「アルゴリズム」は「アルゴリズム」の複数形(NNS)であり、「存在する」は「存在する」の活用(VBZ)であると識別されました。また、「a」と「the」を「限定詞(DT)」として識別しました。これは記事の別の単語です。ご覧のとおり、POSタガーも句読点をトークン化しました。

リストの最後のポイント以外のすべてを行うには、POSタガーを介してテキストを実行し、興味のないカテゴリ(限定詞、代名詞など)を除外して、言葉。

人気のあるPOSタガーは次のとおりです。

TreeTagger (バイナリのみ:Linux、Solaris、OS-X)
GENIA Tagger (C++:自分でコンパイルする)
スタンフォードPOSタガー (Java)

リストの最後のことを行うには、Wordレベルの情報以上のものが必要です。開始する簡単な方法は、シーケンスof単語そのものではなく、単語。これらは n-grams と呼ばれます。開始するのに適した場所は NIX for Poets です。 NLPに関する本に投資する意思がある場合は、 統計的自然言語処理の基礎 をお勧めします。

16
underspecified

これは、Pythonでこれを行う方法の例です。概念は、どの言語でも似ています。

>>> import urllib2, string
>>> devilsdict = urllib2.urlopen('http://www.gutenberg.org/files/972/972.txt').read()
>>> workinglist = devilsdict.split()
>>> cleanlist = [item.strip(string.punctuation) for item in workinglist]
>>> results = {}
>>> skip = {'a':'', 'the':'', 'an':''}
>>> for item in cleanlist:
      if item not in skip:
        try:
          results[item] += 1
        except KeyError:
          results[item] = 1

>>> results
{'': 17, 'writings': 3, 'foul': 1, 'Sugar': 1, 'four': 8, 'Does': 1, "friend's": 1, 'hanging': 4, 'Until': 1, 'marching': 2 ...

最初の行は、urllib2がアンブローズビアスの「悪魔の辞書」のコピーをダウンロードする2行目のように、問題の一部を支援するライブラリを取得します。次の行は、句読点なしでテキスト内のすべての単語のリストを作成します。次に、ハッシュテーブルを作成します。この場合は、番号に関連付けられた一意の単語のリストのようなものです。 forループは、Bierceブックの各単語を調べます。テーブルにその単語のレコードが既に存在する場合、新しい出現ごとに、テーブル内のその単語に関連付けられた値に1が追加されます。 Wordがまだ表示されていない場合は、値1(1回の出現を意味します)でテーブルに追加されます。話している場合は、大文字の使用など、詳細にもっと注意を払う必要があります。文の途中などで固有名詞を識別するために、これは非常に大まかなものですが、概念を表しています。

ステミングと複数化の問題に取り組み、実験してからサードパーティの作業を調べるために、学術的なオープンソースプロジェクトであるNLTKの一部をPythonで楽しんできました。

4
unmounted

私はしばらく前にこれを行うための完全なプログラムを書きました。後で家に帰ったらデモをアップロードできます。

コード(asp.net/c#)は次のとおりです。h ttp://naspinski.net/post/Findingcounting-Keywords-out-of-a-Text-Document.aspx

2
naspinski

あなたの質問の最初の部分はそれほど悪くは聞こえません。基本的に行う必要があるのは、ファイル(またはストリームw/e)から各Wordを読み取り、プレフィックスツリーに配置することです。すでに存在するWordに遭遇するたびに、それに関連付けられた値をインクリメントします。もちろん、計算から除外したいものすべての無視リストもあります。

プレフィックスツリーを使用する場合は、Wordを検索するためにO(N)ここで、Nはデータセット内の単語の最大長です。のプレフィックスツリーの利点この状況では、複数形と語幹を探したい場合は、O(M + 1)をチェックインして、それがWordでも可能かどうかを確認できます。ここで、Mは語幹または複数を含まない単語の長さです(これは単語ですか? )プレフィックスツリーを作成したら、語幹などについて再分析し、ルートWordが結果を保持するように凝縮します。

検索時に、ルートやステム、または何を持っている場合に一致が正になるように、いくつかの簡単なルールを設定できます。

2番目の部分は非常に難しいようです。私の素朴な傾向は、形容詞-主語のグループ化に対して別々の結果を保持することです。上記と同じ原則を使用しますが、分離してください。

セマンティック分析のもう1つのオプションは、各文を主語、動詞などの関係のツリーとしてモデル化することです(文には主語と動詞があり、主語には名詞と形容詞があります)。このようにすべてのテキストを分割すると、実行して、発生したさまざまな適切なペアリングをすばやくカウントするのはかなり簡単なようです。

いくつかのとりとめのない話ですが、もっと良いアイデアがあると確信していますが、私はこのことについて考えるのが大好きです。

2
Justin Bozonier

今説明したアルゴリズム。 「やる」という大きなボタンで箱から出してそれを行うプログラム...わかりません。

しかし、建設的にさせてください。この本をお勧めします 集合知プログラミング 。第3章と第4章には、非常に実用的な例が含まれています(実際には、複雑な理論はなく、単なる例です)。

1
graffic

Uは、ワールドネット辞書を使用して、過去のスピーチなどの質問キーワードの基本情報を取得し、同義語を抽出できます。また、ドキュメントに対して同じことを行って、そのインデックスを作成することもできます。そうすれば、キーワードをインデックスファイルと簡単に照合して、ドキュメントをランク付けできます。それからそれを夏にします。

0
tafseer

あなたがリストしたものはすべて spacy によってうまく処理されます。

  1. 一部の単語を無視する-ストップワードを使用する
  2. 件名を抽出します-品詞タグを使用してそれを識別します(箱から出して機能します)。文が解析されたら、文の主動詞である「ROOT」を見つけます。 解析ツリーをナビゲートする によって、この動詞に関連する名詞が見つかります。それが主題になります。
  3. ハイフンを無視します-ほとんどの場合、それらのトークナイザーはハイフンを処理します。より特殊なケースを処理するために簡単に拡張できます。

トピックのリストが事前に決定されており、膨大ではない場合は、さらに先に進むことができます。トピックを予測する分類モデルを構築します。 10人の被験者がいるとしましょう。サンプルの文章やテキストを収集します。それらを別の製品にロードします: prodigy 。優れたインターフェースを使用して、被験者をサンプルにすばやく割り当てることができます。そして最後に、分類されたサンプルを使用して、テキストまたは文の主題を予測するためにスペイシーモデルをトレーニングします。

0
Dim