シリーズの概要と全体の流れ
障害管理表・インシデントログ・アンケート自由記述など、Excel に溜まり続けるフリーテキスト列は、そのまま眺めるだけでは傾向が見えにくいものです。ワードクラウド(Word Cloud)に変換すれば、頻出するキーワードが視覚的に際立ち、「どの原因が多いか」「どのシステム領域でトラブルが集中しているか」を一目で把握できます。
本シリーズでは Python を使って Excel の読み込み → 日本語形態素解析 → ワードクラウド生成・保存 の一連の処理を実装します。全 3 回の構成は次のとおりです。
対象読者は Python の基礎(pip・仮想環境・関数定義)を理解している中級者です。MeCab のような外部バイナリは不要で、pip install だけで完結する構成にしています。
必要なライブラリのインストール
仮想環境を有効化した状態で、以下のコマンドを実行してください。ライブラリは 5 つあります。
pip install pandas openpyxl wordcloud janome matplotlib
インストールが完了したら、各ライブラリのバージョンを確認します。
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 列があります。「障害内容」と「原因」がワードクラウドの分析対象テキストになります。
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 以降で躓くため、必ず実施してください。
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 で形態素解析を行い、名詞・動詞・形容詞だけを取り出してワードクラウドの入力データを準備します。