TECHNICAL BLOG

2025/2/10 Janomeを用いた形態素解析

はじめに

こんにちは、橋渡です。
今回は、自然言語処理の基礎となる形態素解析について、Janomeを用いて実装したいと思います。

全体の流れ

1.形態素解析とは
2.実施すること
3.Janomeによる形態素解析

1.形態素解析とは

形態素解析とは、文章を構成している単語を最小単位に分解して、その結果について、品詞や活用形などの情報を求めることをいいます。
この分解された単語の最小単位を形態素といいます。
例えば、「今日はいい天気だ。しっかり運動しよう。」という文章は、以下のように分解されます。

2.実施すること

形態素解析ライブラリであるJanomeを用いて弊社ブログの内容を解析し、可視化します。
Janomeは、Pythonで使用できる日本語の形態素解析ライブラリです。
インストールが容易ですぐに利用できるのも魅力です。
日本語の文章を形態素に分解し、品詞や活用形などの情報を得ることができます。
初めに、Janomeの使用方法と得られる情報について確認します。

!pip install japanize-matplotlib

import re
import collections
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import seaborn as sns
from janome.tokenizer import Tokenizer
from typing import List, Tuple
# Tokenizerクラスをインスタンス化
tokenizer = Tokenizer()

# 処理対象のテキストを定義
text = "今日はいい天気だ。しっかり運動しよう。"

# トークン化された結果を1つずつ表示
tokens = tokenizer.tokenize(text)
for token in tokens:
    print(token)

上記のように、JanomeのTokenizerを使用すると、形態素解析が行われ、形態素ごとの品詞や活用形などが取得できます。

3.Janomeによる形態素解析

それでは、Janomeを用いて2024年1月以降の弊社のブログについて形態素解析を行います。
手順は以下のとおりです。
1.文章を形態素解析し、名詞・動詞・形容詞・副詞のリストを取得する
2.名詞・動詞・形容詞・副詞のリストから各品詞ごとの形態素の出現頻度のカウントを行い、上位10件を含むデータフレームを作成する
3.2のデータを棒グラフで可視化する

# テキストのクレンジング
# text にはブログ内容を格納
text = re.sub("[\n\s#*-\.\/,\(\)=_\]\[\d]", "", text)
text = re.sub("[1-9]", "", text)

1.文章を形態素解析し、名詞・動詞・形容詞・副詞のリストを取得します。

def get_part_of_speech(text: str) -> Tuple[List[str], List[str], List[str], List[str]]:
    """
    文章を形態素解析し、名詞・動詞・形容詞・副詞を分類して返す。
    Args:
        text(str): 入力テキスト
    Returns:
        Tuple[List[str], List[str], List[str], List[str]]:
            - 名詞のリスト
            - 動詞のリスト
            - 形容詞のリスト
            - 副詞のリスト
    """
    tokens = tokenizer.tokenize(text)
    noun = []       # 名詞を格納するリスト
    verb = []       # 動詞を格納するリスト
    adjective = []  # 形容詞を格納するリスト
    adverb = []     # 副詞を格納するリスト

    # 最低限のstopwordを定義
    stopwords = ["いる", "する", "の", "なる", "れる", "やる", "よう", "こと", "ある",
                 "せる", "おる", "よる", "られる", "できる", "みる", "ため", "ない",
                "しまう", "おく", "いく"]

    # 各トークンから名詞・動詞・形容詞・副詞を取得する
    # 動詞・形容詞・副詞からは基本形を取得する
    for token in tokens:
        part = token.part_of_speech.split(",")[0]
        if part == "名詞":
            noun.append(token.surface)
        elif part == "動詞":
            verb.append(token.base_form)
        elif part == "形容詞":
            adjective.append(token.base_form)
        elif part == "副詞":
            adverb.append(token.base_form)

    # stopwordを除去
    noun = [n for n in noun if n not in stopwords]
    verb = [v for v in verb if v not in stopwords]
    adjective = [a for a in adjective if a not in stopwords]
    adverb = [ad for ad in adverb if ad not in stopwords]

    return noun, verb, adjective, adverb

noun, verb, adjective, adverb = get_part_of_speech(text)

2.名詞・動詞・形容詞・副詞のリストから各品詞ごとの形態素の出現頻度のカウントを行い、上位10件を含むデータフレームを作成します。

def create_count_df(part_of_speech: List[str]) -> pd.DataFrame:
    """
    与えられた単語リストから頻度カウントを行い、上位10件を含むデータフレームを作成する。
    Args:
        part_of_speech(List[str]): 単語のリスト
    Returns:
        pd.DataFrame: 単語とその頻度を列に持つデータフレーム
    """
    counter = collections.Counter(part_of_speech)
    most_common = counter.most_common(10)
    count_df = pd.DataFrame(most_common, columns=["word", "frequency"])
    return count_df

noun_df = create_count_df(noun)
verb_df = create_count_df(verb)
adjective_df = create_count_df(adjective)
adverb_df = create_count_df(adverb)

# 名詞のデータフレームの5件をサンプル表示
print("名詞のデータフレームの5件をサンプル表示")
display(noun_df.head())

3.棒グラフで可視化する

# 2行に4つのプロットを配置するためのFigureとAxesを作成 
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(20, 10))

# 名詞・動詞・形容詞・副詞のデータフレームに基づいて棒グラフを作成
sns.barplot(data=noun_df, x="frequency", y="word", color="blue", alpha=0.5, ax=axes[0, 0])
sns.barplot(data=verb_df, x="frequency", y="word", color="blue", alpha=0.5, ax=axes[0, 1])
sns.barplot(data=adjective_df, x="frequency", y="word", color="blue", alpha=0.5, ax=axes[1, 0])
sns.barplot(data=adverb_df, x="frequency", y="word", color="blue", alpha=0.5, ax=axes[1, 1])

# 各プロットの設定をループで共通化
for i, ax in enumerate(axes.flatten()):
    ax.set_xlabel("頻度")
    ax.set_ylabel("単語")
    ax.set_title(["名詞", "動詞", "形容詞", "副詞"][i], fontsize=15)

# X軸目盛りを調整
max_frequency = axes.flatten()[2].get_xlim()[1]
axes.flatten()[2].set_xticks(range(0, int(max_frequency) + 1, 1)) 

plt.tight_layout()
plt.savefig("image.png")
plt.show()

おわりに

今回は、Janomeを用いて弊社ブログの形態素解析を行いました。
名詞から「データ・モデル・学習・試験」、動詞から「受ける・読む」、形容詞から「新しい・高い」という単語が多く出現していることから分析すると、「新しく高度な技術を取り入れ、自己研鑽する」というような印象を受けますね。
大量のテキストデータから形態素解析を行うことで、より有意義な分析が可能となり、さまざまなアクションの検討材料とすることができます。
現在は、生成AIで文章の要約などが簡単に行えますが、基礎を学ぶことも大切にしたいと思います。
最後までご覧いただき、ありがとうございました。