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
から取得できます。
これらの問題のうち、カスタムコンポーネントによって解決できるものはどれですか?該当するものをすべて選択してください。
- 事前に訓練されたモデルを更新し、その予測を改善する
- トークンとその属性に基づいてオリジナルの値を計算する
- 辞書に基づいた固有表現の追加などを行う
- 追加言語のサポートの実装
カスタムコンポーネントはDoc
を変更するだけで、他のコンポーネントの重みを直接更新することはできません。
カスタムコンポーネントはDoc
を変更するだけで、他のコンポーネントの重みを直接更新することはできません。
カスタムコンポーネントはDoc
を変更するだけで、他のコンポーネントの重みを直接更新することはできません。また、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。
カスタムコンポーネントは、Doc、トークン、スパンにカスタム値を追加したり、doc.ents
をカスタマイズしたりするのに最適です。
カスタムコンポーネントは、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。
カスタムコンポーネントはDoc
を変更するだけで、他のコンポーネントの重みを直接更新することはできません。また、言語クラスがすでに初期化され、テキストがトークン化された後にパイプラインに追加されるので、新しい言語を追加するのには適していません。
この例では、Docのトークンの長さを表示するカスタムコンポーネントを紹介しています。 足りない部分を埋め、完成させてください。
- コンポーネントの関数を
doc
の長さを用いて完成させます。 - 既存のパイプラインの先頭に
length_component
を追加します。 - 新しいパイプラインを試してみて、
nlp
オブジェクトを使ってテキストを処理してみてください。 例文:「これは文章です。」
Doc
オブジェクトの長さを取得するには、Pythonの組み込みのlen()
メソッドが使えます。- コンポーネントをパイプラインに追加するには
nlp.add_pipe
メソッドを使います。 キーワード引数first
にTrue
を指定すると、他のすべてのコンポーネントよりも前に追加されます。 - テキストを処理するには、
nlp
オブジェクトを呼び出します。
この演習では、PhraseMatcher
を使って文中の動物の名前を見つけ、一致したスパンをdoc.ents
に追加するカスタムコンポーネントを書いてみましょう。
動物のパターンを持つ PhraseMatcher
はすでに変数 matcher
として作成されています。
- カスタムコンポーネントを定義し、
doc
にmatcher
を適用します。 - 各マッチに対して
Span
を作成し、"ANIMAL"
にラベルIDを割り当て、doc.ents
を新しいスパンで上書きします。 - 新しいコンポーネントを
"ner"
コンポーネントの後にパイプラインに追加します。 - テキストを処理し、
doc.ents
内の固有表現の文字列とラベルを表示します。
- マッチは
(match_id, start, end)
タプルのリストであることを思い出してください。 Span
クラスは4つの引数を取ります:親のdoc
、開始インデックス、終了インデックス、ラベルです。- コンポーネントを別のコンポーネントの後ろから追加するには、
nlp.add_pipe
のafter
キーワード引数を用います。
拡張属性の設定を試してみましょう。
Token.set_extension
を用いて"is_country"
(デフォルトはFalse
) を登録します。"スペイン"
について更新し、すべてのトークンを表示します。
拡張属性は._
からアクセスできることを思い出してください。例えば、doc._.has_color
のようにします。
Token.set_extension
を使って"reversed"
を登録してください(getterget_reversed
)。- それぞれのトークンについて、表示してください。
拡張属性は._
からアクセスできることを思い出してください。例えば、doc._.has_color
のようにします。
ゲッターとメソッド属性を用いたより複雑な属性の設定をしていきましょう。
- 関数
get_has_number
を完成させます。 Doc.set_extension
を用いて"has_number"
(getterget_has_number
)を登録し、その値を表示します。
- 拡張属性は
._
からアクセスできることを思い出してください。例えば、doc._.has_color
のようにします。 - 関数
get_has_number
は、doc
に含まれるトークンがtoken.like_num
に対してTrue
を返すかどうか(トークンが数字に似ているかどうか)を返す必要があります。
Span.set_extension
を使って"to_html"
を登録します。(methodto_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
、トークンインデックスstart
とend
、そしてlabel
の 4 つの引数をとります。doc
に対してPhraseMatcher
を呼び出すと、(match_id, start, end)
タプルのリストを返します。- 新しい拡張属性を登録するには、グローバルクラスの
set_extension
メソッドを利用します。ゲッターを登録するには、getter
キーワード引数を使用します。 - 拡張属性は、
._.
プロパティで利用できます。例えば、doc._.has_color
のようにします。
この演習では、より効率的なテキスト処理のために nlp.pipe
を使います。
nlp
オブジェクトはすでに作成されています。アメリカの人気ファストフードチェーンに関するツイートのリストが変数 TEXTS
に入っています。
- 例題を書き換えて
nlp.pipe
を使うようにしてください。テキストを繰り返し処理するのではなく、nlp.pipe
によって生成されたdoc
オブジェクトを繰り返し処理するようにしてください。
nlp.pipe
を使うと、最初の2行のコードを1つにまとめることができます。nlp.pipe
はTEXTS
を受け取り、doc
をイテレートできるオブジェクトを生成します。
- 例を書き換えて
nlp.pipe
を使ってください。 結果をリストにするために、list()
を呼び出すことを忘れないでください。
- 例を書き換えて
nlp.pipe
を使ってください。 結果をリストにするために、list()
を呼び出すことを忘れないでください。
この演習では、拡張属性を使用して、著者と書籍のメタ情報を追加します。
変数 DATA
には [text, context]
の例のリストが入っています。
テキストは有名な書籍からの引用であり、コンテキストはキー "author"
と "book"
を持つ辞書です。
set_extension
メソッドを用いてDoc
に拡張属性"author"
と"book"
を登録します。nlp.pipe
を用いてas_tuples=True
としてDATA
の[text, context]
ペアを処理します。doc._.book
とdoc._.author
を、コンテキストとして渡された情報を用いて上書きします。
Doc.set_extension
メソッドは2つの引数を取ります。属性の文字列名と、デフォルト、ゲッター、セッター、メソッドを示すキーワード引数です。例えば、default=True
のようにします。as_tuples
がTrue
に設定されている場合、nlp.pipe
メソッドは(text, context)
タプルのリストを受け取り、(doc, context)
タプルを生成します。
この演習では、nlp.make_doc
と nlp.disable_pipes
メソッドを使用して、テキストを処理する際に実行するコンポーネントを選択します。
nlp.make_doc
を使ってテキストのトークン化のみを実行するようにコードを書き換えます。
nlp.make_doc
メソッドはテキストに対して呼び出すことができ、 nlp
オブジェクトと同様に Doc
を返します。
nlp.disable_pipes
メソッドを使ってパーサを無効にします。- テキストを処理して
doc
内のすべての固有表現を表示します。
nlp.disable_pipes
メソッドは可変数の引数をとります。例えば、nlp.disable_pipes("ner")
は固有表現抽出器を無効にします。