読み込み中...

Pythonで形態素解析するプログラミング方法10選

Pythonと形態素解析の基本を学ぶ初心者のための図解説明 Python
この記事は約22分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Pythonで日本語の文章を扱うなら、形態素解析を使って文章を単語に近い単位へ分割する流れを押さえる必要があります。形態素解析は、検索、要約、分類、感情分析、テキスト分析などの前処理として使われ、NLPや自然言語処理を学ぶ初心者にも入り口になりやすい領域です。

その処理をPythonで進める場合、代表的なライブラリとしてMeCabJanomeがあります。MeCabは高速な解析エンジンとして使われ、JANOMEはPythonだけで扱いやすい構成になっているため、プログラミング環境や目的に合わせて選ぶのが現実的だと言えますし、ここがポイントです。

この記事の流れは、環境設定、基本的な形態素解析、頻度分析、感情分析、テキストクラスタリング、トラブル対応、辞書カスタマイズまでを一続きで扱いるのが基本です。そのため、Pythonプログラミングで日本語テキストを処理したい初心者でも、コードの役割と応用先を結び付けて理解しやすくなります。

動作確認環境
  • Python 3.12系
  • mecab-python3 1.0系 / unidic-lite 1.0系 / Janome 0.5系
  • scikit-learn 1.5系
  • Windows 11 / macOS 14 / Ubuntu 22.04相当のPython実行環境
📖 この記事で学べること
  • Pythonで形態素解析を始めるための環境設定
  • MeCabとJANOMEの違いと基本コード
  • 形態素解析を使った頻度分析とテキスト分析
  • NLPや自然言語処理で使う感情分析とクラスタリング
  • 辞書エラー、文字コード、ユーザー辞書の扱い方

公式ドキュメントによれば、Pythonの仮想環境は標準ライブラリのvenvで作成できます。詳細はPython公式ドキュメントのvenv、JANOMEの使い方はJanome公式ドキュメント、scikit-learnのTF-IDFはTfidfVectorizer公式ドキュメントを参照すると仕様を確認できます。

Pythonの環境設定

結論として、形態素解析の学習は仮想環境を作り、pipで必要なライブラリを入れる形から始めるのが扱いやすい構成です。Python本体、辞書、解析ライブラリ、機械学習ライブラリを分けて管理すると、プログラミング中の依存関係トラブルを切り分けやすくなるのが基本です。

python -m venv .venv
.venvScriptsactivate
python -m pip install --upgrade pip
pip install mecab-python3 unidic-lite janome scikit-learn

結果: 期待される状態は、.venvが作成され、mecab-python3unidic-litejanomescikit-learnをPythonから読み込める状態です。

これでMeCab.TaggerTokenizerCounterTfidfVectorizerKMeansを使う土台が整います。Windowsでは.venvScriptsactivate、macOSやLinuxではsource .venv/bin/activateを使うという違いがあるため、OSに合わせて読み替えます。

その環境で初心者がつまずきやすいのは、pipをシステム側のPythonへ入れてしまう点です。python -m pipの形で実行すると、現在有効なPython環境に対してパッケージを入れられるため、自然言語処理のライブラリ管理が安定するのが目安です。

Python本体の導入後は、Python初心者のための完全ガイド!アプリ化の10ステップで環境構築やアプリ化の考え方も確認できるのが目安です。形態素解析だけでなく、処理結果をアプリに組み込む流れまで見通したい場合に役立つ内部リンクです。

💡 Tips: pip install janomeだけでもJANOMEは動かせます。一方、MeCabは辞書が必要になるため、初心者はunidic-liteを同時に入れておくと導入時の失敗を減らせますが、これは押さえたい点です。
項目主な役割使うコード確認点関連する用途
Python実行環境python --version3.10以上を目安にする全体
仮想環境依存関係の分離python -m venv .venvプロジェクトごとに作る環境設定
pipパッケージ導入python -m pip install有効な環境を確認するライブラリ管理
MeCab高速な形態素解析MeCab.Tagger()辞書の有無を見る日本語解析
mecab-python3Pythonバインディングimport MeCabPythonからMeCabを呼ぶNLP
unidic-lite軽量辞書pip install unidic-lite初学者向けに扱いやすい辞書設定
JanomePython製解析器Tokenizer()外部エンジンなしで動く初心者学習
JANOME表記ゆれ対策janome.tokenizer記事や資料で大文字表記も見る検索補助
表層形文章中の見た目token.surface単語の表示形を取る頻度分析
品詞単語の分類token.part_of_speech名詞や動詞を分ける抽出条件
原形辞書上の形base_form活用語をまとめる正規化
読み読み仮名reading検索補助に使う辞書拡張
発音発音情報phonetic音声処理と関係する音声NLP
parse解析実行mecab.parse(text)文字列を渡すMeCab基本
parseToNodeノード取得parseToNode()単語単位で走査する詳細処理
splitlines行分割splitlines()EOS行に注意する出力整形
tokenizeトークン化t.tokenize(text)生成されるTokenを扱うJanome基本
Counter出現回数Counter()名詞だけに絞ると読みやすいテキスト分析
most_common上位語取得most_common(10)助詞を除外する頻度分析
TF-IDF特徴量化TfidfVectorizer文書間の特徴語を見る分類
KMeansクラスタリングKMeans()クラスタ数を決める分類補助
labels_分類ラベルkmeans.labels_文書ごとの所属を見るクラスタ確認
stop_words除外語stop_words頻出しすぎる語を外す品質改善
ユーザー辞書専門語登録-u user.dic固有名詞をまとめるカスタマイズ
文字コード文字の解釈encoding="utf-8"読み込みエラーを防ぐ障害対応
CSV辞書データuserdic.csv列順を守る辞書作成
UnicodeDecodeError文字コード例外errors="ignore"元データを確認するトラブル対応
ModuleNotFoundError未導入例外pip show janome仮想環境を見直す導入確認
random_state乱数固定random_state=0結果の揺れを抑えるクラスタリング
n_initKMeans初期化n_init="auto"現行APIに合わせる機械学習

形態素解析の基本:MeCabの使い方

MeCabをPythonから使うと、文章を形態素へ分け、表層形や品詞などの情報を取り出せます。自然言語処理では、文章をそのまま扱うより、語に分けたうえで数えたり絞り込んだりするほうが処理を設計しやすくなります。

その最小例はimport MeCabで読み込み、MeCab.Tagger()を作成し、parse()へ文字列を渡す形です。mecab-python3unidic-liteが入っていれば、初心者でも短いPythonプログラミングで結果を確認できるのがポイントです。

MeCabで文章を解析する

import MeCab

mecab = MeCab.Tagger()
text = "Pythonで形態素解析を学ぶ"
result = mecab.parse(text)
print(result)

結果: 期待される出力は、Python形態素解析学ぶのような行と品詞情報が並ぶ形式です。辞書により分割や品詞名は変わる可能性があります。

この出力は人が読むには十分でも、プログラムで集計するには少し扱いにくい形式です。そのため、splitlines()で行に分け、split("t")で表層形と詳細情報を分けると、後続のテキスト分析へ接続しやすくなります。

import MeCab

mecab = MeCab.Tagger()
text = "Pythonで形態素解析を学ぶ"
result = mecab.parse(text)

for line in result.splitlines():
    if line == "EOS" or "t" not in line:
        continue
    surface, feature = line.split("t", 1)
    print(surface, feature)

結果: 期待される出力は、各行の先頭に表層形、後ろに品詞や読みなどの情報が並ぶ形です。EOSを除外しているため、単語情報だけを取り出せますし、これが一つの目安です。

ただし、line.split("t")だけで書くと、想定外の行に出会ったときにValueErrorが発生する場合があります。このときはif "t" not in lineのような条件を置き、解析結果を安全に処理する書き方へ寄せると安定します。

MeCabの出力を保存してグラフ化したい場合は、Pythonで折れ線グラフ作成の完全ガイド10選のような可視化記事も組み合わせられますが、覚えておくと役立つでしょう。頻度の推移や文書ごとの差を見たいとき、形態素解析とグラフ化は相性がよい組み合わせです。

形態素解析の基本:Janomeの使い方

JanomeはPythonで実装された形態素解析ライブラリで、外部のMeCab本体を別途用意せずに使える点が特徴です。JANOMEは環境差の影響を受けにくいため、初心者が自然言語処理の流れを学ぶ用途に向いています。

その使い方は、janome.tokenizerからTokenizerを読み込み、tokenize()へ文章を渡すだけです。返されるTokenにはsurfacepart_of_speechが含まれ、Pythonのオブジェクトとして扱えます。

Janomeでトークンを取り出す

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
text = "Pythonで形態素解析を学ぶ"

for token in tokenizer.tokenize(text):
    print(token.surface, token.part_of_speech)

結果: 期待される出力は、Python 名詞,...で 助詞,...形態素解析 名詞,...のように、表層形と品詞情報が並ぶ形式です。辞書やバージョンにより細部は変わります。

これにより、名詞だけを集める、助詞を除外する、原形でそろえるといった加工がしやすくなります。テキスト分析では、すべての語を同じ重みで扱うより、目的に合う品詞へ絞ったほうが結果を読み取りやすい場合があるのが一般的です。

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
text = "Pythonで形態素解析を学ぶ。自然言語処理にも使う。"

nouns = []
for token in tokenizer.tokenize(text):
    pos = token.part_of_speech.split(",")[0]
    if pos == "名詞":
        nouns.append(token.surface)

print(nouns)

結果: 期待される出力は、['Python', '形態素解析', '自然言語処理']に近い名詞リストです。JANOMEの辞書判断により、複合語の切れ方は変わることがあります。

一方、Janomeは導入しやすい反面、大量データの高速処理ではMeCabを検討する場面もあります。少量の文章や学習用コードではJANOME、処理速度や辞書運用を重視する場合はMeCabという使い分けが一般的だと言えるでしょう。

ℹ️ 補足: MeCabとJANOMEのどちらを選んでも、最終的な目的は文章を処理しやすい単位へ変えることです。ライブラリ選定は、速度、導入しやすさ、辞書カスタマイズ、運用環境を見て決めますし、ここを基本と考えるとよいでしょう。

形態素解析の応用:頻度分析

頻度分析は、形態素解析で分けた語が文章中に何回出るかを数える処理です。テキスト分析の入り口として使いやすく、商品レビュー、問い合わせ文、アンケート、記事本文などから話題の中心を探るときに役立ちます。

その処理では、collections.Counterを使うと短いコードで単語の出現回数を集計できます。ただし、助詞や記号まで数えると結果が読みづらくなるため、名詞や動詞など必要な品詞へ絞る設計が有効です。

Counterで単語の出現回数を数える

from collections import Counter
from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
text = "Pythonで形態素解析を学ぶ。Pythonで自然言語処理を学ぶ。形態素解析はテキスト分析に使う。"

words = []
for token in tokenizer.tokenize(text):
    pos = token.part_of_speech.split(",")[0]
    if pos == "名詞":
        words.append(token.surface)

count = Counter(words)
print(count.most_common(5))

結果: 期待される出力は、[('Python', 2), ('形態素解析', 2), ...]のように、名詞と出現回数が多い順に並ぶ形式です。

この集計では、token.part_of_speechから品詞の先頭要素を取り出し、名詞だけをwordsへ追加しています。こうした前処理を入れると、NLPの初期分析でありがちな「助詞ばかりが上位に出る」状態を避けやすくなります。

実際、頻度分析だけでも文章の傾向はかなり見えるのが現実的です。たとえば、問い合わせ文でエラーログインパスワードが多ければ認証周りに問題が集中している可能性があり、自然言語処理の前段として十分な手がかりになるのがポイントです。

その結果を表形式で扱いたい場合は、初心者必見!Pythonで表を操作するための7つの詳細ガイドも参照できます。単語、回数、品詞、文書IDを表にまとめると、分析結果を後から再利用しやすくなると整理できます。

形態素解析の応用:感情分析

感情分析は、文章に含まれる語からポジティブまたはネガティブな傾向を推定する処理です。形態素解析で単語へ分け、各語にスコアを与え、文全体の傾向を計算する流れがよく使われますし、ここがポイントです。

ただし、感情分析は文脈の影響を強く受けます。たとえば「軽い」は商品によって肯定的にも否定的にもなり得るため、初心者は辞書ベースの単純な合計を出発点にし、後から文脈や対象領域に合わせて調整すると理解しやすいでしょう。

辞書ベースで感情スコアを計算する

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
sentiment_words = {
    "良い": 1,
    "好き": 1,
    "快適": 1,
    "悪い": -1,
    "不満": -1,
    "遅い": -1,
}

text = "このアプリは快適で好きですが、起動が遅いです"
score = 0
matched = []

for token in tokenizer.tokenize(text):
    surface = token.surface
    if surface in sentiment_words:
        score += sentiment_words[surface]
        matched.append(surface)

print(score, matched)

結果: 期待される出力は、感情スコアと一致した単語のリストです。例では快適好き遅いが辞書に一致し、合計スコアが計算されます。

このコードは外部の感情分析ライブラリに依存しないため、仕組みを理解する用途に向いています。一方、実務寄りのNLPでは、語の否定、係り受け、皮肉、対象語の違いなども影響するため、辞書だけで断定しない姿勢が必要です。

そのため、感情分析の結果は「文章全体の確定評価」ではなく「分類や確認の候補」として扱うのが自然です。自然言語処理のプログラミングでは、機械的なスコアと人による確認を組み合わせる設計がよく採られますし、ここがポイントです。

⚠️ 注意: 感情スコアは辞書や学習データに強く左右されますが、これは押さえたい点です。コードの出力を実際の顧客感情や世論の結論として扱う場合は、評価データ、誤分類例、対象領域の語彙を確認する必要があります。

形態素解析の応用:テキストクラスタリング

テキストクラスタリングは、文章同士の似ている度合いを使ってグループ分けする処理です。形態素解析で単語へ分け、TF-IDFで数値ベクトルに変換し、KMeansなどのアルゴリズムで分類すると理解できます。

その流れでは、形態素解析が「文章を語へ分ける役割」、TfidfVectorizerが「語を数値へ変える役割」、KMeansが「近い文書を同じグループへ寄せる役割」を持ちますし、これが一つの目安です。NLPの全体像を理解するうえで、各処理の責任を分けて捉えると整理しやすいです。

TF-IDFとKMeansで文章を分ける

from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans

tokenizer = Tokenizer()

def tokenize(text):
    return [token.surface for token in tokenizer.tokenize(text)]

texts = [
    "りんごが好きです",
    "みかんが好きです",
    "犬と散歩します",
    "猫と遊びます",
]

vectorizer = TfidfVectorizer(tokenizer=tokenize, token_pattern=None)
X = vectorizer.fit_transform(texts)

kmeans = KMeans(n_clusters=2, random_state=0, n_init="auto")
labels = kmeans.fit_predict(X)

print(labels)

結果: 期待される出力は、[0 0 1 1]またはラベル番号が入れ替わった配列です。クラスタ番号自体に意味はなく、同じ番号の文が同じグループに入ったことを表します。

このコードではtoken_pattern=Noneを入れ、scikit-learn側の標準トークン規則よりJanomeのtokenize関数を優先しています。日本語では空白区切りが前提にならないため、独自の形態素解析関数を渡す設計が扱いやすくなると覚えるとよいでしょう。

ただし、短い例文では結果が直感と一致しても、文章数が増えるとクラスタの解釈は難しくなるのが一般的です。その場合は、各クラスタで出現頻度の高い語を見たり、代表文を確認したりして、分類名を後から付ける方法が現実的です。

テキストクラスタリングの結果をGUI操作や自動処理へつなげたい場合は、Pythonで実現!ウィンドウ操作の自動化15選も関連します。分類結果をファイル保存し、集計や確認作業を半自動化する構成も考えられますが、これは押さえたい点です。

形態素解析のトラブルシューティング

形態素解析で発生するエラーは、主にライブラリ未導入、辞書不足、文字コード、バージョン差、入力データの形式に分けられます。エラーメッセージを読むときは、例外名、発生したファイル、該当行、直前の処理を順番に確認するのが現実的です。

その代表例がModuleNotFoundErrorです。これはjanomeMeCabが現在のPython環境に入っていないときに出やすく、仮想環境を有効化してからpip showで導入状況を見ると切り分けられますし、これが一つの目安です。

python -m pip show janome
python -m pip show mecab-python3
python -m pip show unidic-lite

結果: 期待される出力は、各パッケージのNameVersionLocationなどの情報です。何も出ない場合は、その環境にパッケージが入っていません。

一方、UnicodeDecodeErrorはファイル読み込み時の文字コード不一致で発生します。日本語テキストではutf-8cp932shift_jisが混在することがあるため、元ファイルの保存形式を確認してからopen()encodingを決めます。

from pathlib import Path

path = Path("reviews.txt")
text = path.read_text(encoding="utf-8")
print(text[:50])

結果: 期待される出力は、reviews.txtの先頭50文字です。文字コードが合わない場合は例外が発生するため、encoding="cp932"など別の候補を検討すると考えられますが、覚えておくと役立つでしょう。

MeCabで辞書関連のエラーが出る場合は、unidic-liteが導入されているか、MeCab.Tagger()が辞書を見つけられるかを確認します。辞書の場所を明示する運用もありますが、初心者は軽量辞書を入れて最小構成から始めると原因を絞りやすくなります。

⚠️ 注意: Web上の古いコードには、現在のライブラリでは警告やエラーになる書き方が混じることがあると言えるでしょう。scikit-learnのKMeansではn_initを明示するなど、使用中のバージョンに合わせた引数を確認してください。

形態素解析のカスタマイズ方法

形態素解析の精度を用途に合わせるには、ユーザー辞書、除外語、品詞フィルタ、正規化を調整すると整理できます。特に固有名詞、製品名、サービス名、技術用語は標準辞書だけでは望む単位に分かれないことがあり、テキスト分析の結果にも影響します。

そのため、専門語を扱うプログラミングでは、辞書に登録する語と、集計時に除外する語を分けて考えますが、覚えておくと役立つでしょう。たとえばPython自然言語処理テキスト分析MeCabJANOMEなどをひとまとまりで扱いたい場面があります。

Janomeでユーザー辞書を読み込む

Janomeでは、CSV形式のユーザー辞書をTokenizerへ渡す構成が使えると理解できます。IPADIC形式の列を用意する必要があるため、短い確認用データで読み込みを試してから本番の辞書を増やす流れが扱いやすいです。

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer("userdic.csv", udic_type="ipadic", udic_enc="utf8")
text = "JapanシーモアでPython形態素解析を学ぶ"

for token in tokenizer.tokenize(text):
    print(token.surface, token.part_of_speech)

結果: 期待される出力は、userdic.csvに登録した語が意図した単位で表示される形式です。CSVの列数や文字コードが合わない場合は読み込みエラーになります。

MeCabでもユーザー辞書を使えますが、CSVをそのまま渡すのではなく、辞書コンパイルを経て.dicファイルとして指定する構成が一般的です。記事やサンプルで-u userdic.csvのような書き方を見かけた場合は、辞書形式が実際にMeCabで読める状態か確認します。

import MeCab

userdic = "/path/to/user.dic"
tagger = MeCab.Tagger(f"-u {userdic}")
print(tagger.parse("Pythonで形態素解析を学ぶ"))

結果: 期待される出力は、ユーザー辞書に登録した語が反映されたMeCabの解析結果です。/path/to/user.dicは実際の辞書ファイルのパスへ置き換えますし、ここを基本と考えるとよいでしょう。

これらのカスタマイズは、検索エンジン、FAQ分類、レビュー分析、問い合わせ分類などで効果を発揮すると覚えるとよいでしょう。改行を含むテキストを整形してから解析したい場合は、Pythonで改行あり・なしを制御する方法と応用例10選も関連します。

まとめ

Pythonで形態素解析を進める軸は、環境を分ける、MeCabまたはJanomeで単語へ分ける、目的に応じて集計や分類へつなげる、という流れです。MeCabは速度や辞書運用を重視する場面、JANOMEは導入しやすさやPythonだけで完結する学習用途に向いているのが基本です。

そのうえで、頻度分析ではCounter、感情分析では感情辞書、テキストクラスタリングではTfidfVectorizerKMeansを組み合わせます。これらは自然言語処理やNLPの実装でよく使われる考え方であり、初心者がテキスト分析の全体像をつかむ助けになると考えられます。

ただし、解析結果は辞書、文字コード、品詞体系、ライブラリのバージョンによって変わりますし、ここがポイントです。そのため、Pythonプログラミングで日本語を扱うときは、期待される出力を固定的に覚えるより、入力、辞書、前処理、評価方法を順番に確認する姿勢が欠かせません。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。