シリーズの概要と全体の流れ

障害管理表・インシデントログ・アンケート自由記述など、Excel に溜まり続けるフリーテキスト列は、そのまま眺めるだけでは傾向が見えにくいものです。ワードクラウド(Word Cloud)に変換すれば、頻出するキーワードが視覚的に際立ち、「どの原因が多いか」「どのシステム領域でトラブルが集中しているか」を一目で把握できます。

本シリーズでは Python を使って Excel の読み込み → 日本語形態素解析 → ワードクラウド生成・保存 の一連の処理を実装します。全 3 回の構成は次のとおりです。

PART 01(本記事)
ライブラリのインストールと、動作確認用サンプル Excel(障害管理表)の生成。
PART 02
Excel の読み込み(pandas)とテキストの前処理・形態素解析(janome)による単語抽出。
PART 03
ワードクラウドの生成・表示・PNG 保存、ストップワード追加・月次自動生成などの応用。

対象読者は Python の基礎(pip・仮想環境・関数定義)を理解している中級者です。MeCab のような外部バイナリは不要で、pip install だけで完結する構成にしています。

必要なライブラリのインストール

仮想環境を有効化した状態で、以下のコマンドを実行してください。ライブラリは 5 つあります。

Shell — 一括インストール
pip install pandas openpyxl wordcloud janome matplotlib

インストールが完了したら、各ライブラリのバージョンを確認します。

Shell — バージョン確認
pip show pandas openpyxl wordcloud janome matplotlib
出力例(バージョンは環境によって異なります)
Name: pandas
Version: 2.2.2
---
Name: openpyxl
Version: 3.1.2
---
Name: wordcloud
Version: 1.9.3
---
Name: janome
Version: 0.5.0
---
Name: matplotlib
Version: 3.9.0

⚠️ Python バージョンについて

本シリーズは Python 3.9 以上を前提にしています。python --version で確認してください。また、仮想環境(venv)を作成してからインストールすることを強く推奨します。グローバル環境への直接インストールは依存関係の競合を引き起こす場合があります。

各ライブラリの役割

インストールした 5 つのライブラリは、それぞれ明確な役割を担っています。全体のデータフローの中でどこに位置するかを把握しておくと、エラーが発生したときに原因を特定しやすくなります。

ライブラリ 役割 使用するタイミング
pandas Excel ファイルの読み込みと DataFrame でのデータ整形 Excel を読み込み、特定の列を抽出・結合するとき
openpyxl pandas の Excel 読み書きバックエンド(直接呼び出しは不要) pd.read_excel() / df.to_excel() の内部で自動使用
janome 日本語テキストの形態素解析(単語分割・品詞判定) Excel から取り出したテキストを単語に分割するとき
wordcloud 単語の出現頻度に応じてフォントサイズを変えた画像を生成 形態素解析で得た単語列からワードクラウドを描画するとき
matplotlib ワードクラウド画像の表示・PNG 保存 生成した画像を画面に表示、またはファイルに保存するとき

💡 janome を選ぶ理由

日本語形態素解析には MeCab が有名ですが、Windows への導入は手順が複雑でバイナリのインストールが必要です。janome は純 Python 実装なので pip install だけで動き、MeCab 辞書の設定も不要です。処理速度は MeCab より遅いですが、数千行の Excel なら実用上の問題はありません。

サンプルの障害管理表を作成する

実際の手元データがなくても試せるよう、スクリプト内でサンプルの Excel を生成します。ここで作る障害管理表には「障害ID」「発生日」「障害内容」「原因」の 4 列があります。「障害内容」と「原因」がワードクラウドの分析対象テキストになります。

Python — サンプル Excel 生成
import pandas as pd

# ─── 障害管理表のサンプルデータ(10件) ───────────────────────────────────────
records = [
    {
        "障害ID": "INC-001",
        "発生日": "2024-01-10",
        "障害内容": "データベース接続エラーが発生し、サービスが停止した",
        "原因":    "コネクションプールの設定ミス"
    },
    {
        "障害ID": "INC-002",
        "発生日": "2024-01-15",
        "障害内容": "ネットワーク障害によりAPIタイムアウトが多発した",
        "原因":    "ネットワーク機器のファームウェア不具合"
    },
    {
        "障害ID": "INC-003",
        "発生日": "2024-02-03",
        "障害内容": "メモリ不足でアプリケーションサーバーがクラッシュした",
        "原因":    "メモリリークのバグ"
    },
    {
        "障害ID": "INC-004",
        "発生日": "2024-02-18",
        "障害内容": "ディスク容量不足によりログ書き込みに失敗した",
        "原因":    "ログローテーション設定の漏れ"
    },
    {
        "障害ID": "INC-005",
        "発生日": "2024-03-05",
        "障害内容": "データベースのスロークエリにより応答時間が増大した",
        "原因":    "インデックス未設定"
    },
    {
        "障害ID": "INC-006",
        "発生日": "2024-03-12",
        "障害内容": "認証サーバーへの接続タイムアウトでログインできなかった",
        "原因":    "認証サーバーの過負荷"
    },
    {
        "障害ID": "INC-007",
        "発生日": "2024-04-01",
        "障害内容": "APIのレートリミット超過によりリクエストが拒否された",
        "原因":    "バッチ処理の並列数設定ミス"
    },
    {
        "障害ID": "INC-008",
        "発生日": "2024-04-20",
        "障害内容": "証明書の期限切れによりHTTPS通信が切断された",
        "原因":    "証明書更新の作業漏れ"
    },
    {
        "障害ID": "INC-009",
        "発生日": "2024-05-08",
        "障害内容": "キャッシュサーバーの障害でデータベースに負荷が集中した",
        "原因":    "キャッシュの冗長化不足"
    },
    {
        "障害ID": "INC-010",
        "発生日": "2024-05-22",
        "障害内容": "デプロイ後に設定ファイルの読み込みエラーが発生した",
        "原因":    "環境変数の設定漏れ"
    },
]

df = pd.DataFrame(records)
df.to_excel("incident_log.xlsx", index=False)

print("✅ incident_log.xlsx を作成しました")
print(f"   行数: {len(df)} 件")
print()
print(df[["障害ID", "障害内容"]].to_string(index=False))
実行結果
✅ incident_log.xlsx を作成しました
   行数: 10 件

 障害ID                                   障害内容
INC-001          データベース接続エラーが発生し、サービスが停止した
INC-002              ネットワーク障害によりAPIタイムアウトが多発した
INC-003         メモリ不足でアプリケーションサーバーがクラッシュした
INC-004                ディスク容量不足によりログ書き込みに失敗した
INC-005           データベースのスロークエリにより応答時間が増大した
INC-006       認証サーバーへの接続タイムアウトでログインできなかった
INC-007          APIのレートリミット超過によりリクエストが拒否された
INC-008               証明書の期限切れによりHTTPS通信が切断された
INC-009       キャッシュサーバーの障害でデータベースに負荷が集中した
INC-010            デプロイ後に設定ファイルの読み込みエラーが発生した

スクリプトを実行すると、カレントディレクトリに incident_log.xlsx が生成されます。Excel を開いて内容を確認してみましょう。シート名はデフォルトの Sheet1 になっています。

💡 自分のデータで試す場合

手元に実際の障害管理表や問い合わせログがある場合は、サンプルデータの生成スクリプトは不要です。PART 02 で pd.read_excel("あなたのファイル.xlsx") のように実ファイルを指定するだけで同じ手順が使えます。テキスト列の名前(カラム名)は適宜読み替えてください。

動作確認 — ファイルの読み込みテスト

生成した Excel を pandas で読み込めるか確認しておきます。このステップで問題が出ると PART 02 以降で躓くため、必ず実施してください。

Python — 読み込みテスト
import pandas as pd

df = pd.read_excel("incident_log.xlsx")

# 基本情報を確認
print("=== DataFrame 情報 ===")
print(f"行数 × 列数: {df.shape}")
print(f"列名: {list(df.columns)}")
print()

# 先頭 3 行を表示
print("=== 先頭 3 行 ===")
print(df.head(3))
print()

# 欠損値の確認(NaN があると後工程でエラーになる)
print("=== 欠損値の確認 ===")
print(df.isnull().sum())
実行結果
=== DataFrame 情報 ===
行数 × 列数: (10, 4)
列名: ['障害ID', '発生日', '障害内容', '原因']

=== 先頭 3 行 ===
  障害ID      発生日                        障害内容              原因
0  INC-001  2024-01-10  データベース接続エラーが発生し、サービスが停止した  コネクションプールの設定ミス
1  INC-002  2024-01-15    ネットワーク障害によりAPIタイムアウトが多発した  ネットワーク機器のファームウェア不具合
2  INC-003  2024-02-03  メモリ不足でアプリケーションサーバーがクラッシュした       メモリリークのバグ

=== 欠損値の確認 ===
障害ID    0
発生日    0
障害内容    0
原因      0
dtype: int64

「欠損値の確認」で全列が 0 になっていれば、データはきれいな状態です。実際の業務データでは欠損値(NaN)が混入していることが多いため、次の PART 02 で対処方法を解説します。

次の PART 02 では…

ここで生成した incident_log.xlsx を読み込み、「障害内容」「原因」列を結合してテキストを作成します。続けて janome で形態素解析を行い、名詞・動詞・形容詞だけを取り出してワードクラウドの入力データを準備します。

→ PART 02 — Excel読み込みと形態素解析へ