spaCy入門 (1) - 事始め
以下の記事を参考に書いてます。サンプルは「GiNZA」で日本語対応してます。
・spaCy 101: Everything you need to know
1. spaCy とは?
「spaCy」は、Pythonの自然言語処理ライブラリです。プロダクト用に設計されており、大量のテキストの処理および理解を行うアプリの構築に役立ちます。「情報抽出」「自然言語理解」「深層学習のテキストの前処理」に使用できます。
2. spaCy ではないもの
◎ spaCyはWebサービスではありません。
Webサービスではなく、NLPアプリを構築するために設計されたライブラリです。
◎ spaCyはチャットボットエンジンではありません。
会話型アプリの強化にも利用できますが、チャットボット用に設計されたものではなく、テキスト処理機能のみを提供します。
◎ spaCyは研究用のソフトウェアではありません。
最新の研究に基づいて構築されていますが、プロダクト用に設計されています。研究用に設計された「NLTK」「CoreNLP」とは異なります。「spaCy」は、自然言語処理のアルゴリズムの選択をユーザーに求めません。これによって、より良いパフォーマンスと開発効率を提供します。
◎ spaCyは会社ではありません。
オープンソースのライブラリです。「spaCy」を公開している当社は「Explosion AI」と呼ばれています。
3. 機能
「spaCy」の機能は、次のとおりです。
・トークン化 : テキストを単語や句読点に分割。
・品詞(POS: Part-of-speech)のタグ付け : 単語種別(動詞や名詞など)をトークンに割り当て。
・依存関係の解析 : 構文依存関係(個々のトークン間の関係)ラベルをトークンに割り当て。
・レンマ化 : 単語の基本形の割り当て。
・文境界検出(SBD : Sentence Boundary Detection): 文の境界を検出。
・名前付きエンティティの認識(NER : Named Entity Recognition) : 人、会社、場所など、名前付きエンティティ(実オブジェクト)にラベルを付加。
・エンティティリンク(EL: Entity Linking) : エンティティを知識ベースの一意の識別子に変換。
・ 類似度 : 単語、テキストスパン、テキストの比較、および類似度の計算。
・ テキスト分類 : テキスト全体または一部にカテゴリ(またはラベル)を割り当て。
・ルールベースのマッチング : 正規表現と同様に、テキストと言語アノテーションに基づいてトークンのシーケンスを検索。
・訓練 : 統計モデルの予測の更新と改善。
・シリアライゼーション : オブジェクトをファイル(またはバイト文字列)に保存。
4. 統計モデル
「spaCy」の一部の機能は独立して動きますが、多くの機能は「統計モデル」が必用になります。これにより、「spaCy」は「言語アノテーション」(単語が名詞と動詞のどちらかなど)を予測できるようになります。
「統計モデル」に含まれるコンポーネントは、次のとおりです。
・バイナリウェイト : 「品詞タガー」「依存関係パーサー」「名前付きエンティティ認識」で、アノテーションを予測するために利用。
・語彙エントリ : 単語と文脈に依存しない属性(つづりなど)。
・データファイル : 見出し語化ルールやルックアップテーブルなど。
・単語ベクトル : 単語の類似程度を判断するベクトル値。
・構成オプション : 言語や処理パイプラインの設定など。
5. 言語アノテーション
「spaCy」はテキストを解析してトークンの「言語アノテーション」を予測します。これには、「単語の種類」「単語の相互関係」が含まれます。
「google」が動詞として使われているか、特定のWebサイトまたは会社を参照しているかによって、大きな違いが生じます。
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
for token in doc:
print(token.text, token.pos_, token.dep_)
銀座 PROPN compound
で ADP case
ランチ NOUN obj
を ADP case
ご NOUN compound
一緒 VERB ROOT
し AUX aux
ましょう AUX aux
。 PUNCT punct
spacy.load() で統計モデルをロードします。戻り値は、Language で、通常は nlp という変数名で保持します。テキスト引数で nlp() を呼ぶことで、言語アノテーションの予測結果 doc が返されます。
6. トークン化
「spaCy」は「統計モデル」を使って、テキストをトークン化します。これは、各言語固有のルールで処理されます。
文末の句読点は分割する必要がありますが、“U.K.” は 1つのトークンのままにする必要があります。
「GiNZA」では形態素解析でトークン化しています。
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
for token in doc:
print(token.text)
銀座
で
ランチ
を
ご
一緒
し
ましょう
。
7. 品詞 と 依存関係 の予測
「spaCy」は「統計モデル」を使って、トークンの「品詞」と「依存関係」を予測します。予測した「品詞」と「依存関係」は、トークン属性で確認できます。
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
for token in doc:
print(token.text, # テキスト
token.lemma_, # レンマ
token.pos_, # 品詞
token.tag_, # 品詞詳細
token.dep_, # 構文従属関係
token.shape_, # 正書法の特徴(x:文字,d:数値)
token.is_alpha, # 文字かどうか
token.is_stop) # ストップリストの一部かどうか
「spaCy」は全文字列をハッシュ値にエンコードして、メモリ削減します。文字列表現を取得するには、名前に「アンダースコア(_)」を追加します。
「spaCy」の displaCy visualizer を使用して、「依存関係」を確認するコードは、次のとおりです。
import spacy
from spacy import displacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
displacy.serve(doc, style='dep')
8. 名前付きエンティティ
「名前付きエンティティ」は、名前が割り当てられた実世界のオブジェクトです。「人」「国」「製品」「本のタイトル」などがこれにあたります。「spaCy」は、テキスト内の様々な「名前付きエンティティ」を認識できます。モデルは訓練データに強く依存するため、常に正しく機能するわけではなく、ユースケースによっては調整が必要になります。
「名前付きエンティティ」は、doc.entsでアクセスできます。
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
for ent in doc.ents:
print(ent.text, ent.start_char, ent.end_char, ent.label_)
「spaCy」の displaCy visualizer を使用して、名前付きエンティティを確認するコードは、次のとおりです。
import spacy
from spacy import displacy
nlp = spacy.load('ja_ginza')
doc = nlp('銀座でランチをご一緒しましょう。')
displacy.serve(doc, style="ent")
9. 単語ベクトル と 類似度
「単語ベクトル」(word vector)は、「word2vec」を使用して生成できます。通常は次のような形式になります。
# BANANA.VECTOR
array([2.02280000e-01, -7.66180009e-02, 3.70319992e-01,
3.28450017e-02, -4.19569999e-01, 7.20689967e-02,
-3.74760002e-01, 5.74599989e-02, -1.24009997e-02,
5.29489994e-01, -5.23800015e-01, -1.97710007e-01,
-3.41470003e-01, 5.33169985e-01, -2.53309999e-02,
1.73800007e-01, 1.67720005e-01, 8.39839995e-01,
5.51070012e-02, 1.05470002e-01, 3.78719985e-01,
2.42750004e-01, 1.47449998e-02, 5.59509993e-01,
1.25210002e-01, -6.75960004e-01, 3.58420014e-01,
# ... and so on ...
3.66849989e-01, 2.52470002e-03, -6.40089989e-01,
-2.97650009e-01, 7.89430022e-01, 3.31680000e-01,
-1.19659996e+00, -4.71559986e-02, 5.31750023e-01], dtype=float32)
「類似度」は、「単語ベクトル」を比較することによって計算します。
【注意】 コンパクトかつ高速にするために、「spaCy」の小さなモデル(smで終わるパッケージ)には「単語ベクトル」が付属せず、状況依存のテンソルのみが含まれます。つまり、similarity() を使用してドキュメント、スパン、トークンを比較することはできますが、結果はそれほど良くなく、個々のトークンにはベクトルが割り当てられません。 したがって、実際の「単語ベクトル」を使用するには、より大きなモデルをダウンロードする必要があります。
- python -m spacy download en_core_web_sm
+ python -m spacy download en_core_web_lg
組み込みの「単語ベクトル」が付属しているモデルでは、Token.vector として使用できます。Doc.vector と Span.vector は、デフォルトでトークンベクトルの平均になります。トークンにベクトルが割り当てられているかどうかを確認し、ベクトルの正規化に使用できるL2ノルムを取得することもできます。
import spacy
nlp = spacy.load('ja_ginza')
tokens = nlp('犬 猫 バナナ ほげ')
for token in tokens:
print(token.text, token.has_vector, token.vector_norm, token.is_oov)
犬 True 11.104502 True
猫 True 11.200727 True
バナナ True 10.413499 True
ほげ False 0.0 False
「犬」「猫」「バナナ」という言葉は日本語ではかなり一般的であるため、モデルの語彙の一部であり、ベクトルが付いています。一方、「ほげ」という単語はそれほど一般的ではなく、語彙の範囲外です。そのため、そのベクトル表現は存在しません。 より多くのベクトルを持つ大きなボキャブラリが、アプリケーションにメリットがある場合は、大きいモデルを使用するか、100万個を超える一意のベクトルを含む en_vectors_web_lg などの完全なベクトルパッケージにロードすることを検討してください。
「spaCy」は2つのオブジェクトを比較し、それらがどの程度類似しているかを予測することができます。 類似性の予測は、レコメンデーションシステムの構築や重複のフラグ付けに役立ちます。たとえば、ユーザーが現在見ているコンテンツに類似しているユーザーコンテンツを提案したり、サポートチケットが既存のものと非常に類似している場合は、サポートチケットに重複のラベルを付けたりできます。
Doc、Span、Token には similarity() が付属しており、これを使用して別のオブジェクトと比較し、類似度を判断できます。もちろん、類似度は常に主観的です。「犬」と「猫」が類似しているかどうかは、実際の見方によって異なります。「spaCy」の類似度モデルは通常、かなり汎用的な類似度の定義を前提としています。
import spacy
nlp = spacy.load('ja_ginza')
tokens = nlp('犬 猫 バナナ')
for token1 in tokens:
for token2 in tokens:
print(token1.text, token2.text, token1.similarity(token2))
犬 犬 1.0
犬 猫 0.6731544
犬 バナナ 0.2025507
猫 犬 0.6731544
猫 猫 1.0
猫 バナナ 0.3003257
バナナ 犬 0.2025507
バナナ 猫 0.3003257
バナナ バナナ 1.0
この場合、モデルの予測はかなり適切です。犬は猫によく似ていますが、バナナはどちらにも似ていません。同一のトークンは明らかに100%互いに類似しています(ベクトル演算と浮動小数点の不正確さのため、必ずしも正確に1.0とは限りません)。
10. パイプライン
テキストに対して nlp を呼び出すと、「spaCy」はテキストをトークン化してDocオブジェクトを生成します。その後、ドキュメントはいくつかの異なるステップで処理されます。これは、「処理パイプライン」とも呼ばれます。デフォルトモデルで使用されるパイプラインは、「タガー」「パーサー」「エンティティ認識機能」で構成されています。各パイプラインコンポーネントは処理されたドキュメントを返し、それが次のコンポーネントに渡されます。
◎ tokenizer: Tokenizer
テキストをトークンに分割。
◎ tagger: Tagger
品詞タグを割り当て。
◎ parser: DependencyParser
依存関係ラベルを割り当て。
◎ ner: EntityRecognizer
名前付きエンティティを検出してラベルを付け。
◎ textcat: TextCategorizer
ドキュメントラベルを割り当て。
◎ カスタムコンポーネント
カスタム属性、メソッド、またはプロパティを割り当て。
「処理パイプライン」は、常に「統計モデル」とその機能に依存しています。たとえば、モデルにエンティティラベルの予測を行うためのデータが含まれている場合、パイプラインにエンティティ認識コンポーネントのみを含めることができます。これが、各モデルがメタデータで使用するパイプラインを、コンポーネント名を含む単純なリストとして指定する理由になります。
"pipeline": ["tagger", "parser", "ner"]
11. 語彙、ハッシュ、レンマ
「spaCy」は可能な限り、複数のドキュメントで共有される「語彙」を保存しようとします。「spaCy」は、メモリを節約するために、全文字列をハッシュにエンコードします。たとえば、この場合、「coffee」にはハッシュ「3197928453018144401」があります。「ORG」などのエンティティラベルや「VERB」などの品詞タグもエンコードされます。 内部的には、「spaCy」はハッシュを使うだけです。
さまざまなコンテキストで「coffee」という単語を含む多くのドキュメントを処理する場合、毎回「coffee」という正確な文字列を保存すると、スペースを取りすぎてしまいます。 そこで代わりに文字列をハッシュしてStringStoreに格納します。StringStoreは、双方向で機能するルックアップテーブルと考えることができます。文字列を検索してハッシュを取得したり、ハッシュを取得して文字列を取得したりできます。
import spacy
nlp = spacy.load('ja_ginza')
doc = nlp("私はコーヒーが好き")
print(doc.vocab.strings['コーヒー']) # 16003280304011083252
print(doc.vocab.strings[16003280304011083252]) # 'コーヒー'
16003280304011083252
コーヒー
すべての文字列がエンコードされたので、語彙のエントリに単語テキスト自体を含める必要はありません。代わりに、ハッシュ値を介してStringStoreで検索できます。 Lexemeとも呼ばれる語彙の各エントリには、単語に関するコンテキストに依存しない情報が含まれています。たとえば、「好き」が動詞や名詞として使用されているかどうかに関係なく、そのスペルとアルファベット文字で構成されているかどうかは変わりません。そのハッシュも常に同じです。
単語のハッシュへのマッピングは、どの状態にも依存しません。 各値が一意であることを確認するために、「spaCy」はハッシュ関数を使用して、単語文字列に基づいてハッシュを計算します。これは、使用しているモデルや「spaCy」の設定方法に関係なく、「coffee」のハッシュは常に同じであることも意味します。
ただし、「3197928453018144401」を「coffee」に戻す方法はありません。 「spaCy」でできることは、語彙でそれを調べることだけです。そのため、作成するすべてのオブジェクトが同じ語彙にアクセスできることを常に確認する必要があります。 一致しない場合、「spaCy」は必要な文字列を見つけられない可能性があります。
import spacy
from spacy.tokens import Doc
from spacy.vocab import Vocab
nlp = spacy.load('ja_ginza')
doc = nlp("私はコーヒーが好き")
print(doc.vocab.strings['コーヒー']) # 16003280304011083252
print(doc.vocab.strings[16003280304011083252]) # 'コーヒー'
empty_doc = Doc(Vocab()) # 空のVocabを含む新しいドキュメントを生成
# empty_doc.vocab.strings[16003280304011083252] エラー発生
empty_doc.vocab.strings.add("コーヒー") # 「コーヒー」を追加してハッシュを生成
print(empty_doc.vocab.strings[16003280304011083252]) # 'コーヒー' 👍
new_doc = Doc(doc.vocab) # 最初のドキュメントの語彙で新しいドキュメントを生成
print(new_doc.vocab.strings[16003280304011083252]) # 'コーヒー' 👍
コーヒー
コーヒー
コーヒー
語彙に「3197928453018144401」の文字列が含まれていない場合、「spaCy」はエラーを発生させます。 「coffee」を手動で再度追加できますが、これはドキュメントにその単語が含まれていることが実際にわかっている場合にのみ機能します。この問題を回避するために、Docまたはnlpを保存するときに「spaCy」は語彙もエクスポートします。これにより、オブジェクトとそのエンコードされたアノテーション、およびそれをデコードするための「キー」が提供されます。
12. ナレッジベース
「spaCy」はエンティティリンクタスクをサポートするために、外部ナレッジをナレッジベースに保存します。「ナレッジベース」(KB)はVocabを使用してデータを効率的に保存します。
「ナレッジベース」は、最初にすべてのエンティティを追加することによって作成されます。次に、潜在的な言及またはエイリアスごとに、関連するKB IDとそれらの以前の確率のリストが追加されます。これらの事前確率の合計は、特定のエイリアスで1を超えてはなりません。
import spacy
from spacy.kb import KnowledgeBase
# モデルを読み込み、空のナレッジベースを作成
nlp = spacy.load('ja_ginza')
kb = KnowledgeBase(vocab=nlp.vocab, entity_vector_length=3)
# エンティティの追加
kb.add_entity(entity="Q1004791", freq=6, entity_vector=[0, 3, 5])
kb.add_entity(entity="Q42", freq=342, entity_vector=[1, 9, -3])
kb.add_entity(entity="Q5301561", freq=12, entity_vector=[-2, 4, 2])
# エイリアスの追加
kb.add_alias(alias="Douglas", entities=["Q1004791", "Q42", "Q5301561"], probabilities=[0.6, 0.1, 0.2])
kb.add_alias(alias="Douglas Adams", entities=["Q42"], probabilities=[0.9])
print()
print("Number of entities in KB:",kb.get_size_entities()) # 3
print("Number of aliases in KB:", kb.get_size_aliases()) # 2
Number of entities in KB: 3
Number of aliases in KB: 2
13. 候補生成
テキストエンティティが与えられた場合、ナレッジベースは、もっともらしい候補またはエンティティ識別子のリストを提供します。EntityLinkerは、候補のこのリストを入力として受け取り、ドキュメントのコンテキストを前提として、言及を最も可能性の高い識別子に変換します。
import spacy
from spacy.kb import KnowledgeBase
nlp = spacy.load('ja_ginza')
kb = KnowledgeBase(vocab=nlp.vocab, entity_vector_length=3)
# エンティティの追加
kb.add_entity(entity="Q1004791", freq=6, entity_vector=[0, 3, 5])
kb.add_entity(entity="Q42", freq=342, entity_vector=[1, 9, -3])
kb.add_entity(entity="Q5301561", freq=12, entity_vector=[-2, 4, 2])
# エイリアスの追加
kb.add_alias(alias="Douglas", entities=["Q1004791", "Q42", "Q5301561"], probabilities=[0.6, 0.1, 0.2])
candidates = kb.get_candidates("Douglas")
for c in candidates:
print(" ", c.entity_, c.prior_prob, c.entity_vector)
Q1004791 0.6000000238418579 [0.0, 3.0, 5.0]
Q42 0.10000000149011612 [1.0, 9.0, -3.0]
Q5301561 0.20000000298023224 [-2.0, 4.0, 2.0]
14. シリアライズ
パイプライン、語彙、ベクトル、エンティティを変更したり、モデルを更新したりしている場合は、最終的には進捗状況を保存する必要があります(たとえば、nlpオブジェクトにあるものすべて)。つまり、その内容と構造を、ファイルやバイト文字列などの保存可能な形式に変換する必要があります。このプロセスはシリアル化と呼ばれます。 「spaCy」には、シリアル化メソッドが組み込まれており、Pickleプロトコルをサポートしています。
全てのコンテナクラス、つまり言語(nlp)、Doc、Vocab、StringStoreには、次のメソッドが用意されています。
◎ to_bytes: bytes
data = nlp.to_bytes()
◎ from_bytes: object
nlp.from_bytes(data)
◎ to_disk: -
nlp.to_disk("/path")
◎ from_disk: object
nlp.from_disk("/path")
15. 訓練
「spaCy」のモデルは統計的です。割り当てる品詞タグや、単語が名前付きエンティティであるかどうかなど、モデルが行う「決定」は全て予測になります。このモデルを訓練するには、訓練データが必要です。これは、品詞タグ、名前付きエンティティ、またはその他の情報である可能性があります。
次に、モデルにラベルのないテキストが表示され、予測を行います。私たちは正しい答えを知っているので、予測と答えの差を計算する損失関数の誤差勾配の形で、モデルのフィードバックを返すことができます。
モデルを訓練する時は、答えを記憶するだけではなく、汎化性能を上げたいと考えます。「Amazon」が「会社」であることを学習させるのではなく、「Amazon」はこのような状況ではほとんどの場合「会社」であることを学習させたいのです。そのため、訓練データは常に処理したいデータを表す必要があります。Wikipediaで訓練されたモデルでは、最初の人の文章は非常にまれであり、Twitterではパフォーマンスが低下する可能性があります。同様に、ロマンティックな小説で訓練されたモデルは、おそらく法的文章ではうまく機能しません。
これは、モデルのパフォーマンスを把握し、モデルが正しいことを学習しているかどうかを知るために、訓練データだけでなく、評価データも必要になることを意味します。訓練データを使用してモデルをテストするだけでは、モデルがどれだけ汎化されているかがわかりません。
16. 言語データ
言語は全て異なりますが、通常、一般的な単語の中に、例外や特別なケースがたくさんあります。これらの例外には、言語間で共有されるものもあれば、完全に固有なものもあります。完全に固有なものは、ハードコーディングする必要があります。langモジュールには、全ての言語固有のデータが含まれており、単純なPythonファイルに編成されています。これにより、データの更新と拡張が容易になります。
ディレクトリルートの共有言語データには、言語全体で一般化できるルールが含まれています。たとえば、基本的な句読点、絵文字、顔文字、1文字の略語、および「and」などの異なるスペルを持つ同等のトークンの規範などです。これにより、 モデルはより正確な予測を行います。サブモジュールの個々の言語データには、特定の言語にのみ関連するルールが含まれています。また、すべてのコンポーネントをまとめて、言語サブクラス(たとえば、英語やドイツ語)を作成できます。
・Stop words : 「and」や「|」など、フィルタリングに役立つことが多い言語の最も一般的な単語のリスト。一致するトークンは、is_stopに対してTrueを返す。
・Tokenizer exceptions : トークナイザーの特殊なケースのルール。たとえば、「can’t」などの短縮形や、「U.K.」などの句読点を含む略語。
・Norm exceptions : トークンを正規化してモデルの予測を改善するための特殊なケースのルール(アメリカとイギリスのスペルなど)。
・Punctuation rules : トークンを分割するための正規表現。句読点や絵文字などの特殊文字。プレフィックス、サフィックス、インフィックスのルールが含まれている。
・Character classes : ラテン文字、引用符、ハイフン、アイコンなどの正規表現で使用される文字クラス。
・Lexical attributes : トークンに字句属性を設定するためのカスタム関数。 like_num。「ten」や「hundred」などの言語固有の単語が含まれる。
・Syntax iterators : 構文に基づいてDocオブジェクトのビューを計算する関数。現時点では、名詞チャンクにのみ使用される。
・Tag map : タグセット内の辞書マッピング文字列がUniversal Dependenciesタグに設定されている。
・Morph rules : 個人代名詞のような不規則な単語の形態素解析の例外ルール。
・Lemmatizersp : 基本形を割り当てるための見出し語化規則またはルックアップベースの見出し語化テーブル。たとえば、「was」の「be」。
17. アーキテクチャ
「spaCy」のデータ構造の中心は、Doc と Vocab です。Doc は、一連のトークンと全アノテーションを所有します。Vocab は、ドキュメント全体で共通の情報を利用できるルックアップテーブルを所有しています。文字列、単語ベクトル、字句属性を一元化することにより、このデータの複数のコピーを保存することを避けます。これはメモリを節約し、単一の真の情報源があることを保証します。
また、テキストのアノテーションは単一の真の情報源を許可するように設計されています。Docはデータを所有し、Span と Token はそれを指すビューです。 Doc は Tokenizerによって構築され、パイプラインのコンポーネントによって適切に変更されます。Language はこれらのコンポーネントを調整します。 生のテキストを取得してパイプライン経由で送信し、アノテーション付きドキュメントを返します。また、訓練とシリアライズを調整します。
◎ コンテナオブジェクト
・Doc : 言語アノテーションにアクセスするためのコンテナ。
・Span : Docオブジェクトのスライス。
・Token : トークン(単語、句読記号、空白など)
・Lexeme : 語彙のエントリ。単語トークンとは対照的に、コンテキストのない単語種別。品詞タグ、依存関係解析などはない。
◎ 処理パイプライン
・Language : テキスト処理パイプライン。通常、これをnlpとしてプロセスごとに1回ロードし、アプリケーションの周りにインスタンスを渡す。
・Tokenizer : テキストをセグメント化し、検出されたセグメント境界でDocオブジェクトを作成。
・Lemmatizer : 単語の基本形を決定。
・Morphology : 単語とその品詞タグに基づいて、見出し語、名詞の大文字小文字、動詞時制などの言語機能を割り当て。
・Tagger : Docオブジェクトの品詞タグにアノテーションを付加。
・DependencyParser : Docオブジェクトの構文依存関係にアノテーションを付加。
・EntityRecognizer : 名前付きエンティティにアノテーションを付加。
・TextCategorizer : Docオブジェクトにカテゴリまたはラベルを割り当て。
・Matcher : 正規表現と同様に、パターンルールに基づいてトークンのシーケンスを照合。
・PhraseMatcher : フレーズに基づいてトークンのシーケンスを照合。
・EntityRuler : トークンベースのルールまたは完全なフレーズ一致を使用して、エンティティスパンをドキュメントに追加。
・Sentencizer : 依存関係の解析を必要としないカスタムの文境界検出ロジックを実装。
◎ その他のクラス
・Vocab : レンマへのアクセスを可能にする語彙のルックアップテーブル。
・StringStore : 文字列とハッシュ値のマッピングを行う。
・Vectors : 文字列をキーとしたベクターデータのコンテナークラス。
・GoldParse : アノテーションを訓練するためのコレクション。
・GoldCorpus : JSONファイル形式を使用したアノテーション付きコーパス。