title | description | prev | next | type | id |
---|---|---|---|---|---|
第4章: ニューラルネットワークのトレーニング |
この章では、ユースケースに合わせて機械学習モデルを更新する方法を学びます。例えば、オンラインのコメントを使って新しい固有表現タイプを予測する、などです。 ゼロからモデルを学習させていき、トレーングの基礎を理解し、NLPプロジェクトをより成功させるためのヒントやコツを学んでいきます。 |
/chapter3 |
chapter |
4 |
モデルを学習させるには、通常「学習データ」(または「訓練データ」)と検証データが必要です。この「検証データ」はなぜ必要でしょうか。
訓練中、モデルは学習データのみに基づいて更新されます。 モデルを評価するために、検証データをモデルに与え、未見のデータに対しての予測を正解と比較し、モデルの精度を計算します。
モデルを評価するために、検証データをモデルに与え、未見のデータに対しての予測を正解と比較し、モデルの精度を計算します。
訓練中、モデルは学習データのみに基づいて更新されます。 モデルを評価するために、検証データをモデルに与え、未見のデータに対しての予測を正解と比較し、モデルの精度を計算します。
spaCyのルールベースの Matcher
は、固有表現抽出の学習データを素早く作成するのに最適な方法です。
文章のリストが変数 TEXTS
として用意されており、プリントすると、中身を見ることができます。
iPhoneのモデルが言及されている箇所を見つけるため、それらを "GADGET"
として認識するようにモデルに教えるための学習データを作成します。
- 小文字が
"iphone"
にマッチするトークン、小文字が"x"
にマッチするトークン、合計2つのトークンのパターンを書きます。 - 小文字が
"iphone"
にマッチするトークン、数字のトークン、合計2つのトークンのパターンを書きます。
- トークンの小文字を一致させるには、
"LOWER"
属性を使用します。例えば、{"LOWER": "apple"}
のようにします。 - 数字のトークンを見つけるには、
"IS_DIGIT"
フラグを用います。例えば、{"IS_DIGIT": True}
のようになります。
前の演習で作成したマッチパターンを使って、学習データを作っていきましょう。
spaCyで学習データを使うためには .spacy
ファイルを作成する必要があります。
docs
のリストを使ってDocBin
を作成しますDocBin
をtrain.spacy
というファイルに保存します
DocBin
を初期化するとき、Doc
のリストをdocs
キーワード引数で指定できますDocBin
のto_disk
メソッドは出力ファイル名を引数として取ります。 ファイル名の拡張子は.spacy
にしましょう。
config.cfg
の設定ファイルはパイプラインにとって「信頼できる唯一の情報源」です。
以下の選択肢のうち、どれが正しくないでしょうか。
設定ファイルにはハイパーパラメータを含め、トレーニングの全ての設定が記載されています。
設定ファイルに全ての設定が含まれているため、隠れデフォルトなどはなく、実験の再現性を高めます。 他人に設定ファイルを共有するだけで同じ実験を再現できます。
設定ファイルにトレーニングに関する全ての設定は記載されていますが、パイプラインをパッケージ化することは別の機能です。
パッケージを作成することはspacy package
コマンドでできます。
設定ファイルの[components]
ブロックでは、モデルのバージョンを含め、コンポネントに関する全ての設定が記述されています。
init config
コマンドを使うと、デフォルト設定の設定ファイルを自動に生成できます。
この演習では、固有表現抽出器を学習させるためのパイプラインを作るため、ner
コンポネントを含む設定ファイルを作成します。
この演習はJupyter Notebookで実行されているため、コマンドラインのコマンドは!
で始まるように書きます。
手元のコマンドラインで実行する場合、!
を入れる必要はありません。
- spaCyの
init config
コマンドを使って、日本語の設定ファイルを生成してください - 設定ファイルを
config.cfg
に保存してください --pipeline
の引数を使ってner
コンポネントを指定してください
- パイプラインの言語クラスは
--lang
で指定できます。日本語はja
となります。
今生成された設定ファイルの内容を確認しましょう。 下記のコマンドでファイルの中身を表示できます。
今までの演習で作った設定ファイルを使って固有表現抽出器を学習させましょう!
train
コマンドを使うことで設定ファイルからパイプラインを学習させることができます。
exercises/ja
にconfig_gadget.cfg
の設定ファイル、そして学習データのtrain_gadget.spacy
と検証データのdev_gadget.spacy
は既に用意されています。
この演習はJupyter Notebookで実行されているため、コマンドラインのコマンドは!
で始まるように書きます。
手元のコマンドラインで実行する場合、!
を入れる必要はありません。
exercises/ja/config_gadget.cfg
の設定ファイルを使ってtrain
コマンドを実行してください- 学習されたパイプラインを
output
ディレクトリーに出力してください exercises/ja/train_gadget.spacy
とexercises/ja/dev_gadget.spacy
のパスを指定してください
spacy train
コマンドの1つ目の引数は設定ファイルのパスです。
見たことのないデータに対してモデルがどのように動作するか見てみましょう! 少しスピードを上げるために、パイプラインをすでにいくつかのテキストに対して実行しています。以下に結果の一部を示します。
Text | Entities |
---|---|
アップルはiPhone 8とiPhone Xの性能を制限している - 回避方法はこちら | (iPhone 8, iPhone X) |
iPhone Xの“ノッチ”の役割をようやく理解した | (iPhone X,) |
Samsung Galaxy S9について知っておく必要があるすべて | (Samsung Galaxy,) |
iPadのモデル比較?これが2018年モデルのラインナップだ! | (iPad,) |
iPhone 8とiPhone 8 Plusは、Appleが設計、開発、販売しているスマートフォンです | (iPhone 8, iPhone 8) |
一番安いipad、特にipad pro、はどれですか? | (ipad, ipad) |
Samsung Galaxyは、サムスン電子が設計、製造、販売しているモバイルコンピューティングデバイスのシリーズです | (Samsung Galaxy,) |
文章中のすべての固有表現の中で、モデルの予測の正解数はいくつでしょう? スパンの間違いも、誤りとしてカウントとします! ヒント:モデルが予測すべき固有表現の数をカウントします。そして、実際にモデルが正しく予測できた数を求め、それを先程のカウントで割ります。
モデルが正しく予測した固有表現の数を数え、それをモデルが正しく予測すべきだった固有表現の数で割ってください。
モデルが正しく予測した固有表現の数を数え、それをモデルが正しく予測すべきだった固有表現の数で割ってください。
テストデータに対し、モデルの精度は70%でした。
モデルが正しく予測した固有表現の数を数え、それをモデルが正しく予測すべきだった固有表現の数で割ってください。
旅行者のレビューについて、固有表現タイプTOURIST_DESTINATION
のラベルをつけるトレーニングセットからの抜粋です。
doc1 = nlp("去年アスムテルダムに行った。運河がきれいだった。")
doc1.ents = [Span(doc1, 1, 2, label="TOURIST_DESTINATION")]
doc2 = nlp("人生で一度はパリに行くべきだけど、エッフェル塔はちょっとつまらないな。")
doc2.ents = [Span(doc2, 4, 5, label="TOURIST_DESTINATION")]
doc3 = nlp("アーカンソーにもパリはあるw")
doc3.ents = []
doc4 = nlp("ベルリンは夏が最高!公園がたくさんあって、夜遊びが充実していて、ビールが安い!")
doc4.ents = [Span(doc4, 0, 1, label="TOURIST_DESTINATION")]
なぜこのデータとラベル定義には問題があるでしょうか?
より良いアプローチは、"GPE"
(地政学的実体)または"LOCATION"
というラベルだけを付け、ルールベースのシステムを使って、その実体が観光地であるかどうかを判断することです。
例えば、知識ベースを用いたり、トラベルウィキで調べたりすることができます。
米アーカンソー州のパリは観光地である可能性もありますが、これはラベルスキームがいかに主観的であり、ラベルを付けるかどうかを判断することがいかに難しいかを浮き彫りにするだけです。 結果として、この区別を固有表現抽出器が学習するのは非常に困難になります。
非常に珍しい単語やスペルミスであっても、固有表現としてラベル付けすることができます。 実際、文脈に基づいてスペルミスのあるテキストのカテゴリを予測できることは、機械学習ベースの固有表現抽出器の強みの一つです。
doc.ents
を書き換えて、"TOURIST_DESTINATION"
ではなく、"GPE"
(都市、州、国)というラベルだけを使うようにしてください。- もとのデータではラベルが付いていなかった
"GPE"
固有表現のスパンを追加することを忘れないようにしてください。
- 既にラベル付けされているスパンについては、ラベル名を
"TOURIST_DESTINATION"
から"GPE"
に変更するだけです。 - 1つのテキストには、まだラベル付けされていない都市と州が含まれています。固有表現スパンを追加するには、トークン数を数えて、スパンがどこから始まり、どこで終わるかを調べます。そして、
Span(doc, start, end, label)
でスパンを作り、固有表現のリストに追加します。 - トークンの境目が分からない場合、
list(doc)
で確認できます
ここに、新しい固有表現タイプを学習するために作成されたデータセットの一部があります。元のデータセットには数千文が含まれています。 この演習では、ラベル付けを手作業で行います。 実際には、おそらくこれを自動化してアノテーションツールを使用したいと思うでしょう。 例えば、Bratという人気のあるオープンソースのソリューションや、ProdigyというspaCyと統合できる、私達が作ったアノテーションツールなどです。
- データにある
"WEBSITE"
の固有表現のオフセットを計算してください。 手動で文字数をカウントしたくないときは、len(doc1)
を使ってください。
- 終了オフセット終了オフセットは、その位置の文字を含まないことに注意してください。 例えば、2の位置から3の位置までの固有表現の場合、開始オフセットは2で、終了オフセットは4となります。
先ほどラベルを付けたデータに加えて、数千の類似した例を加えてモデルを学習しました。
学習後、"WEBSITE"
ではうまくいっていますが、"PERSON"
を抽出しなくなってしまいました。なぜこのようなことが起こるのでしょうか?
モデルが全く異なる複数のカテゴリを学習することは可能です。 たとえば、spaCyの事前学習の英語モデルは、人と組織とパーセンテージを認識することができます。
もし"PERSON"
固有表現がトレーニングに含まれているにも関わらずラベル付けされていなかったら、モデルはこのスパンを出力すべきでないというように学習してしまいます。
同様に、今まであったラベルがトレーニングデータに含まれていない場合、モデルはそのラベルのことを忘れてしまい、予測しなくなってしまうことがあります。
ハイパーパラメータはモデルの精度に影響を与える可能性がありますが、ここでは問題ではないでしょう。
"PERSON"
の固有表現「ピューディパイ」と「アレクシス・オハニアン」のアノテーションを含むように学習データを更新します。
- もっと固有表現を追加するには、さらにスパンをリストに追加します。
- 終了オフセット終了オフセットは、その位置の文字を含まないことに注意してください。 例えば、2の位置から3の位置までの固有表現の場合、開始オフセットは2で、終了オフセットは4となります。