0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ChatGPTに教えてもらいながら映画ジャンルのトレンドを可視化してみた

Posted at

はじめに

普段はハードウェア(メカ系・電気系)の技術職をしており、プログラミングをすることはありません。
キーボードよりも工具を触っている時間が多い日もあります。
ただ、プログラミングへの興味はあったのでChatGPT(4o)に色々相談してみたところ「映画データを使ったジャンル分析」を提案されました。

この投稿では、IMDbのデータを使って、

  • 映画ジャンルの年代別トレンドを分析・可視化

を行った流れを記載します。

ちなみに映画がテーマになったのは私が映画好きとChatGPTに教えたからです。

使用データ

環境

  • python 3.12.8
  • Jupyter Notebook

分析の流れ

データの取得

IMDbの 公式データ から title.basics.tsv.gztitle.ratings.tsv.gz をダウンロードしました。

  • title.basics.tsv.gz

    • 公開年
      • startYear (YYYY) – represents the release year of a title. In the case of TV Series, it is the series start year
    • ジャンル
      • genres (string array) – includes up to three genres associated with the title
  • title.ratings.tsv.gz

    • 評価値の平均値
      • averageRating – weighted average of all the individual user ratings
    • 評価の票数
      • numVotes - number of votes the title has received

必要なライブラリのインポート

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib

日本語フォントの設定。
最初は設定していなかったのですが、のちのちグラフ化した際に表ラベル(日本語)が□□になってしまう問題が発生しました。

# 日本語フォントの設定
plt.rcParams['font.family'] = 'Meiryo'  # WindowsならMeiryo、Yu Gothicなど

# マイナス記号が文字化けしないように
matplotlib.rcParams['axes.unicode_minus'] = False

データの読み込みと分類

pandasを使ってデータを読み込み、映画のみに絞り込みました。

file_path = '../data/title.basics.tsv.gz'  # Notebookからの相対パス
df = pd.read_csv(file_path, sep='\t', na_values='\\N', low_memory=False)

# 映画だけに絞る
df = df[df['titleType'] == 'movie'].copy()

# 年代(10年ごと)の設定
df['startYear'] = pd.to_numeric(df['startYear'], errors='coerce')
df = df.dropna(subset=['startYear'])
df['decade'] = (df['startYear'] // 10) * 10

ジャンル分け。

# 複数ジャンルがカンマ区切りで入っている
df['genres'] = df['genres'].fillna('')
df_exploded = df.assign(genres=df['genres'].str.split(',')).explode('genres')
df_exploded = df_exploded[df_exploded['genres'] != '']

可視化

genre_decade = df_exploded.groupby(['decade', 'genres']).size().unstack().fillna(0)
plt.figure(figsize=(12, 8))
sns.heatmap(genre_decade.T, cmap='YlGnBu', linewidths=0.5)
plt.title("IMDb映画ジャンルの年代別傾向")
plt.xlabel("年代")
plt.ylabel("ジャンル")
plt.tight_layout()

genre_trends_by_decade.png

いったん可視化できました。

さらなる絞り込み

映画というタイプのみの絞りこみでは本数が50,000越えと非常に多くなってしまいました。
一定数のレビューをもらっている、かつある程度の評価をされているという条件で映画を絞り込みます。

ratings = pd.read_csv('../data/title.ratings.tsv.gz', sep='\t')
df_filtered = df_exploded.merge(ratings, on='tconst', how='inner')
df_filtered = df_filtered[
    (df_filtered['averageRating'] >= 7.0) &
    (df_filtered['numVotes'] >= 1000)
]

今振り返ってみると、ChatGPTの提案通りのレビュー数(=1000)で絞り込みましたが、人気作に絞るのであればもう少し数値をあげるべきです。
アベンジャーズ:エンドゲーム レビュー数:1.4M(=1,400,000)、評価:8.4 
(注)2025年5月4日時点
この部分は要調整。評価(=7.0)についても同様。

もう一度可視化。

genre_decade_highrated = df_filtered.groupby(['decade', 'genres']).size().unstack().fillna(0)
plt.figure(figsize=(12, 8))
sns.heatmap(genre_decade_highrated.T, cmap='YlGnBu', linewidths=0.5)
plt.title("IMDb高評価映画に限定したジャンルの年代別傾向")
plt.xlabel("年代")
plt.ylabel("ジャンル")
plt.tight_layout()
plt.savefig('../figures/genre_trends_highrated.png', dpi=300)
plt.show()

genre_trends_highrated.png
ヒートマップの上限が20分の1以下になりました。

正規化

前述の可視化だと作品数が多い近年のみが濃くなってしまいます。
したがって、各年代ごとに正規化します。

# 行(各年代)ごとに合計を1にする(=各ジャンルの相対的な割合)
genre_decade_normalized = genre_decade_highrated.div(genre_decade_highrated.max(axis=1), axis=0)

plt.figure(figsize=(12, 8))
sns.heatmap(genre_decade_normalized.T, cmap='YlGnBu', linewidths=0.5)
plt.title("年代ごとに正規化したジャンル分布(高評価映画)")
plt.xlabel("年代")
plt.ylabel("ジャンル")
plt.tight_layout()
plt.savefig('../figures/genre_trends_highrated_normalized.png', dpi=300)
plt.show()

genre_trends_highrated_normalized.png

Drama(≒ヒューマンドラマ)が全ての年代で最大値をとっていることが分かりました。
IMDbでは一つの映画に複数のジャンルがラベルづけされています。
Dramaが人気というよりも、むしろ多くの映画にDramaというラベルをつけやすいことが全年代での多さの理由ではないかと考えています。

おわりに

今回はChatGPTに教わりながらプログラミングをしました。
私がやりたいことを投げかけることでコード例が生成されることは面白かったです。
x.PNG

また、「さらに~することで~できます」というような次につながる提案をしてくれることは作業を進めやすくしてくれました。
y.PNG

今回の分析はかなり粗いですが、ある程度の形にはなったので満足しています。
引き続きChatGPTに教わりながらいろいろやってみます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?