📝 はじめに
本記事では、タイトルテキストから頻出語を抽出し、WordCloudで頻度分布を可視化する手法を紹介します。
日本語対応の形態素解析「Janome」を用い、再現性と構造設計を重視したNotebook実装を行います。
テキストデータに含まれるタイトル群を分析することで、情報の傾向や関心の分布を視覚的に把握することができます。
目次
分析対象の構造設計(YouTube視聴履歴ベース)
本記事では、Google Takeoutで取得したYouTube視聴履歴(watch-history.json)をデータソースとして使用します。
このJSONファイルには、過去に視聴した動画のタイトル・チャンネル名・視聴日時などが記録されており、タイトルテキストの頻度分析に適した構造を持っています。
元データの構造例
{
"title": "YouTubeで視聴した動画のタイトル",
"subtitles": [{"name": "チャンネル名"}],
"time": "2023-08-15T12:34:56.789Z"
}
分析用に再構成するフィールド設計
頻度分析と可視化に適した構造へ変換するため、以下のようなフィールド設計を行います:
| フィールド名 | 説明 |
|---|---|
| title_raw | 元のタイトル文字列(JSONのtitle) |
| title_main | 主タイトル部分(補足除去後) |
| title_extra | 補足情報 |
| channel | チャンネル名(subtitles.name) |
| watched_at | 視聴日時(JST変換済み) |
Notebook内での構造例
{
"title_raw": "Python × Dockerで環境構築してみた【初心者向け】",
"title_main": "Python × Dockerで環境構築してみた",
"title_extra": "初心者向け",
"channel": "Tech学習チャンネル",
"watched_at": "2023-08-15 21:34:56", # JST変換済み
}
import pandas as pd
df = pd.DataFrame([
{
"title_raw": "Python × Dockerで環境構築してみた【初心者向け】",
"title_main": "Python × Dockerで環境構築してみた",
"title_extra": "初心者向け",
"channel_name": "Tech学習チャンネル",
"watched_at": "2023-08-15 21:34:56"
},
...
])
このように構造化することで、以下のような分析が可能になります:
- タイトルテキストの頻出語分析とWordCloud可視化
- チャンネル別・時間帯別の傾向比較
- TF-IDFによるジャンルクラスタリングへの展開
今回はデータ加工や前処理の詳細は割愛し、可視化手法にフォーカスして解説を進めます。
WordCloudによる頻度可視化
タイトルテキストから抽出したキーワードの頻度分布を、WordCloudを用いて視覚的に表現します。
WordCloudは、頻出語ほど大きく表示されるため、タイトル群に潜む傾向やジャンルの特徴を直感的に把握するのに適しています。
本記事のNotebookは、以下の環境で構築・実行しています:
- 実行環境:WSL2(Ubuntu 22.04)
- 分析環境:Jupyter Lab
- 使用言語:Python 3.10
- 主なライブラリ:Janome, wordcloud, matplotlib
ライブラリのインストール
以下のコマンドで必要なライブラリをインストールします。
pip install janome wordcloud matplotlib
- janome Pythonの形態素解析エンジン
- wordcloud:頻度に応じた文字サイズで単語を描画
- matplotlib:画像の表示
日本語フォントのインストール(Ubuntu環境)
WordCloudで日本語を正しく表示するためには、日本語フォントのインストールとパス指定が必要です。日本語をフォントを使用することで文字化けを防ぎます。
ここでは IPAexフォント(IPAexゴシック)を使用します。
インストール手順
sudo apt update
sudo apt install fonts-ipaexfont
インストール後、以下のようにフォントパスを指定します:
font_path = "/usr/share/fonts/truetype/ipaexfont/ipaexg.ttf" # 例:IPAexゴシック
※ Windows環境の場合は "C:/Windows/Fonts/YuGothM.ttc" などを指定してください。
📊 タイトルテキストから頻度辞書を生成する
WordCloudによる可視化の前に、YouTube視聴履歴から抽出したタイトル群を形態素解析し、頻出語の辞書(頻度分布)を生成します。
ここでは、日本語対応の形態素解析ライブラリ「Janome」を用いて、名詞のみを抽出します。
前提 : DataFrame構造
import pandas as pd
# 例:watch-history.json を整形済みの DataFrame
df = pd.DataFrame([
{"title": "Python × Dockerで環境構築してみた【初心者向け】"},
{"title": "ChatGPT APIを使ったSlack Botの作り方(2023年版)"},
{"title": "VSCodeの便利な拡張機能まとめ"},
])
Janomeによる名詞抽出関数
from janome.tokenizer import Tokenizer
tokenizer = Tokenizer()
def extract_nouns(text):
return [
token.surface
for token in tokenizer.tokenize(text)
if "名詞" in token.part_of_speech
]
タイトル群から名詞リストを生成
# 名詞リストを列として追加
df["tokens"] = df["title"].apply(extract_nouns)
# 全タイトルから名詞を集約
all_nouns = df["tokens"].explode().dropna().tolist()
頻度辞書の生成(collections.Counter)
from collections import Counter
word_freq = Counter(all_nouns)
# 上位10語の確認
print(word_freq.most_common(10))
出力例:
[('Python', 5), ('環境', 4), ('構築', 4), ('Docker', 3), ('API', 3), ('Slack', 2), ('Bot', 2), ('作り方', 2), ('拡張', 2), ('機能', 2)]
この word_freq をそのまま WordCloud.generate_from_frequencies() に渡すことで、頻度に応じた可視化が可能になります。
WordCloudによる頻度分布の可視化コード
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# 日本語フォントのパス(Ubuntu環境例)
font_path = "/usr/share/fonts/truetype/ipaexfont/ipaexg.ttf"
## WordCloudの生成
wc = WordCloud(
font_path=font_path,
background_color="white",
width=800,
height=600,
colormap="tab10"
).generate_from_frequencies(word_freq)
# 可視化
plt.figure(figsize=(10, 6))
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.tight_layout()
plt.show()
Tips
SettingWithCopyWarning が出るとき
df["tokens"] = df["title"].apply(extract_nouns)
ではdfに対してtokensを追加していますが、
'DataFrame'の一部(部分抽出したwatched_df=df[df["条件"]])に対して新しい列を追加しようとするとSettingWithCopyWarningがでます。
その場合、copy()を使うことで回避できます。
watched_df = df[df["条件"]].copy()
watched_df["tokens"] = watched_df["title_main"].apply(extract_nouns)
ストップワードの設計
タイトルテキストの頻度分析では、意味のない語や汎用語が頻出語として現れることがあります。これらを除外することで、WordCloudの可視性と分析精度が向上します。
🔹ストップワードとは?
- 頻度は高いが、分析上の意味を持たない語句
- 例:記号、数字、助詞、接続詞、YouTube特有の汎用語(例:shorts, ch, 再生)
🔹 設計方針
| 観点 | 対処方法 |
|---|---|
| 記号・数字 | 正規表現で除去(例: #,/,2,万
|
| ひらがな1文字 | - |
| 助詞・接続詞 | 品詞フィルタで除去(名詞のみ抽出) |
| 汎用後 | 手動で除外後リストを設計(例:shorts,動画) |
| 表記ゆれ | 小文字化・辞書統一(例:Python,python
|
| 改行・URL | 前処理で除去 |
🔹 絵文字・記号の除去
- YouTubeタイトルには絵文字(🔥✨💡など)や記号(【】()[]など)が多く含まれます
- これらは意味を持たない装飾要素として扱い、頻度分析から除外するのが望ましいです
🔹 助詞・接続詞の除外
- 「の」「に」「と」「で」などの助詞は頻出しやすく、意味のある傾向を埋もれさせる可能性があります
- Janomeで品詞情報を参照し、「名詞」のみを抽出することで回避できます
def extract_nouns(text):
return [
token.surface
for token in tokenizer.tokenize(text)
if "名詞" in token.part_of_speech
]
🔹 単語の重複と表記ゆれ
- 「Python」「python」「PYTHON」など、表記揺れによる分散が起こりやすい
- .lower() や .title() などで正規化するか、辞書ベースで統一する工夫が有効
🔹 空白・改行・URLの混入
- タイトルに改行やURLが含まれる場合、形態素解析が正しく動作しないことがあります
- 前処理で空白・改行・URLを除去しておくと安心です
🔹 実装例
import re
stopwords = {"shorts", "ch", "動画", "再生", "まとめ", "見る", "万"}
## Tokensの追加(名詞のみ抽出)
watched_df["tokens"] = watched_df["title_main"].apply(extract_nouns)
def is_valid_token(token):
# 絵文字・記号・数字を除去
if not re.fullmatch(r"[ぁ-んァ-ン一-龥a-zA-Z]+", token):
return False
# ひらがな1文字の除去
if re.fullmatch(r"[ぁ-ん]", token):
return False
# ストップワード除外
if token.lower() in stopwords:
return False
return True
# ストップワードと記号を除外した名詞リストを生成
filtered_nouns = [
token for token in watched_df["tokens"].explode().dropna()
if is_valid_token(token)
]
word_freq = Counter(filtered_tokens)
🔹 ストップワードの拡張性
- 分析対象が変わるごとに、除外語リストを調整可能
- チャンネル別・ジャンル別に「残す語」「除く語」を切り替えることで、柔軟な分析が可能
まとめ
ストップワードの設計は、単なる除去ではなく「分析目的に応じた語彙選定」として捉えることで、
WordCloudの意味解釈とジャンル傾向の把握に大きく貢献します。
まとめ
本記事では、Google Takeoutで取得したYouTube視聴履歴などをもとに、タイトルテキストの頻度分布をWordCloudで可視化する手法を紹介しました。
実施内容の整理
- Janomeによる名詞抽出とノイズ除去(絵文字・記号・助詞・ひらがな1文字)
- ストップワード設計による精度向上
- Counter による頻度辞書生成
- WordCloudによる視覚的な傾向把握
今後の展開
次回記事では、タイトル群をベクトル化し、ジャンル別クラスタリング(TF-IDF × PCA × KMeans)による視聴傾向の構造化に挑戦します。