LoginSignup
8
11

More than 5 years have passed since last update.

機械学習における自然言語処理とは

Posted at

自然言語処理とは、人間が使っている言葉(自然言語)を機械に処理してもらうこと。

身の回りでいいうと、Google翻訳機能や予測変換などにも用いられている。

機械学習を行う際に、データをSNSやWikiやNewsなどテキストから
取り出す際、入り用となる。

まずそのテキストデータの種類からみていく。

テキストデータの種類

まずテキストデータは4種類に分けられる。
1、 カテゴリデータ
2、 自由記述だが意味的にはカテゴリ
3、 構造化された文字列
4、 自由なテキストデータ

この一つずつを簡単に説明すると

1、カテゴリデータ

赤、青、黄色などあきらかにカテゴリー。
誤字脱字など、同じカテゴリーに含まれるもの、
重複には気をつけなければならない。

2、自由記述だが意味的にはカテゴリデータ

カテゴリ変数としてエンコード。
たとえばなんでもよいのだが、夏から秋に変わりかけの頃の夕日の色、など。
カテゴリーに分けづらいので、これは”その他”などといったカテゴリに分けたほうが良い。

3、構造化された文字列

住所・電話番号・地名など。
この処理はコンテクストやドメインに応じて対応しないといけないから大変。

4、自由なテキストデータ

SNSやWikipediaなど。
使う条件としては1つの言語で書かれているもの。
データセットはコーパス、データポイントは文書と呼ぶ

こうしたテキストデータを機械学習に用いることが可能な形に変える必要がある。

テキストデータを機械学習に用いることが可能な形へ

最も用いられるテキスト表現を紹介。

  • BoW(bag-of-words) 表現
    コーパスに現れた単語がテキスト内に現れた回数を数え、袋に入れる。

その為に行うこと3つ

1、トークン分割
対象の文をトークンに分割(スペースや句読点で句切る)

2、ボキャブラリ構築
すべてのトークンをボキャブラリとして集め、アルファベット順など番号をつける 

3、エンコード
文書に対してボキャブラリの単語が現れる回数を数える

scikit-learnでBoW処理が行える

エンコードまでおわれば特徴量を割り当てた数値表現になった。
ボキャブラリが何単語となったのかわかる。

ちなみにこのBoWの問題点としては、
"not ~~"など、否定形と離れ、逆の意味のボキャブラリとして認識されてしまうことがある。

その点を避けられる方法がn-グラムである。
単一のトークンで句切るのではなく、2つのトークン"バイグラム"
3つのトークン"トリグラム"と変え、攻略できる。

ボキャブラリを選別していく手法たち

  • CountVectorizer
  • ストップワード
  • tf-idf
  • 語幹処理・見出し語化

CountVectorizer

ボキャブラリを詳しくみる方法の一つ、CountVectorizerのget_feature_name。
個々の特徴量の中身が見られる。

トークンを正規表現を用いて抽出。
つまり、2つ以上の文字か数字が単語ずつで区切られたものをすべて抽出。

CountVectorizerはすべて小文字にしてくれるので
"Ants" も "ants"も同じトークンと認識してくれる。

しかしこのままいくと問題点として上がるのことが、
あまり意味を持たない数字などの情報量の少ない特徴量がたくさんでてくること。

その問題を避ける1つの手は、文の中に2つ以上の文書に出てくるトークンのみ
特徴量とすれば良い。
2つ、3つ、、と増やしていくと頻出トークンが残り、数を減らすことができる。

ストップワード

次に紹介するものが、トークンの中で頻出しすぎて意味のない単語を捨てる方法である。

この実行方法は2つ。
1、ストップワードリストを作る
2、頻度の高い言語を捨てる

1はscikit-learnがfeature_extraction.textモジュールに持っている。
英語のストップワード用であるが。

tf-idf

tf-idfは特徴量がどの程度情報を持っているかによってスケールを変換する機能。
捨てさるわけではない。

ある一つの文書に頻出するトークンには重みをつけ
すべての文書に頻出するトークンはあまり重みづけしない。

これは、特定の文書にのみ頻出するトークンは、
その内容をよく表すものではないか、ということだそう。

tf-idf実行にはscikit-learnにTfidfTransformer、TfidfVectorizerクラスがある。
 

語幹処理・見出し語化

ボキャブラリ抽出時の問題点、
同じ意味の単語でも、複数形、単数形で別に分けられてしまうところである。

その問題を解決する点がこちら
1、語幹処理
末尾を取り除き、語幹のみの形とする。
2、見出し語化
辞書を用いて文章内の単語の役割考慮し取り出す。

両者とも、正規化と呼ぶ。

"had"という単語に対して語幹処理は"ha"と出る可能性もあるが、
見出し語化は"have"と出るため
機械学習においては見出し語化の方がより良い結果が得られる。

LDA

機械学習においてLDAは2つ、Linear Discriminant AnalysisとLatent Dirichlet Allocationがある。
前者は線形クラス分類モデル、今回はトピックを抽出する方法の後者である。

文書ごとにトピックを割り当てることをトピックモデリングと呼ぶ。

LDAは同時に頻出する単語の集合体を探す。
LDA実行時の注意点は、頻出すぎる単語が混ざっているとうまくいかないため、
ある程度削ったものを使用したほうがいい。

 

機械学習における自然言語処理とは、
まずテキストを決める。
データ表現を変換する。
その中から特徴量を抽出する。
の流れである。

この処理には様々な方法があり、近年だとリカレントニュートラルネットワークが
上がってきている。
色々試してみる必要があると感じます。

参考文献

・【事例付き】自然言語処理とは!仕組みやライブラリを解説
https://techacademy.jp/magazine/17184 2018/10/26閲覧)
・Pythonではじめる機械学習ーscikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
(著者 Andreas C.Muller、Sarah Guido 発行所 株式会社オライリー・ジャパン)

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11