プロクラシスト

今日の寄り道 明日の近道

孫悟空の戦闘力を回帰分析で予想したら凄まじかった。


スポンサーリンク

f:id:imslotter:20170510202739p:plain

こんにちは、ほけきよです!

「私の戦闘力は53万です」

なんてもうミジンコ程度の戦闘力。学校のクラスならイジメの対象です。 現在放映中のアニメ『ドラゴンボール超(スーパー)』、キャラのインフレっぷりがのぶっ飛んでいて面白いです。

www.toei-anim.co.jp

そのアニメの中で、特に悟空の戦闘力の伸びが半端なさすぎる件について、 理系の目線でフォーカスしてみたいと思います!!

戦闘力の系譜

この記事に、戦闘力の系譜が載っていましたので、今回はこのデータを使いたいと思います

matome.naver.jp

(最後の方は、結構予想が入っていて信ぴょう性は…ですが、気にしないでいきましょう!)

戦闘力の伸びをグラフにするとこんな感じです。

f:id:imslotter:20170510202236p:plain

パナイ。。。 このままでは何が何だかわからないので、代表的な年と戦闘力を表にしておきます。

戦闘力 イベント
0 2 生まれる
16 260 ピッコロ大魔王
25 32000 ベジータ襲来
25 1.5億 フリーザ襲来(スーパーサイヤ人)
30 95億 セル襲来
37 1400億 魔人ブウ襲来(スーパーサイヤ人3
41 40兆 ビルス(スーパーサイヤ人ゴッド)
41 55兆 ゴールデンフリーザ襲来(超サイヤ人ゴッド悟空(スーパーサイヤ人)

パナイ。。。

予想してみる

とりあえず線形に合わせてみる(最小二乗法)。

オリジナルのデータのグラフは上記の通りですが、 どう考えても線形ではあわなさそうです… とりあえず、sklearnを使って回帰直線を引いてみましょう。

sklearn.linear_model.LinearRegressionを使えば、簡単に回帰を実行してくれます。素晴らしい! (コードは最後に付与します)

f:id:imslotter:20170510201315p:plain

全く合っていない…笑 当てはまり具合を示す決定係数R*1をみても、0.34程度と、全然ダメなことがわかります。

どう見ても非線形なグラフなので、しょうがないですね。

ログスケールでグラフをプロットしなおす

このままじゃどうしようもありません。戦闘力の伸びが半端ないので、とりあえず対数スケールにしてみます。 戦闘力にlog(底10)を施して、回帰を行いましょう。

結果はこちら f:id:imslotter:20170510201402p:plain

どうでしょう?かなりそれっぽい当てはまりかたをしてますね!!! 決定係数も0.89となっているので、いい感じに線形回帰ができたと言っていいのではないでしょうか。

1週間/1年でどのくらい成長するの?

はい、回帰曲線を引けたので、これからどのくらい成長できるかを予想することができます。 例えば、最近話題の「力の大会」*2。 これだと1週間後に試合なので、それまでに鍛えるということになります。 先ほどの回帰直線を式に直すと

f:id:imslotter:20170510201433p:plain

つまり、一週間で戦闘力が何倍に伸びるかを計算するためには

f:id:imslotter:20170510201448p:plain

を計算すればいいのです。すると

  • 一週間 1.7%アップ
  • 一年 250%アップ*3

となる計算です。 通常の人間の1.7%アップだと大したことないかもしれませんが、悟空の1.7%アップはなかなかやばそうですね…戦闘力にすると一週間で約1兆5000億の伸び。フリーザ換算にするとフリーザ30万体分ですね1!!どうなってんの???

50歳での悟空の戦闘力は?

最後に、回帰直線を外挿して、50歳の悟空の戦闘力を予想してみましょう。 先ほどの式に50を当てはめるだけです。計算結果は…

50000000000000000

です。5。スーパー意味不明。地球滅亡ワロタ。

【考察】なんでlogスケールになるんだろう。

ここまでで、logスケールにすると当てはまりが良く、予想できそうだということがわかりました。 どうしてlogスケールだと当てはまりが良いのか、精神物理学を引っ張ってきて考察してみましょう。

精神物理学の分野では、ヴェーバーフェヒナーの法則というのが基本法則としてよく知られていて、

「人の刺激に対する感覚の変化具合は、その時の刺激の大きさによる」

と、されています。超簡略化した数式に表すと、こういう微分方程式になります。

f:id:imslotter:20170510201536p:plain

この方程式は簡単に解けて*4、その解にlogが現れます。このようなグラフになります。

f:id:imslotter:20170510201558p:plain

  • 100円しか持っていない人が200円をGETする感覚と、100万円持っている人が200万円をGETする感覚は等しい
  • 1回目のデートと10回目のデートが同じだと飽きられる

ということを示唆しています。そんな気もしますね!

人の感覚に関わる様々な単位系でlogスケールは用いられていて、音の大きさを表すデシベル(db)、地震の大きさを表すマグニチュード(M) なども、logスケールです。

これを元にすると、戦闘力の伸びがこのように爆発的になっているのも頷けます。 読者が常に「オッ、また戦闘力が伸びたな!」と思うためには、

“どのくらい戦闘力を増やす"ではなく、むしろ"戦闘力を何倍にする”

という考え方の方が理にかなっているというわけです。これは作者自身にも言えることなので、 自然にlogスケールで戦闘力が伸びるようになっているのでしょう。

まとめ

いかがでしたか? これを予想しといてなんですが、正直ドラゴンボールは予想不可能です!w

だって、強い敵が出たらそれを超える強さが必要なんだもん…

初期から見ている私にとっては、「エッ、そこの設定まで変えちゃうのか…!」などと なかなか突っ込みどころ満載、けれどドラゴンボールらしくワクワクするような内容の作品になっています。

その困惑と期待っぷりは、過去記事に書いているのでそちらもご覧になってください。

昔のキャラがリメイク(?)されて出てきたりするので*5、気になる人はみてみるといいかもしれませんね! ではではっ!

ドラゴンボール超 1 (ジャンプコミックスDIGITAL)

ドラゴンボール超 1 (ジャンプコミックスDIGITAL)

コード

#coding:utf-8
import numpy as np
import pylab as plt
from sklearn.linear_model import LinearRegression


#データ (年, 戦闘力)
data =  [(737,2),(749,10),(750,100),(753,180),
            (753,260),(756,910),(761,1040),(762,8000),(762,3.0E+4),
            (762,30E+4),(762,90E+4),(762,300E+4),(762,1.5E+8),(764,2E+8),
            (767,5E+8),(767,9E+8),(767,12E+8),(767,66E+8),(767,95E+8),
            (767,300E+8),(774,350E+8),(774,1400E+8),(774,2.52E+12),(778,40E+12),
            (779,55E+12),(779,75E+12),(779,90E+12)]

# 回帰を実行する
def regression(t,f,fit_intercept=True):
    t = np.array(t).reshape(-1,1)
    f = np.array(f).reshape(-1,1)
    clf = LinearRegression(fit_intercept=fit_intercept)
    clf.fit(t,f)
    print(clf.coef_)        #回帰係数
    print(clf.intercept_)   #切片
    print(clf.score(t,f))   #決定係数
    return clf.coef_,clf.intercept_

# グラフを書く
def visualize(ages,powers,intercept=True):
    a,b = regression(ages,powers,intercept)
    year = range(51)
    if intercept:
        pred = [a[0,0]*t+b[0] for t in year]
    else:
        pred = [a[0,0]*t+b for t in year]
    plt.plot(ages,powers,"o-",label="data")
    plt.plot(year,pred,label="regression")
    plt.xlim(0,45)
    plt.grid()
    plt.legend(loc=2)
    plt.show()

# 年から年齢に変換
# (ほんとは途中死んだりしているのでアレなのだが、割愛!)
ages = [elm[0] - data[0][0] for elm in data]
# 戦闘力
powers = [elm[1] for elm in data]
visualize(ages,powers,intercept=False)

# 対数スケールの戦闘力
log_power = [np.log10(power) for power in powers]
visualize(ages,log_power,intercept=False)

*1:決定係数に関する詳しい解説はこちら:決定係数とは?

*2:全宇宙の天下一武道会みたいなものです

*3:計算ミスがありました。id:Drgorillaさん、ありがとうございます!

*4:きちんと解くには初期値などはいるのですが、少し省きます

*5:ゴールデンフリーザとか

PROCRASIST