---
title: '第1章: 単語やフレーズ、名前、概念の検索'
description:
  "この章では、spaCyの基本的なテキスト処理の方法を紹介します。
  データ構造や機械学習パイプラインの扱い方や、これらを用いてテキストの言語的特徴を抽出する方法を学んでいきます。"
prev: null
next: /chapter2
type: chapter
id: 1
---

<exercise id="1" title="はじめに" type="slides">

<slides source="chapter1_01_introduction-to-spacy">
</slides>

</exercise>

<exercise id="2" title="spaCyを使ってみる">

ではさっそく、spaCyを試していきましょう！ この演習では、[spaCyが対応している60以上の言語](https://spacy.io/usage/models#languages)のうちのいくつかを試すことができます。

### パート1: 英語

- `spacy.blank`を使って、英語 (`"en"`) の`nlp`オブジェクトを作ってください。
- `doc`オブジェクトを作り、文字列を表示してください。

<codeblock id="01_02_01"></codeblock>

### パート2: ドイツ語

- `spacy.blank`を使って、ドイツ語 (`"de"`) の`nlp`オブジェクトを作ってください。
- `doc`オブジェクトを作り、文字列を表示してください。

<codeblock id="01_02_02"></codeblock>

### パート3: スペイン語

- `spacy.blank`を使って、スペイン語 (`"es"`) の`nlp`オブジェクトを作ってください。
- `doc`オブジェクトを作り、文字列を表示してください。

<codeblock id="01_02_03"></codeblock>

### パート4: 日本語

- `spacy.blank`を使って、日本語 (`"ja"`) の`nlp`オブジェクトを作ってください。
- `doc`オブジェクトを作り、文字列を表示してください。

<codeblock id="01_02_04"></codeblock>

</exercise>

<exercise id="3" title="ドキュメントとスパンとトークン">

`nlp`を文字列に適用すると、spaCyはまず文字列を分割し、`Doc`オブジェクトを作ります。
この演習では、`Doc`やそのビューである`Token`と`Span`について詳しく学んでいきます。

### ステップ1

- `spacy.blank`を使って、日本語の`nlp`オブジェクトを作ってください。
- テキストを処理し、`Doc`オブジェクトである`doc`を作ってください。
- `doc`の最初のトークンを選び、`text`を表示してください。

<codeblock id="01_03_01">

Pythonのリストの要素をインデックスを使って取得するのと同じ方法を`Doc`に対して用いることができます。
例えば、`doc[4]`は位置4のトークン、つまりテキストの前から5番目のトークンを表します。
他の多くの言語と同様、Pythonではインデックスは1ではなく0から始まることに注意してください。

</codeblock>

### ステップ2

- `spacy.blank`を使って、日本語の`nlp`オブジェクトを作ってください。
- テキストを処理し、`Doc`オブジェクトである`doc`を作ってください。
- 「ツリーカンガルー」と「ツリーカンガルーとイッカク」のトークンに対応するスライスを`Doc`から作成してください。

<codeblock id="01_03_02">

`Doc`からスライスを作るには、Pythonのリストと同様、`:`記法を使います。
スライスの右端のインデックスのトークンは、スライスに _含まれない_ ことに注意してください。
つまり`0:4`は、位置0,1,2,3のトークンを表し、位置4のトークンは含まれません。

</codeblock>

</exercise>

<exercise id="4" title="語彙の属性">

spaCyの`Doc`と`Token`オブジェクトと、その語彙属性（lexical attributes）を使って、
文字列の中からパーセンテージを表す部分を抜き出す方法をみていきます。
つまり、数字とパーセント記号からなる連続した二つのトークンを探す方法をみていきます。

- `Token`オブジェクトの`like_num`を使って、`doc`に含まれるトークンが数字っぽいかどうかを判定してください。
- `Doc`のうち、数字のトークンの次のトークンを取得してみてください。あるトークン`token`の次のトークンのインデックスは
  `token.i + 1`です。
- 次のトークンの文字列がパーセント記号（%）かどうかをチェックしてください。

<codeblock id="01_04">

トークンは、`doc`からインデックスを使って取得できます。
例えば、`doc[5]`は位置5のトークンを表します。

</codeblock>

</exercise>

<exercise id="5" title="機械学習パイプライン" type="slides">

<slides source="chapter1_02_statistical-models">
</slides>

</exercise>

<exercise id="6" title="パイプラインパッケージ" type="choice">

次のうち、spaCyのパイプラインパッケージに含まれて**いない**ものはどれでしょう？

<choice>
<opt text="パイプラインを作成するための設定ファイル">

全てのパイプラインには`config.cfg`という設定ファイルが含まれています。

全てのパイプラインには`meta.json`というメタファイルが含まれています。
これには、使用言語、ロードすべきパイプライン要素の名前のほか、学習時の設定
等が記載されています。

</opt>
<opt text="機械学習パイプラインの重み">

品詞タグや依存関係ラベル、固有表現等の言語特徴量の抽出をするため、機械学習パイプラインの重みが含まれています。

</opt>
<opt correct="true" text="機械学習パイプライン作成につかったラベル付きデータ">

機械学習パイプラインは、データをもとに学習を行い、パイプラインの重みを更新し、その重みを用いて汎化した予測を行います。
つまり、予測には学習データが不必要なので、パイプラインパッケージには含まれていません。

</opt>
<opt text="パイプラインの語彙データの文字列と、そのハッシュ値">

パイプラインパッケージには、語彙データの要素とそのハッシュ値のマッピングが保存されている`strings.json`という
ファイルが含まれています。
ハッシュ値を用いることで、spaCyは内部で効率的にデータをやり取りしており、文字列は必要な場面でのみ参照されます。

</opt>
</choice>

</exercise>

<exercise id="7" title="パイプラインのロード">

このコースで使うパイプラインは、事前にインストールされているものです。
spaCyの機械学習パイプラインの詳細やインストール方法については、[公式ドキュメント](https://spacy.io/usage/models)をみてください。

- `spacy.load`を使って、小サイズの日本語パイプライン`"ja_core_news_sm"`をロードしてください。
- テキストを処理し、文字列を出力してください。

<codeblock id="01_07">

パイプラインをロードするには、`spacy.load`関数にパイプライン名を渡してください。
パイプライン名は、言語や使用されたトレーニングデータによって異なるので、適切なものを選んで使ってください。

</codeblock>

</exercise>

<exercise id="8" title="言語特徴量の解析">

では実際に、spaCyの学習済みパイプラインを用いて解析をしてみましょう。
お気軽にご自分の文章で試してみてください！
タグやラベルの意味を調べるには、`spacy.explain`を使ってください。
例えば、`spacy.explain("PROPN")` や `spacy.explain("GPE")`とすることで意味を出力することができます。

### パート1

- `nlp`オブジェクトでテキストを処理し、`doc`を作ってください
- それぞれのトークンについて、文字列、`.pos_`（品詞タグ）、`.dep_`（依存関係ラベル）を表示してください。

<codeblock id="01_08_01">

`doc`オブジェクトを作るには、`nlp`オブジェクトを文字列に対して呼び出します。
トークンの属性の文字列を出力するには、属性名にアンダースコアをつけることを忘れないでください。

</codeblock>

### パート2

- テキストを処理し、`doc`オブジェクトを作ってください。
- `doc.ents`をイテレートし、固有表現の文字列とラベルを出力してください。

<codeblock id="01_08_02">

`doc`オブジェクトを作るには、`nlp`オブジェクトを文字列に対して呼び出します。
トークンの属性の文字列を出力するには、属性名にアンダースコアをつけることを忘れないでください。

</codeblock>

</exercise>

<exercise id="9" title="文脈に基づいた固有表現抽出">

機械学習パイプラインの出力は常に正しいとは限りません。
出力は、学習データや入力データに依存します。
一つ例をみてみましょう。

- `nlp`オブジェクトでテキストを処理してください。
- 固有表現をイテレートし、文字列とラベルを出力してください。
- パイプラインは「三保の松原」を正しく抽出できないようです。手動でスパンを作ってみてください。

<codeblock id="01_09">

- `doc`オブジェクトを作るには、文に対して`nlp`オブジェクトを呼び出してください。固有表現は
  `doc.ents`プロパティから取得することができます。
- `Span`オブジェクトを作る最も簡単な方法は、スライス記法を使うことです。例えば、`doc[5:10]`は位置5から位置9までのトークンを示します。
  右端は含まれないことに注意してください。

</codeblock>

</exercise>

<exercise id="10" title="ルールベースマッチ" type="slides">

<slides source="chapter1_03_rule-based-matching">
</slides>

</exercise>

<exercise id="11" title="Matcherを使う">

さて、spaCyのルールベース機能である`Matcher`を使っていきましょう。
以前演習で用いた例を使って、「iPhone X」にマッチするパターンを書いていきます。

- `Matcher`を`spacy.matcher`からインポートしてください。
- `nlp`が持つ共有語彙データ`vocab`を用いて初期化してください。
- 「iPhone」と「X」2つのトークンの文字列（`"TEXT"`）にマッチするパターンを書いてください。
- `matcher.add`メソッドを使って、パターンをmatcherに追加してください。
- matcherを`doc`に対して呼び出し、返り値を`matches`変数に入れてください。
- `matches`をイテレートし、マッチしたスパンを`start`と`end`インデックスから取得してください。

<codeblock id="01_11">

- 共有語彙データは`nlp.vocab`から取得できます。
- パターンは、属性名をキーとする辞書からなるリストです。例えば、`[{"TEXT": "Hello"}]`は
  文字列が「Hello」に正確に一致するトークンにマッチします。
- それぞれのマッチの`start`と`end`は、マッチしたスパンの開始インデックスと終了インデックスを表しています。
  実際のスパンを取得するには、`doc`オブジェクトからスライスしてください。

</codeblock>

</exercise>

<exercise id="12" title="パターンを書く">

この演習では、トークンの属性や演算子を用いてより複雑なパターンを書いていきます。

### パート1

- iOSの完全なバージョン（「iOS 7」「iOS 11」「iOS 10」等）にのみマッチするパターンを**1つ**書いてください。

<codeblock id="01_12_01">

- トークンの文字列に完全一致させたいときは、`TEXT`属性を使いましょう。例えば、`{"TEXT": "Apple"}`
  は「Apple」という文字列を持つトークンにマッチします。
- 数字のトークンにマッチさせたいときは、`"IS_DIGIT"`属性を使いましょう。これは
  トークンが数字だけからなるときのみ`True`となります。

</codeblock>

### パート2

- 品詞が`"PROPN"`（固有名詞）のトークンと、見出し語が「県」のトークンの組み合わせからなる
  トークンにマッチするパターンを**1つ**書いてください。

<codeblock id="01_12_02">

- 固有名詞を探すには`"POS"`属性が`"PROPN"`であるようなトークンを探します。
- 見出し語を指定するには、`"LEMMA"`属性をトークンのパターンに使います。
  例えば、`{"LEMMA": "ある"}`は「あり(ます)」「あっ(た)」「あれ(ば)」等にマッチします。

</codeblock>

### パート3

- 形容詞`"ADJ"`と、一つか二つの名詞`"NOUN"`（つまり、一つの名詞と一つのオプショナルな名詞）からなるトークンの組にマッチするパターンを**1つ**書いてください。

<codeblock id="01_12_03">

- 形容詞を探すには、`"POS"`属性が`"ADJ"`であるようなトークンを探してください。名詞は`"NOUN"`です。
- 演算子は`"OP"`キーに追加します。例えば、`"OP": "?"`は0個もしくは1個にマッチします。

</codeblock>

</exercise>
