STEP 4:日本語NLPの特殊性

🇯🇵 STEP 4: 日本語NLPの特殊性

日本語特有の処理と形態素解析ツール(MeCab、Janome、SudachiPy)の使い方を習得します

📋 このステップで学ぶこと

  • 日本語の特徴(分かち書きなし、表記の多様性)
  • 形態素解析とは何か
  • MeCab の使い方と辞書の選択
  • Janome(純Pythonの形態素解析器)
  • SudachiPy(最新の形態素解析器)
  • 実装:日本語テキスト前処理パイプライン

練習問題: 4問

💻 実行環境について

このステップでは日本語処理用のライブラリをインストールします。
Google Colabで実行する場合、セルごとにインストールコマンドを実行してください。
インストール後、ランタイムの再起動が必要な場合があります。

🎯 1. 日本語の特徴と課題

日本語のテキスト処理は、英語とは大きく異なります。 まず、その違いを理解しましょう。

1-1. 英語と日本語の決定的な違い

🔤 英語の場合:トークン化が簡単

英語は単語がスペースで区切られているため、簡単に分割できます。

【英語のトークン化】 文章: “I love natural language processing” 分割方法: スペースで区切るだけ! → split() メソッドで簡単にできる 結果: [“I”, “love”, “natural”, “language”, “processing”]
🇯🇵 日本語の場合:トークン化が困難

日本語には単語の区切り(スペース)がありません。

【日本語のトークン化の問題】 文章: “私は自然言語処理が好きです” 問題: どこで区切ればいい? ❌ 文字単位: [“私”, “は”, “自”, “然”, “言”, “語”, “処”, “理”, …] → 意味のある単位になっていない ❌ 適当に区切る: [“私は”, “自然”, “言語処理”, “が好き”, “です”] → 文法的に不正確 ✅ 正しい分割: [“私”, “は”, “自然言語処理”, “が”, “好き”, “です”] → 形態素解析が必要!

1-2. 日本語の特殊性①:分かち書きがない

⚠️ 最大の課題:単語の境界が不明確

日本語は「分かち書き」(単語をスペースで区切る書き方)をしないため、 コンピュータにとって単語の境界を判断することが非常に難しいです。

【英語 vs 日本語の比較】 ■ 英語 “I love NLP” ↓ split() で分割 [“I”, “love”, “NLP”] → 簡単! ■ 日本語 “私はNLPが好きです” ↓ split() で分割 [“私はNLPが好きです”] ← 分割されない! → 特殊なツールが必要

1-3. 日本語の特殊性②:4種類の文字が混在

📝 日本語の文字体系

日本語は4種類の文字が混在しており、これも処理を複雑にします。

【日本語の4種類の文字】 1. ひらがな: “ありがとう”、”わたし” 2. カタカナ: “コンピュータ”、”プログラミング” 3. 漢字: “自然言語処理”、”機械学習” 4. 英数字: “NLP”、”AI”、”2024年” 【1文の中に全て混在】 “2024年のAI技術はすごい” ↑ ↑ ↑ ↑ 数字 英字 漢字 ひらがな

1-4. 日本語の特殊性③:表記のゆれ

同じ意味でも複数の表記が存在することがあります。

【表記ゆれの例】 ■ カタカナの長音 “コンピュータ” vs “コンピューター” “サーバ” vs “サーバー” ■ 漢字とひらがな “出来る” vs “できる” “事” vs “こと” ■ 全角と半角 “123” vs “123” “AI” vs “AI” ■ 数字の表記 “10個” vs “十個” vs “10個” → これらを同一視する処理(正規化)が必要

1-5. 日本語の特殊性④:単語の曖昧性

【曖昧性の例1:境界の曖昧性】 “今日は晴れです” 分割パターン1: “今日” + “は” + “晴れ” + “です” (「今日」= 名詞、「は」= 助詞) 分割パターン2: “今日は” + “晴れ” + “です” (「今日は」= 接続詞的に使う場合) → 文脈で判断が必要 【曖昧性の例2:複合語の扱い】 “機械学習” 分割パターン1: “機械学習”(1つの複合語として扱う) 分割パターン2: “機械” + “学習”(2つの単語に分割) → タスクによって最適解が異なる
💡 なぜ形態素解析が必要なのか?

上記の課題を解決するために、形態素解析という技術が必要です。 形態素解析により:

  • 単語の境界を正しく認識できる
  • 品詞(名詞、動詞、形容詞等)を判定できる
  • 基本形(原形)を取得できる
  • 読みがなを取得できる

🔍 2. 形態素解析とは?

形態素解析は、日本語NLPの最も基本的な処理です。 この仕組みを理解しましょう。

2-1. 形態素とは?

📖 形態素の定義

形態素(Morpheme)とは、意味を持つ最小の言語単位のことです。 これ以上分割すると意味がなくなる単位です。

【形態素の例】 文章: “私は自然言語処理が好きです” 形態素に分割すると: ┌─────────────────────────────────────┐ │ 私 / は / 自然言語処理 / が / 好き / です │ └─────────────────────────────────────┘ 各形態素の情報: ・私 → 名詞(代名詞) ・は → 助詞(係助詞) ・自然言語処理 → 名詞(複合語) ・が → 助詞(格助詞) ・好き → 形容動詞の語幹 ・です → 助動詞

2-2. 形態素解析が行う4つのこと

✅ 形態素解析の機能
  1. 分かち書き:文を形態素(単語)に分割する
  2. 品詞タグ付け:各形態素の品詞を判定する
  3. 基本形取得:活用形を原形に戻す(「走った」→「走る」)
  4. 読み取得:漢字の読みを取得する
【形態素解析の具体例】 入力: “彼女は走った” 出力: ┌────────┬────────┬────────┬────────┐ │ 表層形 │ 品詞 │ 基本形 │ 読み │ ├────────┼────────┼────────┼────────┤ │ 彼女 │ 名詞 │ 彼女 │ カノジョ│ │ は │ 助詞 │ は │ ハ │ │ 走っ │ 動詞 │ 走る │ ハシッ │ │ た │ 助動詞 │ た │ タ │ └────────┴────────┴────────┴────────┘ ※「走った」が「走っ」+「た」に分解され、 基本形として「走る」が取得できる

2-3. 形態素解析の仕組み

形態素解析器は、辞書統計モデルを使って 最適な分割を見つけます。

【形態素解析の処理の流れ】 入力: “今日は晴れです” 【ステップ1】辞書から単語候補を探す 辞書に登録されている単語: – “今”、”日”、”今日”、”今日は” – “は” – “晴”、”晴れ” – “です” 考えられる分割パターン: パターンA: “今” / “日” / “は” / “晴れ” / “です” パターンB: “今日” / “は” / “晴れ” / “です” パターンC: “今日は” / “晴れ” / “です” 【ステップ2】統計モデルで最適な分割を選ぶ 各パターンの「もっともらしさ」をスコア計算 → パターンB が最も自然な分割と判定 結果: “今日” / “は” / “晴れ” / “です”
💡 補足:ビタビアルゴリズム

形態素解析では「ビタビアルゴリズム」という手法で、 最も確率の高い分割パターンを効率的に見つけます。 詳細は機械学習の授業で学びますので、ここでは 「辞書と統計で最適な分割を見つける」と理解しておけばOKです。

🐍 3. Janome(初心者におすすめ)

まずは最も使いやすいJanomeから学びましょう。 純Python実装なので、インストールが簡単です。

3-1. Janomeとは?

📦 Janomeの特徴
  • 純Python実装:外部ライブラリ不要
  • 簡単インストール:pip install janome だけ
  • クロスプラットフォーム:Windows/Mac/Linuxで同じように動く
  • 学習に最適:シンプルで分かりやすいAPI

3-2. Janomeのインストール

Google Colabまたはターミナルで以下を実行します。

# Janomeのインストール !pip install janome
実行結果: Collecting janome Downloading Janome-0.5.0-py3-none-any.whl (19.7 MB) Installing collected packages: janome Successfully installed janome-0.5.0

3-3. Janomeの基本的な使い方

ステップ1:Tokenizerをインポートして初期化

# Janomeのインポート from janome.tokenizer import Tokenizer # Tokenizerを作成 # ※初回は辞書の読み込みに少し時間がかかります t = Tokenizer() print(“Tokenizerの準備完了!”)
実行結果: Tokenizerの準備完了!

ステップ2:テキストを形態素解析

# 解析したいテキスト text = “私は自然言語処理が好きです” # tokenize()メソッドで形態素解析 # 戻り値はトークン(形態素)のイテレータ for token in t.tokenize(text): print(token)
実行結果: 私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ は 助詞,係助詞,*,*,*,*,は,ハ,ワ 自然 名詞,形容動詞語幹,*,*,*,*,自然,シゼン,シゼン 言語 名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ 処理 名詞,サ変接続,*,*,*,*,処理,ショリ,ショリ が 助詞,格助詞,一般,*,*,*,が,ガ,ガ 好き 名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
💡 出力の読み方

各行の形式は「表層形<タブ>品詞情報」です。 品詞情報はカンマ区切りで:

  • 品詞、品詞細分類1、品詞細分類2、品詞細分類3
  • 活用型、活用形
  • 基本形、読み、発音

3-4. 単語のリストだけを取得する

分かち書きだけが必要な場合は、wakati=Trueオプションを使います。

# wakati=True で分かち書きモード # 表層形(単語)だけがリストで返される text = “私は自然言語処理が好きです” words = t.tokenize(text, wakati=True) # リストに変換して表示 words_list = list(words) print(“分かち書き結果:”, words_list)
実行結果: 分かち書き結果: [‘私’, ‘は’, ‘自然’, ‘言語’, ‘処理’, ‘が’, ‘好き’, ‘です’]

3-5. 特定の品詞だけを抽出する

名詞だけ、動詞だけを抽出することも簡単にできます。 トークンオブジェクトの属性を使います。

トークンオブジェクトの主な属性

【tokenオブジェクトの属性】 token.surface → 表層形(実際の文字列) token.part_of_speech → 品詞情報(カンマ区切り) token.base_form → 基本形(原形) token.reading → 読み token.phonetic → 発音

名詞だけを抽出するコード

# 名詞だけを抽出する関数 def extract_nouns(text): “””テキストから名詞だけを抽出する””” t = Tokenizer() nouns = [] for token in t.tokenize(text): # part_of_speech は “名詞,一般,*,*” のような形式 # split(‘,’)[0] で最初の要素(大分類)を取得 pos = token.part_of_speech.split(‘,’)[0] if pos == ‘名詞’: nouns.append(token.surface) return nouns # テスト text = “東京で機械学習の勉強会に参加しました” nouns = extract_nouns(text) print(“抽出された名詞:”, nouns)
実行結果: 抽出された名詞: [‘東京’, ‘機械’, ‘学習’, ‘勉強’, ‘会’, ‘参加’]

動詞の基本形を抽出するコード

# 動詞を基本形で抽出する関数 def extract_verbs_base(text): “””テキストから動詞を基本形で抽出する””” t = Tokenizer() verbs = [] for token in t.tokenize(text): pos = token.part_of_speech.split(‘,’)[0] if pos == ‘動詞’: # base_form で基本形を取得 verbs.append(token.base_form) return verbs # テスト text = “朝起きて、ご飯を食べて、会社に行きました” verbs = extract_verbs_base(text) print(“動詞(基本形):”, verbs)
実行結果: 動詞(基本形): [‘起きる’, ‘食べる’, ‘行く’]

3-6. Janome完成コード

ここまでの内容をまとめた完成コードです。 ※コードが長いため、横スクロールできます。

# Janome完成コード:日本語テキスト処理 from janome.tokenizer import Tokenizer class JanomeProcessor: “””Janomeを使った日本語テキスト処理クラス””” def __init__(self): # Tokenizerを初期化(初回は辞書読み込みに時間がかかる) self.tokenizer = Tokenizer() def tokenize(self, text): “””分かち書き(単語リストを返す)””” return list(self.tokenizer.tokenize(text, wakati=True)) def tokenize_with_pos(self, text): “””品詞情報付きでトークン化””” result = [] for token in self.tokenizer.tokenize(text): result.append({ ‘surface’: token.surface, # 表層形 ‘pos’: token.part_of_speech, # 品詞 ‘base’: token.base_form, # 基本形 ‘reading’: token.reading # 読み }) return result def extract_by_pos(self, text, target_pos): “””指定した品詞の単語を抽出””” words = [] for token in self.tokenizer.tokenize(text): pos = token.part_of_speech.split(‘,’)[0] if pos in target_pos: words.append(token.surface) return words # 使用例 processor = JanomeProcessor() text = “私は東京で自然言語処理を勉強しています” print(“【分かち書き】”) print(processor.tokenize(text)) print(“\n【名詞抽出】”) print(processor.extract_by_pos(text, [‘名詞’])) print(“\n【動詞抽出】”) print(processor.extract_by_pos(text, [‘動詞’]))
実行結果: 【分かち書き】 [‘私’, ‘は’, ‘東京’, ‘で’, ‘自然’, ‘言語’, ‘処理’, ‘を’, ‘勉強’, ‘し’, ‘て’, ‘い’, ‘ます’] 【名詞抽出】 [‘私’, ‘東京’, ‘自然’, ‘言語’, ‘処理’, ‘勉強’] 【動詞抽出】 [‘し’, ‘て’, ‘い’]

⚙️ 4. MeCab(実務でのスタンダード)

MeCabは、日本語形態素解析のデファクトスタンダードです。 高速で精度が高く、多くの実務システムで使われています。

4-1. MeCabとは?

⚡ MeCabの特徴
  • 高速:C++で実装されており、非常に高速(Janomeの10倍以上)
  • 高精度:条件付き確率場(CRF)を使用した高精度な解析
  • 豊富な辞書:IPAdic、UniDic、NEologd等から選択可能
  • カスタマイズ可能:独自の辞書を追加できる

4-2. Google ColabでMeCabをインストール

Google ColabではMeCabとPythonバインディングをインストールします。

# MeCabのインストール(Google Colab用) !apt-get install -y mecab libmecab-dev mecab-ipadic-utf8 !pip install mecab-python3
実行結果: Reading package lists… Done Building dependency tree… Done …(省略)… Successfully installed mecab-python3-1.0.6
⚠️ インストール後の注意

インストール後、MeCabをインポートする前に ランタイムを再起動する必要がある場合があります。
メニューから「ランタイム」→「ランタイムを再起動」を選択してください。

4-3. MeCabの基本的な使い方

ステップ1:MeCabをインポートして初期化

# MeCabのインポート import MeCab # Taggerを作成(デフォルト設定) mecab = MeCab.Tagger() print(“MeCabの準備完了!”)
実行結果: MeCabの準備完了!

ステップ2:テキストを形態素解析

# 解析したいテキスト text = “私は自然言語処理が好きです” # parse()メソッドで形態素解析 # 結果は文字列として返される result = mecab.parse(text) print(result)
実行結果: 私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ は 助詞,係助詞,*,*,*,*,は,ハ,ワ 自然 名詞,形容動詞語幹,*,*,*,*,自然,シゼン,シゼン 言語 名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ 処理 名詞,サ変接続,*,*,*,*,処理,ショリ,ショリ が 助詞,格助詞,一般,*,*,*,が,ガ,ガ 好き 名詞,形容動詞語幹,*,*,*,*,好き,スキ,スキ です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス EOS

4-4. 分かち書きモード(-Owakati)

単語のリストだけが必要な場合は、分かち書きモードを使います。

# 分かち書きモードのTaggerを作成 # -Owakati オプションで分かち書き出力 mecab_wakati = MeCab.Tagger(‘-Owakati’) text = “私は自然言語処理が好きです” # 分かち書き結果を取得 result = mecab_wakati.parse(text) print(“分かち書き:”, result) # スペースで区切られた文字列なのでsplit()でリスト化 words = result.strip().split() print(“単語リスト:”, words)
実行結果: 分かち書き: 私 は 自然 言語 処理 が 好き です 単語リスト: [‘私’, ‘は’, ‘自然’, ‘言語’, ‘処理’, ‘が’, ‘好き’, ‘です’]

4-5. parseToNodeで詳細な情報を取得

parseToNode()を使うと、各形態素を ノードオブジェクトとして取得でき、詳細な情報にアクセスできます。

# parseToNode()で形態素ごとに処理 mecab = MeCab.Tagger() text = “私は自然言語処理が好きです” # parseToNode()はノードオブジェクトを返す node = mecab.parseToNode(text) print(“【形態素解析の詳細】”) while node: # surface: 表層形(実際の単語) # feature: 品詞情報(カンマ区切りの文字列) word = node.surface features = node.feature.split(‘,’) if word: # 空文字列(BOS/EOS)を除外 pos = features[0] # 品詞(最初の要素) print(f”単語: {word:10} 品詞: {pos}”) node = node.next # 次のノードへ
実行結果: 【形態素解析の詳細】 単語: 私 品詞: 名詞 単語: は 品詞: 助詞 単語: 自然 品詞: 名詞 単語: 言語 品詞: 名詞 単語: 処理 品詞: 名詞 単語: が 品詞: 助詞 単語: 好き 品詞: 名詞 単語: です 品詞: 助動詞

4-6. 名詞だけを抽出する関数

# MeCabで名詞を抽出する関数 def extract_nouns_mecab(text): “””MeCabを使って名詞だけを抽出する””” mecab = MeCab.Tagger() node = mecab.parseToNode(text) nouns = [] while node: features = node.feature.split(‘,’) # 品詞が「名詞」の場合 if features[0] == ‘名詞’: nouns.append(node.surface) node = node.next return nouns # テスト text = “東京スカイツリーは東京都墨田区にあります” nouns = extract_nouns_mecab(text) print(“抽出された名詞:”, nouns)
実行結果: 抽出された名詞: [‘東京’, ‘スカイツリー’, ‘東京’, ‘都’, ‘墨田’, ‘区’]

4-7. MeCabの辞書について

📚 主要な辞書の種類

MeCabは複数の辞書に対応しています。目的に応じて選択します。

辞書名 特徴 用途
IPAdic 標準辞書、バランスが良い 一般的な用途
UniDic 学術研究向け、詳細な品詞情報 研究・分析
NEologd 固有名詞・新語に強い、定期更新 SNS・Web分析
【辞書による違いの例】 テキスト: “ビートルズのレット・イット・ビーが好きです” ■ IPAdic(標準辞書) “ビートルズ” → “ビート” + “ルズ” に分割される可能性 ■ NEologd(新語辞書) “ビートルズ” → “ビートルズ” として1単語で認識 “レット・イット・ビー” → “レット・イット・ビー” として認識 → 固有名詞が重要な場合はNEologdがおすすめ

🆕 5. SudachiPy(最新の形態素解析器)

SudachiPyは、ワークスアプリケーションズが開発した 最新の形態素解析器です。複数の分割単位に対応しているのが特徴です。

5-1. SudachiPyの特徴

✨ SudachiPyの特徴
  • 3つの分割モード:短単位・中単位・長単位を選択可能
  • 正規化機能:表記ゆれを自動的に統一
  • 同義語辞書:「パソコン」「PC」を同一視できる
  • 純Python:インストールが簡単

5-2. SudachiPyのインストール

# SudachiPyのインストール !pip install sudachipy sudachidict_core
実行結果: Collecting sudachipy …(省略)… Successfully installed sudachipy-0.6.7 sudachidict_core-20230927

5-3. SudachiPyの基本的な使い方

# SudachiPyのインポート from sudachipy import tokenizer from sudachipy import dictionary # Tokenizerを作成 tokenizer_obj = dictionary.Dictionary().create() # 解析したいテキスト text = “自然言語処理を勉強しています” # モードA(短単位)でトークン化 mode = tokenizer.Tokenizer.SplitMode.A tokens = tokenizer_obj.tokenize(text, mode) print(“【形態素解析結果】”) for token in tokens: print(f”表層形: {token.surface()}, 品詞: {token.part_of_speech()[0]}”)
実行結果: 【形態素解析結果】 表層形: 自然, 品詞: 名詞 表層形: 言語, 品詞: 名詞 表層形: 処理, 品詞: 名詞 表層形: を, 品詞: 助詞 表層形: 勉強, 品詞: 名詞 表層形: し, 品詞: 動詞 表層形: て, 品詞: 助詞 表層形: い, 品詞: 動詞 表層形: ます, 品詞: 助動詞

5-4. 3つの分割モードの違い

SudachiPyの最大の特徴は、3つの分割粒度を選べることです。

# 3つの分割モードを比較 from sudachipy import tokenizer from sudachipy import dictionary tokenizer_obj = dictionary.Dictionary().create() text = “自然言語処理を勉強しています” # 3つのモードを定義 modes = { ‘A(短単位)’: tokenizer.Tokenizer.SplitMode.A, ‘B(中単位)’: tokenizer.Tokenizer.SplitMode.B, ‘C(長単位)’: tokenizer.Tokenizer.SplitMode.C } for mode_name, mode in modes.items(): tokens = tokenizer_obj.tokenize(text, mode) words = [token.surface() for token in tokens] print(f”{mode_name}: {words}”)
実行結果: A(短単位): [‘自然’, ‘言語’, ‘処理’, ‘を’, ‘勉強’, ‘し’, ‘て’, ‘い’, ‘ます’] B(中単位): [‘自然’, ‘言語’, ‘処理’, ‘を’, ‘勉強’, ‘し’, ‘て’, ‘い’, ‘ます’] C(長単位): [‘自然言語処理’, ‘を’, ‘勉強’, ‘し’, ‘て’, ‘いる’]
💡 分割モードの使い分け
  • モードA(短単位):細かい分析、テキスト分類向け
  • モードB(中単位):一般的な用途
  • モードC(長単位):複合語を保持したい場合、情報検索向け

5-5. 正規化機能(表記ゆれの統一)

SudachiPyはnormalized_form()で表記ゆれを統一できます。

# 正規化機能のデモ from sudachipy import tokenizer from sudachipy import dictionary tokenizer_obj = dictionary.Dictionary().create() mode = tokenizer.Tokenizer.SplitMode.C # 表記ゆれがあるテキスト texts = [“パソコン”, “コンピュータ”, “コンピューター”] print(“【表記ゆれの正規化】”) for text in texts: tokens = tokenizer_obj.tokenize(text, mode) for token in tokens: print(f”入力: {token.surface():15} → 正規化: {token.normalized_form()}”)
実行結果: 【表記ゆれの正規化】 入力: パソコン → 正規化: パーソナルコンピュータ 入力: コンピュータ → 正規化: コンピュータ 入力: コンピューター → 正規化: コンピュータ
💡 正規化の利点

「パソコン」「コンピュータ」「コンピューター」のように 同じ意味で異なる表記の単語を統一できます。 テキスト検索や分析の精度向上に役立ちます。

📊 6. 形態素解析器の比較と選択

6-1. 3つの形態素解析器の比較

項目 Janome MeCab SudachiPy
速度 やや遅い 非常に高速 中程度
インストール ◎ 簡単 △ やや複雑 ○ 簡単
辞書 標準のみ 豊富 3サイズ
正規化 なし なし ◎ あり
分割モード 1種類 1種類 3種類
推奨用途 学習・実験 本番システム 高度な分析

6-2. 用途別おすすめ

💡 形態素解析器の選び方

🎓 学習・プロトタイピング:

Janome(インストール簡単、すぐ使える)

🚀 本番システム・大量データ:

MeCab + NEologd(高速・高精度・新語対応)

🔧 表記ゆれ対応・複合語処理:

SudachiPy(正規化機能・分割モード選択)

🛠️ 7. 実装:日本語テキスト前処理パイプライン

これまで学んだ内容を組み合わせて、実用的な前処理パイプラインを作成します。

7-1. Janomeを使った前処理パイプライン

# Janomeを使った日本語前処理パイプライン import re from janome.tokenizer import Tokenizer class JapanesePreprocessor: “””日本語テキストの前処理クラス””” def __init__(self): self.tokenizer = Tokenizer() def clean_text(self, text): “””テキストクリーニング””” # URL除去 text = re.sub(r’https?://[\w/:%#\$&\?\(\)~\.=\+\-]+’, ”, text) # メールアドレス除去 text = re.sub(r’\S+@\S+’, ”, text) # 改行を空白に text = text.replace(‘\n’, ‘ ‘) # 連続する空白を1つに text = re.sub(r’\s+’, ‘ ‘, text) return text.strip() def tokenize(self, text, pos_filter=None): “”” トークン化 引数: text: 入力テキスト pos_filter: 抽出する品詞のリスト(例: [‘名詞’, ‘動詞’]) Noneの場合は全ての品詞を返す “”” tokens = [] for token in self.tokenizer.tokenize(text): pos = token.part_of_speech.split(‘,’)[0] if pos_filter is None or pos in pos_filter: tokens.append(token.surface) return tokens def preprocess(self, text, pos_filter=None): “””完全な前処理パイプライン””” # 1. クリーニング text = self.clean_text(text) # 2. トークン化 tokens = self.tokenize(text, pos_filter) return tokens # 使用例 preprocessor = JapanesePreprocessor() text = “”” 自然言語処理(NLP)は、人工知能の一分野です。 詳しくはhttps://example.com をご覧ください。 機械学習や深層学習の技術が使われています。 “”” # 全ての単語を取得 all_tokens = preprocessor.preprocess(text) print(“【全ての単語】”) print(all_tokens) # 名詞だけを取得 noun_tokens = preprocessor.preprocess(text, pos_filter=[‘名詞’]) print(“\n【名詞のみ】”) print(noun_tokens)
実行結果: 【全ての単語】 [‘自然’, ‘言語’, ‘処理’, ‘(’, ‘NLP’, ‘)’, ‘は’, ‘、’, ‘人工’, ‘知能’, ‘の’, ‘一’, ‘分野’, ‘です’, ‘。’, ‘詳しく’, ‘は’, ‘を’, ‘ご覧’, ‘ください’, ‘。’, ‘機械’, ‘学習’, ‘や’, ‘深’, ‘層’, ‘学習’, ‘の’, ‘技術’, ‘が’, ‘使わ’, ‘れ’, ‘て’, ‘い’, ‘ます’, ‘。’] 【名詞のみ】 [‘自然’, ‘言語’, ‘処理’, ‘NLP’, ‘人工’, ‘知能’, ‘一’, ‘分野’, ‘機械’, ‘学習’, ‘深’, ‘層’, ‘学習’, ‘技術’]

7-2. TF-IDFと組み合わせてテキスト分類

# 日本語テキスト分類の例 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from janome.tokenizer import Tokenizer # 日本語用トークナイザー関数 def tokenize_japanese(text): “””Janomeで分かち書き””” t = Tokenizer() tokens = t.tokenize(text, wakati=True) return ‘ ‘.join(tokens) # スペース区切りの文字列に # サンプルデータ documents = [ “機械学習は人工知能の一分野です”, “深層学習はニューラルネットワークを使います”, “自然言語処理はテキストを扱う技術です”, “画像認識は畳み込みニューラルネットワークを使います”, “音声認識は音声データを処理します” ] labels = [0, 0, 1, 2, 2] # 0=機械学習, 1=NLP, 2=その他 # 日本語をトークン化してからベクトル化 tokenized_docs = [tokenize_japanese(doc) for doc in documents] # TF-IDFベクトル化 vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(tokenized_docs) # モデル訓練 model = MultinomialNB() model.fit(X, labels) # 新しい文書で予測 new_doc = “自然言語処理の研究をしています” new_tokenized = tokenize_japanese(new_doc) new_vec = vectorizer.transform([new_tokenized]) prediction = model.predict(new_vec) print(f”入力: {new_doc}”) print(f”予測カテゴリ: {prediction[0]}”) # 1 = NLP
実行結果: 入力: 自然言語処理の研究をしています 予測カテゴリ: 1

📝 練習問題

このステップで学んだ内容を確認しましょう。

問題1:日本語の特徴

日本語のテキスト処理において、英語と比べて最も大きな課題は何ですか?

  1. 文字の種類が多い(ひらがな、カタカナ、漢字)
  2. 単語の区切りがない(分かち書きがない)
  3. 漢字の読み方が複数ある
  4. 敬語が複雑
正解:b

日本語の最大の課題は「分かち書きがない」ことです。

比較:

  • 英語: “I love NLP” → スペースで区切られている → split()で簡単に分割
  • 日本語: “私は自然言語処理が好きです” → 区切りがない → どこで分割すべきか不明

この問題を解決するために形態素解析が必要です。 a, c, d も課題ですが、最も根本的な問題は b です。

問題2:形態素解析

形態素解析が行うこととして、正しくないものはどれですか?

  1. 文を形態素(最小の意味単位)に分割する
  2. 各単語の品詞を判定する
  3. 活用形を基本形に戻す
  4. 文章の意味を理解して要約する
正解:d

形態素解析は文法的な解析を行うものであり、 文章の意味理解や要約は行いません。

形態素解析が行うこと:

  • ✅ a. 形態素への分割(「走った」→「走っ」+「た」)
  • ✅ b. 品詞タグ付け(名詞、動詞、形容詞等)
  • ✅ c. 基本形取得(「走った」→「走る」)
  • ❌ d. 意味理解や要約(これは別のタスク)

意味理解には、Word2VecやBERTなどのより高度な技術が必要です。

問題3:形態素解析器の比較

次のうち、インストールが最も簡単な形態素解析器はどれですか?

  1. MeCab
  2. Janome
  3. SudachiPy
  4. b と c(同じくらい簡単)
正解:d

Janome と SudachiPy純Python実装なので、 インストールが非常に簡単です。

  • Janome: pip install janome だけでOK
  • SudachiPy: pip install sudachipy sudachidict_core でOK
  • MeCab: C++の外部ライブラリが必要、OSごとにインストール方法が異なる

ただし、MeCabは速度と精度で優れているため、 本番環境では依然として人気があります。

問題4:SudachiPyの特徴

SudachiPyの最大の特徴は何ですか?

  1. 最も処理速度が速い
  2. 3つの分割単位(短単位・中単位・長単位)に対応
  3. 辞書の種類が最も豊富
  4. 最も古くから使われている
正解:b

SudachiPyの最大の特徴は、3つの分割モードです。

  • モードA(短単位):“自然言語処理” → [“自然”, “言語”, “処理”]
  • モードB(中単位):“自然言語処理” → [“自然”, “言語”, “処理”]
  • モードC(長単位):“自然言語処理” → [“自然言語処理”]

タスクに応じて分割粒度を選べるのが強みです。

他の選択肢について:

  • a. 速度は MeCab が最速
  • c. 辞書の豊富さは MeCab(NEologd等)
  • d. 最も古いのは MeCab(2001年〜)

📝 STEP 4 のまとめ

✅ このステップで学んだこと
  • 日本語の特徴:分かち書きがない、表記が多様、単語の曖昧性
  • 形態素解析:文を形態素に分割し、品詞や基本形を取得
  • Janome:純Python、インストール簡単、学習向け
  • MeCab:高速・高精度、本番システム向け
  • SudachiPy:3つの分割モード、正規化機能
  • 実装:日本語テキスト前処理パイプライン
💡 重要ポイント

日本語NLPでは形態素解析が必須です。 英語のように split() で簡単に分割できないため、 専用のツールを使う必要があります。

目的に応じて適切なツールを選びましょう:

  • 学習・実験 → Janome
  • 本番・大量データ → MeCab
  • 高度な分析 → SudachiPy
🎯 次のステップの準備

次のSTEP 5では、Word2Vecの理論と実装を学びます。

Bag of WordsやTF-IDFとは異なり、単語の意味を捉える 分散表現の世界に入っていきましょう! 「king – man + woman = queen」のような単語演算が可能になります。

📝

学習メモ

自然言語処理(NLP) - Step 4

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE