プロクラシスト

今日の寄り道 明日の近道

孫悟空の今後の戦闘力の伸びを回帰分析で予想したら想像を超えた


スポンサーリンク

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