« 2015年10月 | トップページ | 2017年1月 »

2016年4月 1日 (金)

[R]非線形最小二乗法を簡単に行う

使用するデータは、オンラインゲーム「ドラゴンクエストX」の操作キャラクターのレベルとそのレベルになるために必要な累積の経験値(レベル1からの通算の値)とする。

使用するデータは本記事の最後に表示してある。なお、これら数値をまとめたテキストファイルdqxexpe1.datも用意してありダウンロードすることも可能。なお、このウェブサイトの数値を引用させてもらっている。

上記テキストファイルを置いたフォルダーでコマンドライン入力を行うことを前提とする。

まず、テキストファイルのデータを読み込み、ベクトルに格納する。プロットする。

> dtf <- read.table("dqxexpe1.dat", colClasses = "numeric")
> lvo <- dtf$V1
> exo <- dtf$V2
> plot(lvo, exo, xlab = "", ylab = "")

Figure01

レベル1から継続して規則的に増加しているのはレベル77までのように見える。ここでは特に深く考えずレベル1~77の値について計算対象とする。

> idx <- which(lv <= 77)
> lv <- lvo[idx]
> ex <- exo[idx]

図を見る限りはf(x)=x^2(※xの2乗を示す)のグラフに似ているように見える。そこで、以下の式を近似式と仮定する。

y = a * (x ^ b)

x:横軸の値(レベル)
y:縦軸の値(レベル1からの累積の必要経験値)
a,b:求める係数

変数aと変数bの値を非線形最小二乗法により求める。

関数nlsを使用して非線形最小二乗法を行う。

> r <- nls(ex ~ a * I(lv ^ b), start = c(a = 1.e3, b = 1.e0))

非線形最小2乗法は適切な初期値を与えなければ収束する解(もっともらしい解)を得ることは理論上できず、基本的な機能しか搭載されていないnls関数も例外ではない。上記の例ではaに1000(=1.e3)、bに1(=1.e0)を与えて計算を行っている。

nls関数は計算が適切に実行されれば(解が収束すれば)特に何も表示せずに終了する。なお、参考としてうまく解が求められなかった典型的な例を以下に示す。

> r <- nls(ex ~ a * I(lv ^ b), start = c(a = 1.e0, b = 1.e0))
numericDeriv(form[[3L]], names(ind), env) でエラー:
   モデルを評価する際,欠損値または無限大が生成されました
> r <- nls(ex ~ a * I(lv ^ b), start = c(a = 0., b = 0.))
nlsModel(formula, mf, start, wts) でエラー:
   パラメータの初期値で勾配行列が特異です

得られた回帰モデルを図に重ねて表示する。coef関数を使用すれば、得られた係数(モデルパラメータ)を得ることができる。分かりやすさを重視して、とりあえずベクトルaとbにそれぞれ代入する。

> a <- coef(r)[1]
> b <- coef(r)[2]

回帰モデルをlines関数を使用して重ねて描画する。x(レベル)が1~77における回帰モデルから計算される経験値をベクトルyに代入し、すでに表示されている図に赤実線で描画する。

> x <- 1:77
> y <- a * x ^ b
> lines(x, y, col = "red")

Figure02

図からも妥当なモデルが得られたことがわかる。なお、計算結果の要約はsummary関数を使うと表示される。

> summary(r)
Formula: ex ~ a * I(lv^b)
Parameters:
  Estimate Std. Error t value Pr(>|t|)   
a 0.320597   0.007543    42.5   <2e-16 ***
b 3.767800   0.005556   678.1   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 8255 on 75 degrees of freedom
Number of iterations to convergence: 33
Achieved convergence tolerance: 7.386e-06

この結果より、累積の経験値はレベルの数値の約3.8乗の値に比例して増え、その比例定数は約0.3であることがわかる。

 

1       0
2       7
3      22
4      48
5      88
6     147
7     234
8     362
9     546
10     810
11    1180
12    1692
13    2383
14    3303
15    4503
16    6043
17    7989
18   10412
19   13387
20   16996
21   21320
22   26447
23   32459
24   39444
25   47480
26   56645
27   67009
28   78638
29   91599
30  105958
31  121784
32  139146
33  158115
34  178765
35  201169
36  225401
37  251537
38  279655
39  309835
40  342154
41  376695
42  413539
43  452770
44  494474
45  538736
46  585643
47  635284
48  687748
49  743129
50  801516
51  863004
52  930921
53 1002458
54 1077729
55 1156846
56 1239919
57 1327056
58 1418364
59 1513949
60 1613920
61 1718384
62 1827446
63 1941210
64 2059779
65 2183258
66 2311750
67 2445356
68 2584176
69 2728309
70 2877856
71 3032916
72 3193604
73 3360070
74 3532512
75 3711179
76 3896371
77 4088439
78 4287785
79 4487131
80 4686477
81 4885823
82 5085169
83 5284515
84 5483861
85 5683207
86 5932553
87 6231899
88 6581245
89 6980591
90 7429937
91 8029283
92 8778629
93 9737975

« 2015年10月 | トップページ | 2017年1月 »

無料ブログはココログ

■■

■■■