Pythonで形態素解析を行うには、いくつかの方法があります。ここでは自然言語処理に特化したライブラリspaCyと日本語の自然言語処理ライブラリGiNZAを用いて形態素解析を行う方法を簡単に説明します。
spaCyとGiNZAとSudachiPyの関係
最初に、spaCyとGiNZAで形態素解析を行うとお伝えしましたが、実際に形態素解析を行っている形態素解析器はSudachiPyになります。spaCyは形態素解析や固有表現抽出、構文解析などを言語に依らず統一的なフレームワークとして提供しており、GiNZAはspaCyを自然言語処理フレームワークとして使用しています。そして、GiNZAは形態素解析部分でSudachiPyを使用しています。そのため、Pythonで形態素解析を行うことだけを考えるのであれば、SudachiPyだけを使用すればよいのですが、自然言語処理の枠組みの中での形態素解析を考えた場合、spaCyを使用して統一的な記述によりコードを書く機会が多いと思うので、ここでは、spaCy->GiNZA->SudachiPyで形態素解析を行います。
Sudachi辞書
Sudachi辞書は次の3つがあります。ここでは、デフォルトのCoreを使用します。
- Small: UniDicの語彙のみを含む
- Core: 基本的な語彙を含む(デフォルト)
- Full: その他の固有名詞を含む
環境構築
spaCyとGiNZAはpipで簡単にインストールできます。SudachiPyとデフォルトのSudachi辞書Coreは、GiNZAのインストール時に自動的にインストールされます。
pip install spacy ginza
形態素解析
Sudachiは3つの分割モードを提供しています。
- Aモード: テキストはUniDicの短縮単位に相当する最短単位に分割されます
- Bモード: 中間単位に分割されます
- Cモード: 固有表現を抽出します
以下では、それぞれ3つのモードで「すだちの主な産地は徳島県神山町や佐那河内村、阿南市です。」を形態素解析してみます。「徳島県神山町」に注目してみてください。
Aモード
import spacy
import ginza
nlp = spacy.load('ja_ginza')
ginza.set_split_mode(nlp, 'A')
text = 'すだちの主な産地は徳島県神山町や佐那河内村、阿南市です。'
for token in nlp(text):
print(f'{token.i} {token.text} {token.lemma_} {token.pos_} {token.pos_} {token.tag_}')
0 すだち すだち NOUN NOUN 名詞-普通名詞-一般
1 の の ADP ADP 助詞-格助詞
2 主な 主な ADJ ADJ 連体詞
3 産地 産地 NOUN NOUN 名詞-普通名詞-一般
4 は は ADP ADP 助詞-係助詞
5 徳島 徳島 PROPN PROPN 名詞-固有名詞-地名-一般
6 県 県 NOUN NOUN 名詞-普通名詞-一般
7 神山 神山 PROPN PROPN 名詞-固有名詞-地名-一般
8 町 町 NOUN NOUN 名詞-普通名詞-助数詞可能
9 や や ADP ADP 助詞-副助詞
10 佐那河内 佐那河内 PROPN PROPN 名詞-固有名詞-地名-一般
11 村 村 NOUN NOUN 名詞-普通名詞-一般
12 、 、 PUNCT PUNCT 補助記号-読点
13 阿南 阿南 PROPN PROPN 名詞-固有名詞-地名-一般
14 市 市 NOUN NOUN 名詞-普通名詞-一般
15 です です AUX AUX 助動詞
16 。 。 PUNCT PUNCT 補助記号-句点
Bモード
import spacy
import ginza
nlp = spacy.load('ja_ginza')
ginza.set_split_mode(nlp, 'B')
text = 'すだちの主な産地は徳島県神山町や佐那河内村、阿南市です。'
for token in nlp(text):
print(f'{token.i} {token.text} {token.lemma_} {token.pos_} {token.pos_} {token.tag_}')
0 すだち すだち NOUN NOUN 名詞-普通名詞-一般
1 の の ADP ADP 助詞-格助詞
2 主な 主な ADJ ADJ 連体詞
3 産地 産地 NOUN NOUN 名詞-普通名詞-一般
4 は は ADP ADP 助詞-係助詞
5 徳島県 徳島県 PROPN PROPN 名詞-固有名詞-地名-一般
6 神山町 神山町 PROPN PROPN 名詞-固有名詞-地名-一般
7 や や ADP ADP 助詞-副助詞
8 佐那河内村 佐那河内村 PROPN PROPN 名詞-固有名詞-地名-一般
9 、 、 PUNCT PUNCT 補助記号-読点
10 阿南市 阿南市 PROPN PROPN 名詞-固有名詞-地名-一般
11 です です AUX AUX 助動詞
12 。 。 PUNCT PUNCT 補助記号-句点
Cモード
import spacy
import ginza
nlp = spacy.load('ja_ginza')
ginza.set_split_mode(nlp, 'C')
text = 'すだちの主な産地は徳島県神山町や佐那河内村、阿南市です。'
for token in nlp(text):
print(f'{token.i} {token.text} {token.lemma_} {token.pos_} {token.pos_} {token.tag_}')
0 すだち すだち NOUN NOUN 名詞-普通名詞-一般
1 の の ADP ADP 助詞-格助詞
2 主な 主な ADJ ADJ 連体詞
3 産地 産地 NOUN NOUN 名詞-普通名詞-一般
4 は は ADP ADP 助詞-係助詞
5 徳島県神山町 徳島県神山町 PROPN PROPN 名詞-固有名詞-地名-一般
6 や や ADP ADP 助詞-副助詞
7 佐那河内村 佐那河内村 PROPN PROPN 名詞-固有名詞-地名-一般
8 、 、 PUNCT PUNCT 補助記号-読点
9 阿南市 阿南市 PROPN PROPN 名詞-固有名詞-地名-一般
10 です です AUX AUX 助動詞
11 。 。 PUNCT PUNCT 補助記号-句点
トークンの属性
上記のコードでtokenのlemma_(基本形)などを出力しましたが、tokenから得られる属性の一覧は次になります。
Name | Type | Description |
---|---|---|
doc | Doc | 親文書 |
lex | Lexeme | 基礎となる語彙素 |
sent | Span | このトークンが含まれる文の範囲 |
text | str | 逐語的なテキスト内容 |
text_with_ws | str | 末尾にスペース文字がある場合はそれを付けたテキスト内容 |
whitespace_ | str | 末尾のスペース文字(存在する場合) |
orth | int | 逐語的テキストコンテンツのID |
orth_ | str | 逐語的テキストコンテンツ(Token.textと同一)。主に他の属性との一貫性を保つために存在します。 |
vocab | vocab | 親Docの語彙オブジェクト |
tensor | numpy.ndarray | 親Docのテンソルのトークンスライス |
head | Token | このトークンの構文上の親、または「ガバナー」 |
left_edge | Token | このトークンの構文上の子孫の左端のトークン |
right_edge | Token | このトークンの構文上の子孫の右端のトークン |
i | int | 親文書内のトークンのインデックス |
ent_type | int | 名前付きエンティティ型 |
ent_type_ | str | 名前付きエンティティ型 |
ent_iob | int | 名前付きエンティティタグのIOBコード。3はトークンがエンティティの始まりであること、2はエンティティの外側にあること、1はエンティティの内側にあること、0はエンティティタグが設定されていないことを意味します。 |
ent_iob_ | str | 名前付きエンティティタグのIOBコード。「B」はトークンがエンティティの始まりであること、「I」はトークンがエンティティの内側にあること、「O」はトークンがエンティティの外側にあること、"" はエンティティタグが設定されていないことを意味します。 |
ent_kb_id | int | このトークンが含まれる名前付きエンティティを参照するナレッジベースID(存在する場合) |
ent_kb_id_ | str | このトークンが含まれる名前付きエンティティを参照するナレッジベースID(存在する場合) |
ent_id | int | このトークンが含まれる名前付きエンティティのインスタンスID(存在する場合)。現在は使用されていませんが、共参照の解決に使用される可能性があります。 |
ent_id_ | str | このトークンが含まれるエンティティのインスタンスID(存在する場合)。現在は使用されていませんが、共参照の解決に使用される可能性があります。 |
lemma | int | 語形変化接尾辞のないトークンの基本形 |
lemma_ | str | 語形変化接尾辞のないトークンの基本形 |
norm | int | トークンのノルム、つまりトークンテキストの正規化形式。言語のトークナイザー例外で設定できます。 |
norm_ | str | トークンのノルム、つまりトークンテキストの正規化形式。言語のトークナイザー例外で設定できます。 |
lower | int | トークンの小文字形式 |
lower_ | str | トークンテキストの小文字形式。Token.text.lower() と同等です。 |
shape | int | トークンの文字列を正書法の特徴に合わせて変換します。英字は x または X に、数字は d に置き換えられ、同じ文字の連続は長さ 4 より後で切り捨てられます。例: "Xxxx" または "dd"。 |
shape_ | str | トークンの文字列を正書法の特徴に合わせて変換します。英字は x または X に、数字は d に置き換えられ、同じ文字の連続は長さ 4 より後で切り捨てられます。例: "Xxxx" または "dd"。 |
prefix | int | トークンの先頭からの長さ N の部分文字列のハッシュ値。デフォルトは N=1 です。 |
prefix_ | str | トークンの先頭からの長さ N の部分文字列。デフォルトは N=1 です。 |
suffix | int | トークンの末尾からの長さ N の部分文字列のハッシュ値。デフォルトは N=3 です。 |
suffix_ | str | トークンの末尾からの長さ N の部分文字列。デフォルトは N=3 です。 |
is_alpha | bool | トークンはアルファベット文字で構成されていますか? token.text.isalpha() と同等です。 |
is_ascii | bool | トークンは ASCII 文字で構成されていますか? all(ord(c) < 128 for c in token.text) と同等です。 |
is_digit | bool | トークンは数字で構成されていますか? token.text.isdigit() と同等です。 |
is_lower | bool | トークンは小文字ですか? token.text.islower() と同等です。 |
is_upper | bool | トークンは大文字ですか? token.text.isupper() と同等です。 |
is_title | bool | トークンはタイトルケースですか? token.text.istitle() と同等です。 |
is_punct | bool | トークンは句読点ですか? |
is_left_punct | bool | トークンは左句読点ですか?(例:「(」) |
is_right_punct | bool | トークンは右句読点ですか?(例:「)」) |
is_sent_start | bool | トークンは文頭ですか?(bool 型、または不明な場合は None 型)。ドキュメント内の最初のトークンの場合はデフォルトで True になります。 |
is_sent_end | bool | トークンは文末ですか?(bool 型、または不明な場合は None 型)。 |
is_space | bool | トークンは空白文字で構成されていますか?(token.text.isspace() と同等です。) |
is_bracket | bool | トークンは括弧ですか? |
is_quote | bool | トークンは引用符ですか? |
is_currency | bool | トークンは通貨記号ですか? |
like_url | bool | トークンはURLに似ていますか? |
like_num | bool | トークンは数値を表していますか?例:「10.9」、「10」、「ten」など。 |
like_email | bool | トークンはメールアドレスに似ていますか? |
is_oov | bool | トークンは語彙外ですか(つまり、単語ベクトルを持っていませんか)? |
is_stop | bool | トークンは「ストップリスト」の一部ですか? |
pos | int | Universal POSタグセットからの粗粒度品詞 |
pos_ | str | Universal POSタグセットからの粗粒度品詞 |
tag | int | 細粒度品詞 |
tag_ | str | 細粒度品詞 |
morph | MorphAnalysis | 形態素解析 |
dep | int | 統語的依存関係 |
dep_ | str | 統語的依存関係 |
lang | int | 親文書の語彙の言語 |
lang_ | str | 親文書の語彙の言語 |
prob | float | トークンの単語タイプ(語彙における文脈非依存エントリ)の平滑化対数確率推定値 |
idx | int | 親文書内におけるトークンの文字オフセット |
sentiment | float | トークンの正負を示すスカラー値 |
lex_id | int | トークンの語彙タイプのシーケンシャルID。単語ベクトルなどのテーブルへのインデックス付けに使用されます。 |
rank | int | トークンの語彙タイプのシーケンシャルID。単語ベクトルなどのテーブルへのインデックス付けに使用されます。 |
cluster | int | ブラウンクラスターID |
_ | Underscore | カスタム属性拡張を追加するためのユーザー空間 |