Skip to content

Latest commit

 

History

History
362 lines (212 loc) · 16 KB

chapter3.md

File metadata and controls

362 lines (212 loc) · 16 KB
title description prev next type id
第3章: パイプライン処理
この章では spaCy の処理パイプラインについて知っておくべきことをすべて紹介します。テキストを処理するときに裏側で起こっていること、自分でコンポーネントを書いてパイプラインに追加する方法、拡張属性を使用してdocやスパン、トークンに独自のメタデータを追加する方法、などを学びます。
/chapter2
/chapter4
chapter
3

nlpをテキストに対して呼び出すとき、spaCyは何をしているでしょうか?

doc = nlp("これは文章です。")

トークナイザはテキストをDocオブジェクトに変換するため、常に全てのパイプラインの前に適用されます。 そしてパイプラインには、タガー、パーサー、固有表現抽出器は必ずしも必要ありません。

トークナイザはテキストをDocオブジェクトに変換します。 spaCyはパイプライン内のすべてのコンポーネントを順にDocに適用します。

spaCyはローカルマシン上で全てを計算するので、サーバに接続する必要はありません。

spacy.load() を呼び出してモデルをロードすると、言語の初期化、パイプラインの追加モデルの重みのロードを行います。 テキストに対してnlp オブジェクトを呼び出すとき、モデルは既にロードされています。

日本語の小サイズのモデルのパイプラインの中身を見てみましょう!

  • ja_core_news_smモデルを読み込み、nlp オブジェクトを作成します。
  • nlp.pipe_namesを用いてパイプラインのコンポーネント名を表示します。
  • nlp.pipelineを用いて(name, component)タプルからなる全てのパイプラインを表示します。

コンポーネント名のリストはnlp.pipe_names属性で入手できます。 (name, component)タプルからなるパイプラインのリストはnlp.pipelineから取得できます。

これらの問題のうち、カスタムコンポーネントによって解決できるものはどれですか?該当するものをすべて選択してください。

  1. 事前に訓練されたモデルを更新し、その予測を改善する
  2. トークンとその属性に基づいてオリジナルの値を計算する
  3. 辞書に基づいた固有表現の追加などを行う
  4. 追加言語のサポートの実装

カスタムコンポーネントはDocを変更するだけで、他のコンポーネントの重みを直接更新することはできません。

カスタムコンポーネントはDocを変更するだけで、他のコンポーネントの重みを直接更新することはできません。

カスタムコンポーネントはDocを変更するだけで、他のコンポーネントの重みを直接更新することはできません。また、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。

カスタムコンポーネントは、Doc、トークン、スパンにカスタム値を追加したり、doc.entsをカスタマイズしたりするのに最適です。

カスタムコンポーネントは、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。

カスタムコンポーネントはDocを変更するだけで、他のコンポーネントの重みを直接更新することはできません。また、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。

この例では、Docのトークンの長さを表示するカスタムコンポーネントを紹介しています。 足りない部分を埋め、完成させてください。

  • コンポーネントの関数をdocの長さを用いて完成させます。
  • 既存のパイプラインの先頭にlength_componentを追加します。
  • 新しいパイプラインを試してみて、nlp オブジェクトを使ってテキストを処理してみてください。 例文:「これは文章です。」
  • Docオブジェクトの長さを取得するには、Pythonの組み込みのlen()メソッドが使えます。
  • コンポーネントをパイプラインに追加するにはnlp.add_pipeメソッドを使います。 キーワード引数firstTrueを指定すると、他のすべてのコンポーネントよりも前に追加されます。
  • テキストを処理するには、nlpオブジェクトを呼び出します。

この演習では、PhraseMatcherを使って文中の動物の名前を見つけ、一致したスパンをdoc.entsに追加するカスタムコンポーネントを書いてみましょう。 動物のパターンを持つ PhraseMatcher はすでに変数 matcher として作成されています。

  • カスタムコンポーネントを定義し、docmatcher を適用します。
  • 各マッチに対して Span を作成し、"ANIMAL" にラベルIDを割り当て、doc.ents を新しいスパンで上書きします。
  • 新しいコンポーネントを "ner" コンポーネントの後にパイプラインに追加します。
  • テキストを処理し、doc.ents内の固有表現の文字列とラベルを表示します。
  • マッチは (match_id, start, end) タプルのリストであることを思い出してください。
  • Spanクラスは4つの引数を取ります:親のdoc、開始インデックス、終了インデックス、ラベルです。
  • コンポーネントを別のコンポーネントの後ろから追加するには、nlp.add_pipeafter キーワード引数を用います。

拡張属性の設定を試してみましょう。

ステップ1

  • Token.set_extension を用いて "is_country" (デフォルトは False) を登録します。
  • "スペイン"について更新し、すべてのトークンを表示します。

拡張属性は._からアクセスできることを思い出してください。例えば、doc._.has_colorのようにします。

ステップ3

  • Token.set_extensionを使って"reversed"を登録してください(getter get_reversed)。
  • それぞれのトークンについて、表示してください。

拡張属性は._からアクセスできることを思い出してください。例えば、doc._.has_colorのようにします。

ゲッターとメソッド属性を用いたより複雑な属性の設定をしていきましょう。

パート1

  • 関数get_has_numberを完成させます。
  • Doc.set_extensionを用いて"has_number"(getter get_has_number)を登録し、その値を表示します。
  • 拡張属性は._からアクセスできることを思い出してください。例えば、doc._.has_colorのようにします。
  • 関数 get_has_number は、doc に含まれるトークンが token.like_num に対して True を返すかどうか(トークンが数字に似ているかどうか)を返す必要があります。

パート2

  • Span.set_extensionを使って"to_html"を登録します。(method to_html
  • doc[0:3]に対して、"strong"を使って呼び出します。
  • メソッドの拡張子は1つ以上の引数を取ることができます。例えば、doc._.some_method("argument")のようになります。
  • メソッドに渡される最初の引数は、呼び出されたメソッドの親である Doc, Token, Span オブジェクトです。

この演習では、拡張属性とモデルの予測を組み合わせて、スパンが人、組織、または場所の場合にWikipediaの検索URLを返すゲッター属性を作成します。

  • ゲッター get_wikipedia_url を完成させ、ラベルのリストにスパンのラベルが含まれている場合にのみURLを返すようにします。
  • ゲッター get_wikipedia_url を用いてSpanの拡張子 "wikipedia_url" を設定します。
  • doc内の固有表現をイテレートし、WikipediaのURLを表示します。
  • スパンの文字列ラベルを取得するには、span.label_ 属性を使用します。これは、スパンが固有表現である場合に固有表現抽出器が予測するラベルです。
  • 拡張属性は._プロパティで利用できることを覚えておいてください。例えば、doc._.has_colorとします。

拡張属性は、カスタムパイプラインコンポーネントと組み合わせて使用すると強力です。この演習では、国の名前を検索するパイプラインコンポーネントと、国の首都を返すカスタム拡張属性を書いてみましょう。

変数 matcher に、すべての国を含むPhraseMatcherがはいっています。 国と首都の関係の辞書が変数 CAPITALS として利用できます。

  • countries_componentを完成させ、すべてのマッチに対して "GPE" (地政学的実体) のラベルを持つ Span を作成します。
  • コンポーネントをパイプラインに追加します。
  • ゲッター get_capital にスパンの拡張属性 "capital" を登録します。
  • テキストを処理し、doc.entsに入っている各固有表現スパンのテキスト、ラベル、キャピタルを表示します。
  • Span クラスは、doc、トークンインデックス startend、そして label の 4 つの引数をとります。
  • doc に対して PhraseMatcher を呼び出すと、(match_id, start, end) タプルのリストを返します。
  • 新しい拡張属性を登録するには、グローバルクラスの set_extension メソッドを利用します。ゲッターを登録するには、getter キーワード引数を使用します。
  • 拡張属性は、._.プロパティで利用できます。例えば、doc._.has_color のようにします。

この演習では、より効率的なテキスト処理のために nlp.pipe を使います。 nlp オブジェクトはすでに作成されています。アメリカの人気ファストフードチェーンに関するツイートのリストが変数 TEXTS に入っています。

パート1

  • 例題を書き換えて nlp.pipe を使うようにしてください。テキストを繰り返し処理するのではなく、nlp.pipeによって生成された doc オブジェクトを繰り返し処理するようにしてください。
  • nlp.pipe を使うと、最初の2行のコードを1つにまとめることができます。
  • nlp.pipeTEXTS を受け取り、docをイテレートできるオブジェクトを生成します。

パート2

  • 例を書き換えて nlp.pipe を使ってください。 結果をリストにするために、list() を呼び出すことを忘れないでください。

パート3

  • 例を書き換えて nlp.pipe を使ってください。 結果をリストにするために、list() を呼び出すことを忘れないでください。

この演習では、拡張属性を使用して、著者と書籍のメタ情報を追加します。

変数 DATA には [text, context] の例のリストが入っています。 テキストは有名な書籍からの引用であり、コンテキストはキー "author""book" を持つ辞書です。

  • set_extensionメソッドを用いて Doc に拡張属性 "author""book"を登録します。
  • nlp.pipe を用いて as_tuples=True として DATA[text, context] ペアを処理します。
  • doc._.bookdoc._.author を、コンテキストとして渡された情報を用いて上書きします。
  • Doc.set_extensionメソッドは2つの引数を取ります。属性の文字列名と、デフォルト、ゲッター、セッター、メソッドを示すキーワード引数です。例えば、default=True のようにします。
  • as_tuplesTrue に設定されている場合、nlp.pipe メソッドは (text, context) タプルのリストを受け取り、(doc, context) タプルを生成します。

この演習では、nlp.make_docnlp.disable_pipes メソッドを使用して、テキストを処理する際に実行するコンポーネントを選択します。

パート1

  • nlp.make_docを使ってテキストのトークン化のみを実行するようにコードを書き換えます。

nlp.make_docメソッドはテキストに対して呼び出すことができ、 nlp オブジェクトと同様に Doc を返します。

パート2

  • nlp.disable_pipes メソッドを使ってパーサを無効にします。
  • テキストを処理して doc 内のすべての固有表現を表示します。

nlp.disable_pipes メソッドは可変数の引数をとります。例えば、nlp.disable_pipes("ner") は固有表現抽出器を無効にします。