Rで Orthogonal Polynomials を作る時の注意点
最近 Growth Curve Analysis という分析手法に手を出したのですが、 ハマったポイントがあるのでメモします。 後々思った感想というか後悔なのですが、 GCAの使いどころは「理論的に曲線を期待するようなデータ」に対してですね。 難しい…。
Higher-order polynomial and its strengths
まず Growth Curve Analysis とは何か、という話ですが、 これは独立変数に連続値をもつようなデータの分析方法の1つです。 例えばxに実時間を含むようデータが挙げられれます。 発達心理学などの学習データは時間とともに要因で変動し、 こういうデータに使えます。 あるいは心理言語学の視覚世界パラダイム、ERPのデータにも使えるそうです。 言い換えると、「時間で指標がどう変化しているのか」を分析できます。
GCAは独立変数をベースに多項式を作り、 時間($Time$)という変数があれば、 時間の二乗($Time^2$)、三乗($Time^3$)をつくります。 ありがたいポイントとして、見た目は線形っぽくないデータに対してモデルを組めます。 工学的にはある種の素性エンジニアリングですね。交互作用を作る感覚に似ています。 これを愚直に時間を掛け算してしまうとエグいことになるので気をつけましょう、という内容です。
ライブラリのインポート
以下は今回使うライブラリの ggplot2
と関数です。
完全に余談なのですが、今まで magrittr
はつかってませんでした。
これはゼミでの普及率が今ひとつなのと、こういうチュートリアル的な内容で
「そもそも動かない」という事態は致命的だと考えてたからです。
でもパイプは単なる中置関数なので定義したほうが楽ですよね。
本題に戻ります。
多項式の作りかた(NGなケース)
どのように多項式の項を独立変数として作るか、 を考えた時に一番てっとり早いのは直接掛けあわせる方法です(だめですが)。
例えばここに太郎くんがいるとして、 彼の友達が増える割合を考えてみましょう。 もし太郎くんが20日に1人友達を増やせるならば、 1000日で50人増やせますよね。 (後述しますが「なぜ20日」というのにはちゃんと意味があります。)
ここで時間(日)の多項式を作れと言われれば、 以下のような方法が思いつくかもしれません。
- まず
x
という共通の変数を用意するためにx
を抽出 - cubicまでのデータフレームを作成
- 全てマージ
しかし上の図を見れば分かるように、この方法ではもとの変数と作成した変数が相関してしまいます。 いわゆるマルチコです。 そこで使えるのがpoly関数です。(単にスケールして掛け算を繰り返すだけでもいい気もします)
多項式の作りかた(OKなケース)
まずはx.bin
という変数を作り、 1から始まりかつ1ずつ増えるような値に
x
を 頑張って変換します。
後でこの値をつかってデータフレームにアクセスするから必要です。
(これをしない場合が今回の話題のミソなのですが、それは最後にします。)
そしてx.bin
と作りたい多項の値をpoly
関数に入れてます。
## 1 2 3
## [1,] -0.2400980 0.2978049 -0.33182333
## [2,] -0.2302981 0.2613390 -0.25056047
## [3,] -0.2204982 0.2263925 -0.17776250
## [4,] -0.2106983 0.1929654 -0.11306919
## [5,] -0.2008983 0.1610578 -0.05612036
## [6,] -0.1910984 0.1306695 -0.00655578
さてpoly
関数で3列作れましたね。 次に少しトリッキーなことをします。
ちょっと既存のデータフレームを書き換えるのは気が引けるので、
friend.ot
というデータフレームで少し作業します。
プロットの結果、上手くot1
, ot2
そしてot3
という列ができており、
さらにそれらの値が全く相関していないことが見ただけで分かります。
先ほどのNGの例と今回のOKな例をくらべてみれば、
分析前にplot
でマルチコが無いことを確認できることが解ると思います。
ちなみに僕は発表3日前にマルチコに気づいてキンキンに冷えました。
(ちゃんとpoly
関数つかったのですが、
その時は上手く多項式をつくれておらず、
かつ以前作ったダメな方のデータが残っていたため、
アカンデータが残ってしまっていた…という落ちです。)
さて、上の式の左辺では列をつくていますね。
1:3
が1,2,3という数値を作り,ot
という文字列の右に結合してます。
そんな列名はないので、この場合は新しい列名に右辺を格納する、
という意味になります。 他方、右辺では2つのことをしています。
- binの値でtの行にアクセス
- tには自動的に1–3の名前がつくので1:3でベクトルを作ってスタートのbinでtの行にアクセス
ここが極めて大事なのでそれぞれを更に詳しく説明します。
先ほど、x.bin
という変数は
「1から始まりかつ1ずつ増えるような値」だと述べました。
このx.bin
が1から始まらねばならない理由は、
多項のテーブルに最初の行(つまり1)からアクセスするためです。
更に1ずつ増やした理由は、それらの各行にアクセスするためです。
これをミスるとデータにアクセスできない、
という詰みポイントに到達します。