LoginSignup
5
0

More than 1 year has passed since last update.

"Python初心者"がアニメデータをPythonで分析してみた

Last updated at Posted at 2022-08-07

目次

・はじめに
・やりたいこと
・実行環境
・分析してみた
・最後に
・参考

・はじめに

Aidemy Premiumにて「データ分析コース」を3ヶ月受講いたしました。Aidemy Premiumを受講したのは、データ分析、機械学習、Pythonを学びそれを仕事に活かしたと思ったことがきっかけです。
Pythonもデータ分析も初心者なので、至らない点が多々あると思いますが、温かい目で見守って頂ければと思います。

・実行環境

Python 3.7.13
Google Colaboratory

・やりたいこと

普段からアニメが好きなので、Kaggleの「Anime list」 を用いて、高評価となっているアニメの要因を分析し、次にどんな特徴があるアニメが流行るか分析したいと思います。

・分析してみた

1.データ全体を確認する

前提として、各カラムの意味は下記の通りです。( Kaggleページより)

カラム
・name: アニメタイトル
・studio: スタジオ名
・theme: テーマ
・tags: 追加のテーマやジャンルなど
・source: ソース(マンガなど)
・rating: 評価点
・year: 放送が開始された年
・synopsis: アニメの概要
・demographic: 対象性年齢区分(少年やキッズなど)
・status: ステータス(放送終了、放送中など)
・eps: エピソード数
・eps_avg_duration_in_min: 1話あたりの長さ(分)
・rated_by: レビュー数

1-1.まずはデータを読み込みます。

import pandas as pd

df = pd.read_csv("/content/anime-list.csv", index_col=0)
display(df.head())

image.png

1-2.shapeを確認します。

print(f'shape : {df.shape}\n')

出力結果
→shape : (3005, 13)

13カラム、3005行のデータであることがわかります。

1-3.次に、データの統計量を表示します。

print(f'{df.dtypes} \n')

出力結果

name objects
studio object
theme object
tags object
source object
rating float64
year float64
synopsis object
demographic object
status object
eps float64
eps_avg_duration_in_min float64
rated_by object

数値データの統計量

display(df.describe())
index rating year eps eps_avg_duration_in_min
count 1812.0 2949.0 2890.0 2950.0
mean 7.043311258278146 2007.2641573414717 43.062283737024224 18.194576271186442
std 0.7760967667136169 12.151285471626275 75.14915315176842 8.01981932089218
min 2.93 1963.0 2.0 0.0
25% 6.49 2002.0 13.0 12.0
50% 7.05 2011.0 26.0 23.0
75% 7.55 2016.0 51.0 24.0
max 9.14 2023.0 1787.0 50.0

coutより全カラム欠損データがあることがわかります。
ratingは最大9.14、最小2.93なのでおそらく10点満点の評価だと思います。

数値以外

display(df.describe(exclude='number'))
index name studio theme tags source synopsis demographic status rated_by
count 3005 3005 3005 2470 2510 2315 3005 2981 3005
unique 3005 242 323 358 15 2309 5 4 995
top Shingeki no Kyojin Unknown Kids Comedy Manga It is based on N.Y.SALAD written by Yoshitaka Amano. It depicts lives of vegetable fairies at a kitchen in N. Y.StudioUnknownSourceDemographicKids Kids Finished 0
freq 1 1032 1002 252 1181 2 1376 2850 277

欠損データについても確認します

df.isna().sum()

出力結果

name count
name 0
studio 0
theme 0
tags 535
source 495
rating 1193
year 56
synopsis 690
demographic 0
status 24
eps 115
eps_avg_duration_in_min 55
rated_by 0

2.カラム確認と前処理

次にカラムの値を確認します。
分析で利用できそうなカラムだけピックアップして記載します。
欠損値などは後々分析しやすいよう前処理も合わせて行います。

2-1.studio(スタジオ名)

データを集計して最も多いものトップ10を表示します

df["studio"].value_counts().head(10)

出力結果
image.png
Unknownが最大でした。

2-2.theme(テーマ)

データを集計して最も多いものトップ10を表示します

df["theme"].value_counts().head(10)

出力結果
image.png

Kidsが最大となっていることがわかります。

2-3.source(ソース(マンガなど))

データを集計して最も多いものトップ10を表示します

df["source"].value_counts().head(10)

出力結果
image.png

Mangaが最大となっていることがわかります。
アニメオリジナルが多いのは個人的には以外でした。

また、項目にOtherがありました。
本来他の項目もちゃんとみて欠損データをどう補完するか検討したほうが良いかもしれませんが、
今回は、欠損データはすべてOtherにしたいと思います。

df.source.fillna("Other", inplace=True)
df["source"].value_counts().head(10)

出力結果
image.png

2-4.demographic(対象年齢)

unique数も少ないので、ヒストグラフとして表示します。

sns.countplot(x="demographic", data=df)
df["source"].value_counts().head(10)
plt.show()

出力結果
image.png
最も多いのはKidsでした。

2-5.year(放送が開始された年)

同じくヒストグラフとして表示します。

import seaborn as sns
sns.histplot(data=df, x="year")

出力結果
image.png
2000年あたりから急激に数が増えてきていることがわかります。

2-6.status(ステータス(放送終了、放送中など))

データを集計して最も多いものトップ10を表示します

df["status"].value_counts().head(10)

出力結果
image.png

Finishedは既に放送が終了しているもの、Airingが現在放送中のものであることがわかりますが、
残りのNotとished、欠損データについては状況が不明なので、
もう少し詳細を確認します。

Not

df[df.status == "Not"].head()

出力結果

index name studio theme tags source rating year synopsis demographic status eps eps_avg_duration_in_min rated_by
139 Chainsaw Man MAPPA Gore, Mythology Action, Adventure Manga NaN 2022.0 Denji has a simple dream—to live a happy and peaceful life, spending time with a girl he likes. This is a far cry from reality, however, as Denji is forced by the yakuza into killing devils in order to pay off his crushing debts. Using his pet devil Pochita as a weapon, he is ready to do anything for a bit of cash.Unfortunately, he has outlived his usefulness and is murdered by a devil in contract with the yakuza. However, in an unexpected turn of events, Pochita merges with Denji's dead body and grants him the powers of a chainsaw devil. Now able to transform parts of his body into chainsaws, a revived Denji uses his new abilities to quickly and brutally dispatch his enemies. Catching the eye of the official devil hunters who arrive at the scene, he is offered work at the Public Safety Bureau as one of them. Now with the means to face even the toughest of enemies, Denji will stop at nothing to achieve his simple teenage dreams.[Written by MAL Rewrite]StudioMAPPASourceMangaThemesGoreMythologyDemographicShounen Shounen Not NaN NaN 386K
265 Boku no Hero Academia 6th Season Unknown School, Super Power Action Manga NaN 2022.0 Sixth season of Boku no Hero Academia.StudioUnknownSourceMangaThemesSchoolSuperPowerDemographicShounen Shounen Not NaN NaN 154K
319 Bleach: Sennen Kessen-hen Unknown Shounen Action,Adventure,Fantasy Manga NaN 2022.0 NaN Shounen Not NaN NaN 111K
339 Dr. Stone 3rd Season Unknown Time Travel Adventure, Comedy, Sci-Fi Manga NaN 2023.0 Third season of Dr. Stone, airing in 2023.StudioUnknownSourceMangaThemeTime TravelDemographicShounen Shounen Not NaN NaN 94K

タイトルをGoogleで数件調べたのと、上記よりyearが2022、2023となっているため放送日は決まっているがまだ開始していないものが「Not」だと推測できます。
そのため、わかりやすく「comming soon」に変更したいと思います。

df["status"].replace("Not", "comming soon", inplace=True)

次に、ished

df[df.status == "ished"]

※件数が多いので、上位5件のみ表示
出力結果

index name studio theme tags source rating year synopsis demographic status eps eps_avg_duration_in_min rated_by
870 Shaolin Chuanqi Unknown Martial Arts Action, Adventure, Comedy, Fantasy Other NaN NaN NaN Shounen ished 26.0 22.0 111
2232 Xing Mao Lixian Ji Zhi Shu Fa Pian Unknown Kids Adventure Other NaN NaN Chisese series about the adventures of Star Cat.StudioUnknownSourceDemographicKids Kids ished 26.0 12.0 198
2282 Wu Lan Qi Qi Ge Unknown Historical NaN Other NaN NaN NaN Kids ished 26.0 22.0 171
2490 G Fighters Unknown Kids Action, Sci-Fi Original NaN NaN NaN Kids ished 26.0 23.0 47
2494 Baobao Yue Xuetang: Binfen Kuaile Hao Unknown Kids Adventure, Comedy Original NaN NaN NaN Kids ished 180.0 25.0 46

中国のアニメも多そうな気がし、ratingもyearもNanなので分析では使えなさそうなので、
「ished」のデータは削除してしまいます。

df.drop(df[df["status"] == "ished"].index, inplace=True)

最後に、欠損値

df[df.status.isna()]

※件数が多いので、上位5件のみ表示
出力結果

index name studio theme tags source rating year synopsis demographic status eps eps_avg_duration_in_min rated_by
352 Tonikaku Kawaii 2nd Season Unknown Shounen Comedy, Romance Manga NaN NaN Second season of Tonikaku Kawaii.StudioUnknownSourceMangaDemographicShounen Shounen NaN NaN NaN 85K
428 Fairy Tail: 100 Years Quest Unknown Shounen Action, Adventure, Fantasy Manga NaN NaN The 100 Years Quest: a mission so challenging and hazardous that it has remained unaccomplished for over a century. While countless mages have attempted to take on this grueling objective, their results ended in either overwhelming defeat or worse. Nonetheless, Natsu Dragneel and his friends—Lucy Heartfilia, Gray Fullbuster, Erza Scarlet, and Wendy Marvell, along with the exceeds Happy and Charlés—ambitiously embark on the quest.A year after the Fairy Tail guild has overcome the diabolical forces of Acnologia and Zeref, Natsu and his team trek into the northern continent of Guiltina, where they seek out the employer of the 100 Years Quest and receive their nearly impossible mission: to seal away the Five Dragon Gods—a group of individuals with such vast power that, if left alone, could cause global devastation. Meanwhile, a spirited new member named Touka is recruited to Fairy Tail. Although her vibrant energy and passionate nature makes her perfect for the guild, there seems to be more to her than meets the eye.Determined to accomplish their seemingly insurmountable mission, Natsu and his friends begin their treacherous search for the Dragon Gods. However, once encountering a new dark guild named Diabolos, along with the newest recruit of Fairy Tail revealing her true colors, Natsu and his team will find that the 100 Years Quest isn't the only challenge they face. [Written by MAL Rewrite]StudioUnknownSourceMangaDemographicShounen Shounen NaN NaN NaN 49K
435 Jigokuraku MAPPA Historical NaN Manga NaN NaN Gabimaru the Hollow, a ninja of Iwagakure Village known for being cold and emotionless, was set up by his fellow ninja and is now on death row. Tired of killing and betrayal, he wants to die. However, no method of execution works on him because as much as the seemingly apathetic Gabimaru refuses to admit it, he does have a reason to live. He wants to return to his wife, who was the reason why he softened up and failed to be an effective assassin. Thus, he refuses to die.Asaemon the Decapitator, a famous executioner, sees this and has a proposal for the ninja. He wants Gabimaru to join an expedition to an island south of Japan in search of the elixir of life in exchange for a full pardon by the Shogunate. However, this island isn't a normal island: it's believed to be Paradise.However the island is full of mysteries, and the exploring team—consisting of those marked for death—might not be fully prepared to handle them.[Written by MAL Rewrite]StudioMAPPASourceMangaThemeHistoricalDemographicShounen Shounen NaN NaN NaN 47K
607 Mato Seihei no Slave Seven Arcs Harem Action, Fantasy, Supernatural Manga NaN NaN When entrances to a different dimension known as the "Mato" emerge all over Japan, a new resource known as "Peaches" are discovered which give unique abilities only to women. However, dangerous monsters called "Yomotsu Shuuki" also roam throughout the Mato and have been responsible for various disasters ever since. To combat them, the government formed the Anti-demon Corps, an elite group of women who have received power from the Peaches.One day, a high school student named Yuuki Wakura was walking home from school when he suddenly got lost in a Mato entrance. When he calls for help, he is immediately rescued by Kyouka Uzen, the chief of the Seventh Unit of the Anti-demon Corps. Recognizing his potential while also needing him to make her Peach power more effective, she asks that Yuuki join the Anti-demon Corps by becoming her slave, a position he might find more enjoyable than he initially would have thought... (Source: MU, edited)StudioSeven ArcsSourceMangaThemeHaremDemographicShounen Shounen NaN NaN NaN 12K

タイトルをGoogleで数件調べたところ、制作中のアニメで放送日が決まっていないものが「NaN」だと推測できます。
そのため、わかりやすく「no release date」に変更したいと思います。

df["status"].fillna("no release date", inplace=True)

最後にもう一度確認する。

df["status"].value_counts().head(10)

image.png
明確になりました。

2-7.rated_by(レビュー数)

データを集計して最も多いものトップ10を表示します

df["rated_by"].value_counts().head(10)

出力結果
image.png

1,000=K、1,000,000=Mとアルファベットで表記されているので、利用しやすいようにreplaceで数値に変換します。

df["rated_by"] = df["rated_by"].replace({"K":"*1000", "M":"*1000000"}, regex=True).map(pd.eval).astype(int)
display(df["rated_by"].value_counts())

image.png

正しく変換できました。

2-8.eps(エピソード数)

データを集計して最も多いものトップ10を表示します

df["eps"].value_counts().head(10)

出力結果
image.png

epsの欠損データは

df[(df['eps'].isna())]

出力結果
image.png

この内、statusが「Airing,comming soon,no release date」のものが大半で、4件だけstatusが「Finished」のものがあった。
なぜepsがNanなのか不明だが、ratingもNanなので削除する。

df.drop(df[(df['eps'].isna()) & (df.status =="Finished")].index, inplace=True)

image.png

2-9.rating(評価点)

最後にratingです。
高評価となっているアニメの要因分析を行う目的なので、statusがFinishedでratingが欠損値、rated_byが0件以外のものは削除します。

df.drop(df[(df['rating'].isna()) & (df.status =="Finished") & (df.rated_by !=0)].index, inplace=True)

ヒストグラフとして表示します。

import seaborn as sns
sns.displot(data=df, x="rating")

出力結果
image.png

2-10.放送終了・放送中に絞る

今回は、高評価となっているアニメの要因分析までしか取り組まないためデータを放送終了・放送中のものだけに絞ります。
今後は今回の分析をもとに公開予定のアニメが流行るかどうか分析できるまで取り組みたいです・・・。

df2 = df[df["status"].isin(["Finished", "Airing"])].copy()
df2.info()

image.png

3.高評価となっているアニメの要因分析

まず何をもって高評価とするか決める。
今回はratingの上位5%を高評価として定義する。

import numpy as np
np.percentile(df2["rating"].dropna(), 95)

出力結果
8.368999999999996

上位5%を区別するため、列を追加する。

df2['TopFlg'] = 0
df2.loc[df2[df2["rating"] >=8.368999999999996].index, 'TopFlg'] = 1

追加した列と他のカラムの相関を確認します。

import seaborn as sns
sns.heatmap(df2.corr(), annot=True)

image.png

1に近いほど相関があるので、このなかでいうとrateed_byくらいが相関がありそうですが、
他はあまり相関がなさそうです。以降で深掘りしていきます。

3-1.studioから見ていきます

グラフにしてみたのですが、ユニーク数が多く見れないので、
データを確認します。

df2[df2["TopFlg"] == 1]["studio"].value_counts().head()

出力結果
image.png
Madhouseが高評価のアニメを一番出しています。

はじめの一歩や、NANAなどが入ってました。

単純に出しているアニメが多いだけかもしれないので確率を求めてみます。

df2["studio"].value_counts()
df3=pd.concat([df2[df2["TopFlg"] == 1]["studio"].value_counts(),df2["studio"].value_counts()],axis=1,keys=["topflg1","sum"])

df3["kaku"] = df3['topflg1']/df3["sum"]*100
display(df3[df3['topflg1'].notna()].sort_values('kaku',ascending=False).head(7))

出力結果
image.png

Shuka、Egg Firmは2件中2件高評価となっています。
Wit Studioは10件中5件となっています。

Madhouseより、上記スタジオのほうが高評価を出す確率は高そうです。

3-2.次はthemeです。

themeはカンマ区切りで複数1列に登録されているので、
分割して件数を確認します。

themes = []
 
for theme in df2[df2["TopFlg"] == 1]["theme"].tolist():
    themes.extend(theme.split(", "))
    
pd.Series(themes).value_counts().head(10)

出力結果
image.png
Historical(歴史)とSchool(学校)が多く含まれているものが高評価が多いです。

鬼滅の刃・キングダム、呪術廻戦・スラムダンクなどが入っていました。

3-3.次はtagsです。

theme同様カンマ区切りで複数1列に登録されているので、
分割して件数を確認します。


# tagsがfloatになっていたのでstrに変換する
df2 = df2.astype(
    {
        'tags' : str
        }
    )
themes = []
for theme in df2[df2["TopFlg"] == 1]["tags"].tolist():
    themes.extend(theme.split(", "))
    
pd.Series(themes).value_counts().head(10)

出力結果
image.png
アクションとドラマが多く含まれているものが高評価が多いです。

進撃の巨人・鋼の錬金術師、ジョジョの奇妙な冒険・ちはやふるなどが入ってました。

3-4.次はsourceです。

import matplotlib.pyplot as plt
sns.countplot(x= 'source',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png
漫画原作のものがダントツで1位でした。
評価関わらず、総数も漫画がダントツでした。

3-5.次はyearです。

グラフにするとx軸が見にくいので8つの区間に分類してからグラフ化しました。

df2['yearBunrui'] = pd.qcut(df2['year'],8)

import matplotlib.pyplot as plt
sns.countplot(x= 'yearBunrui',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png

1990年台と古いものは高評価のものがないですが、以降の年によって大きな変化はなかったので、放送開始年は特に高評価の要因とは関係ないと判断しました。

3-6.次はdemographicです。

import matplotlib.pyplot as plt
sns.countplot(x= 'demographic',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png

少年と青年で大半を占めています。
Kidsは総数は多いのですが高評価は0件でした。
ポケモンやデジモンなど高評価が付きそうなものがあったのですが7点台が大半でした。
対象年齢が低いと良い評価を得にくいと判断しました。

3-7.次はepsです。

グラフにするとx軸が見にくいので6つの区間に分類してからグラフ化しました。

df2['epsBunrui'] = pd.qcut(df2['eps'],6)

import matplotlib.pyplot as plt
sns.countplot(x= 'epsBunrui',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png

エピソード数と高評価は、前段の結果と同様やはり相関がないようでした。
エピソード数が多い=長く続いているので高評価かと分析前は思っていたのですが関係なさそうです。
実際のデータを見ると、1つのアニメでもシーズン1、2と別れているためこのような結果になっていました。

3-7.次はeps_avg_duration_in_minです。

import matplotlib.pyplot as plt
sns.countplot(x= 'eps_avg_duration_in_min',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png

display(df2[df2["TopFlg"] == 1]["eps_avg_duration_in_min"].value_counts())

出力結果
image.png

22-26分に高評価が集まっていました。
大体のアニメがこの範囲に集まっているので当然の結果かなと思いました。
youtubeやTikTokなどショート動画が流行っているので今後は短いものが高評価を得るなどもあるかもしれません。

3-8.最後にrated_byです。

これもグラフにするとx軸が見にくいので8つの区間に分類してからグラフ化しました。

df2['rated_byBunrui'] = pd.qcut(df2['rated_by'],8)
import matplotlib.pyplot as plt
sns.countplot(x= 'rated_byBunrui',hue='TopFlg',data=df2)
plt.legend(title='TopFlg', loc='upper right')
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

出力結果
image.png

評価数が多くなると高評価を得やすい結果となりました。
やはり相関が強いようです。

3-8.まとめ

上記結果をまとめると、
・スタジオは、Shuka、Egg Firm、Wit Studioあたりが良い
・テーマとしては、歴史、学園ものが良い
・ジャンルは、アクション系、ドラマ系が良い
・ソースは、マンガ原作!!
・対象年齢としては、少年・青年が良い
・1話あたりの長さは、22-26分程度
・レビュー数が多い=高評価。

すべて該当しないが、放送予定のもので上記に該当するものはアンダーニンジャ、チェンソーマンなどがヒットしました。
(分析しなくてもわかりそうなタイトルですが・・)

最後に

今回はKaggleのコードなども参考にしながら少しデータを分析してみました。
実際に分析してみることで知識が定着したが、もっと頑張らないとと反省しました…。
今後は仕事の中でも分析していこうと思うので、今回の経験を活かし勉強に励みたいと思います!

参考

□データセット https://www.kaggle.com/datasets/pmanthan/anime-list-2022

□参考サイト
https://myfrankblog.com/data_analysis_with_anime_review_data_part1/
https://myfrankblog.com/finding_best_animation_from_data/
https://myfrankblog.com/analyzing_good_review_anime/
(すみません、めちゃくちゃ参考にさせて頂きました。ほぼ類似してしまい申し訳ございません。)

5
0
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
5
0