読者です 読者をやめる 読者になる 読者になる

St_Hakky’s blog

心理学/人事/就活/留学/データサイエンス/バイオインフォマティクス/日頃思ったことについて書きます。

時系列解析:自己相関係数, 定常性, White Noise, AR, MA, ARMA, ARIMA, ARIMAXについて【調べたら随時追加】

こんにちは。

最近時系列解析をすることになり、AR, MA, ARMA, ARIMA, ARIMAXあたりについて勉強したので、それについてまとめておこうかと思います。ぶっちゃけいろんなところにもうすでに解説は出ているので、これは調べている過程で参考になったリンクまとめ&個人的メモみたいな感じになってます。

○時系列解析とは

そもそも時系列解析とはなんぞやっていうことなんですが、過去のデータから未来のデータを予測することを言います(そのまんまかよみたいな笑)。

他の情報とかを利用するケースもあると思うんですが(あんまり深く勉強していないので、こんなのもあるよとかあれば教えて欲しい笑)、基本的には過去の自分自身のデータを用いて、つまり1変量のデータのみを用いて未来の予測を行います。

こちらの参考資料にもありますが、時系列データにおいて回帰分析を行うのはあまり得策ではありません。

時間軸における影響、例えば先月の銀行の預金額は今月の預金額に影響を与えるといった、時間軸における特徴をしっかり考慮したモデルを考えよう、ということで時系列解析を行います。

○時系列データの種類

何も加工のしていない時系列データそのものは、原系列と呼ばれます。

これに対して、あとで示す定常性を満たすために、原系列を変換する処理として一般的に使われるものがいくつかあります。

対数系列 原系列に対数変換をしたもの
階差系列/差分系列 原系列の各時点から何時点か前の時点を引いた系列
対数差分系列 原系列に対数変換を施して、その系列の差分系列をとったもの
季節調整済み系列 季節変動の影響を取り除いた系列

○自己相関係数(ACF), 偏自己相関係数(PACF)

自己相関係数とは、過去の値とどれくらい似ているかを表したものです。以下の関数の定義式を用いて計算されます。

自己相関係数(ACF) = \frac{ \sum{ (y_t - \overline{y} )y_{t-lag} - \overline{y} )} }{ \sum{(y_t - \overline{y})^2 }}

  • 分母は、分散
  • y_t : 時刻tにおける値
  • lag : ラグ
  • \overline{y} : 平均

相関係数の時系列バージョンという感じですね。値も-1から1までの値をとります。

こちらで自己相関係数を実際に Rでプロットしているものがあるんですが、こんな感じで、今現在の値が過去のどの時点に影響を受けているか、を見ることは大事です。

このプロットされているグラフはコレログラフといい、Rとかでめっちゃ簡単に表せます(Pythonでもできます)。

以下で定常性の話をしますが、定常性を満たしているかどうかを確認する上でも、この自己相関係数は重要です。以下の事実は、こちらにある通り、重要なのでここでも紹介させていただきます。

  • データが定常じゃないと直線になってしまう
  • データが定常だと「指数的に減衰」または「sinカーブを描きながら、減衰」となる

相関係数とは、注目している時点以外の要因を無視した自己相関係数のことです。例えば、昨日の関係はみたいけど、一昨日の要因は差排除して関係を見たいとかそういう時に使います。

以下の動画はACFとかPACFを理解するために参考になりました。
youtu.be

そこで紹介されていたのが、以下のテーブル。一応メモがてらこれだけ残しておきます笑。

AR(p) MA(q) ARMA(p,q)
ACF Tails off Cuts off after lag q Tails Off
PACF Cuts off after lag p Tails Off Tails Off

○(弱)定常性

時間依存を調べることは、データの並び順に意味を見いだすことになります。なので、データの並び順を考慮しない「データが独立に抽出された標本」という前提条件に基づいた分析手法では、時間依存関係を調査することはできません。

そこで、「データが同一の分布に従う」という条件を元に、時間に依存した前提条件を考えることで、時系列データ解析が可能になります。その前提条件というのが、弱定常性というものです。

定常性には大まかに2種類定義があり、弱定常性と強定常性の二つがあるのですが、まずは弱定常性のみを示します。


【弱定常性の定義】
弱定常性を持つという定義は、任意のthに対して、以下を全て満たす時に言います。

  1. E(y_t)=a => 平均が一定
  2. Var(y_t)=\sigma_0 => 分散が一定
  3. Cov(y_t, y_{t-h}) = \sigma_h => 自己共分散がラグhにのみ依存


次に、強定常性の定義です。

【強定常性】
任意のthに対して、(y_t, y_{t+1},...,y_{t+h})^{T}の同時分布が同一になる場合、過程は強定常性という。

これらの定義から、弱定常性は「時点ではなく、lagにのみに線形の依存関係が存在する」ことを示していること、強定常性は「時点ではなく、lagにのみに線形の依存関係が存在するだけでなく、すべての形の依存構造がlagにのみにある」ことを示していることになります。

○White Noise

定常な時系列の中でももっとも簡単で重要な系列であるのが、このWhite Noise(ホワイトノイズ、白色雑音)です。White Noiseでとは、平均が0、分散がある一定の値をとり、全ての自己共分散が0になっているものをさします。

【定義】

  • E(y_t)=0 => 平均が0
  • Var(y_t)=\sigma^2 => 分散がある一定の値をとる
  • Cov(y_t, y_{t-h}) = 0 => 自己共分散が0

このWhite Noiseは、時系列モデルにおいて確率的変動を表現するところとして表現することができます。また、White Noiseが弱定常性を満たすことは明らかです。

■参考文献

White noise - Wikipedia

○見せかけの回帰・単位根検定・共和分検定

ARIMAなどのモデルに入る前に、このテーマについて扱っておきます。

見せかけの回帰とは、こちらのブログで示されている説明を引用させていただくと、

デタラメな2つの数字同士であっても、それが「前の日の分に今日の分を足す」操作をするだけで、勝手にお互いに関連があるように見えてしまうのです。これが見せかけの回帰です。

ということらしいです。見せかけの回帰についてや単位根過程についてはこちらに詳しくかいてあり、それも参考になりました。

○AR(Auto Regressive model)

まず、定義は以下の通り。

y_{t} = \sum_{i=1}^{p} \gamma_{i}  y_{t-i} + C + \epsilon_{t}

  • p : lagの数
  • C : Constant
  • \gamma_{i} : parameter
  • \epsilon_{t} : White Noise

\gamma_{i}の値が例えば正の値を取ると、過去のその時点と同じ方向に進もうとする傾向が強くなるので、時系列におけるデータの変化が同じ方向に行こうとします。

逆に、負の値を取ると、過去のその時点と逆の方向に進もうとする傾向が強くなるので、時系列における変化がブレブレになります。

○MA(Moving average model)

定義は以下の通り。

y_{t} = C + \epsilon_{t} + \sum_{i=1}^{q} \theta_{i}\epsilon_{t-i}

  • q : lagの数
  • C : Constant
  • \theta_{i} : parameter
  • \epsilon_{t} : White Noise

これを見ると、パラメーター\theta_{i}の値が正だと、同じ方向に動く傾向があり、また負だと逆方向に進む傾向が強くなるので、時系列における変化がブレブレになります。これは、ARと同じような感じです。

○ARMA

先ほど示したARモデルとMAモデルを組み合わせたものです。定義は以下の通り。

y_{t} = C + \sum_{i=1}^{q} \theta_{i}\epsilon_{t-i} +  \sum_{i=1}^{p} \gamma_{i}  y_{t-i}

○ARIMA(Auto Regressive Integrated Moving Average)

沖本先生の本に実際の定義はあるらしいのですが、こちらの方から引用させていただくと、

d階差分をとった系列が定常かつ反転可能なARMA(p,q)過程に従う過程は次数(p,d,q)の自己回帰和分移動平均過程もしくはARIMA(p,d,q)と呼ばれる。

ということらしいです。d=0の時は、ARMAモデルということになりますね。

○ARIMAX

これは、ARIMAモデルは基本的には上で適宜される1変量による自己回帰なんですが、例えば曜日とか天気とか気温とかそういう効果を取り入れたいときに、使用するモデルです。これについては、こちらの記事が参考になりました。

○ARFIMA、SARIMA、、、

他にもたくさんあるみたいです笑。またここは調べたら更新します。

Python/Rでの実装

Pythonでもできるみたいですが、色々調べた感じでは、Rの方がパッケージの充実度としては高い感じの印象を受けました。Pythonの方が言語としては好きなので、色々頑張りましたが結局Rで実装しました笑

時系列解析系で使えるRのパッケージの一覧は以下にあります。

CRAN Task View: Time Series Analysis

ありすぎてやばいっすね。笑

で、どうしよっかなーと思っていたら、以下の資料を見つけました。

www.slideshare.net

○参考にした本



経済・ファイナンスデータの計量時系列分析


また書き足したら更新します。

Macでscreenを使うときのインストールからコマンドまでのまとめ

こんにちは。以下、自分用のメモです。

○Screenとは

仮想的に複数の端末を起動させて、いろんな作業を同時にやっちゃおうっていうことをしたり、画面を分割したりできる便利なやつです。

○Homebrewでインストー

普通にHomebrewでインストール可能です。ただ、縦方向の分割もしたい場合は、バージョンを最新のやつで入れたほうがいいのと、Macに標準で入っている場合とのバッティングがあるので、それを回避する必要があります。

brew update
brew tap homebrew/dupes # tapします
brew info screen # 最新のscreenの情報の確認
brew install --HEAD screen   # 最新のバージョンのインストール

○Screenの環境設定

基本的には、以下のサイトを見ればだいたいやりたいことができるので、そこにおまかせします。

wadap.hatenablog.com

○Screenでよく使うコマンドまとめ

「A=>B」 は、「Aの後B」という意味。

目的 コマンド
screenの起動 terminalでscreenと入力
複数のシェルの起動 terminalでscreen -t newtermと入力
とある番号の端末に移動 ctrl + j => 数字
端末のリストを確認 ctrl + j => l (アルファベットのエル)
画面を横方向に分割 ctrl + j => S
画面を縦方向に分割 ctrl + j => l(棒線)
ターミナルの移動 ctrl + j => TAB
画面分割を閉じる ctrl + k => X

「職場の問題地図 ~「で、どこから変える?」残業だらけ・休めない働き方」を読んだ

こんばんは。

最近はデータ解析系の本(これは論文の方が多いかも)から、プログラミング、ビジネス書までとにかく読んで読んで読みまくっているんですが、「職場の問題地図 ~「で、どこから変える?」残業だらけ・休めない働き方」をかいつまんで(全部は読んでない)読んだのでそのことについて書こうと思います。

○読んだ本

読んだ本は以下の本。

これと同じシリーズの本みたいなのも出ているようですね。

○読んだ感想

僕は気になった部分だけ読んだのですが(諸事情により全部読む暇なかった。3/4くらいだけ読んだ)、普通に面白かったです。

読んでる間、ずっと

「あぁ、これあるあるだなぁ」

みたいな感じで読み続けてました笑。全体的にすごく読みやすくて、また職場のあるあるすぎる問題点をわかりやすくまとめていて、さらにすぐに実践できる改善策まで書かれていました。管理職とか、プロジェクトのリーダーが読むべき本かな、と思います。

色々参考になるところがあったのですが、個人的にいいなと思ったことをまとめると以下のような感じかと。

  • 部下の報告に対して、復唱したり、感情を添えたりする
  • 非属人化をマニュアル化で進める。
  • 嫌がられるマニュアル化や非属人化を進めること自体を「良い評価指標」とする
  • 報連相ができてない、しない人には報連相をするタイミングを事前に決めておく
  • 報連相ができない人には、フォーマットを決めてお互いに「結論から言えよ…」みたいなイライラを防止する

最近接した「みんなから認められている人」とかは、もちろん専門的な技能としても秀でているんだけど、こういったマネジメントとか、みんなで気持ちよく振る舞えるようにする"コツ"とか"勘所"みたいなのを抑えているなぁとこの本を読んで思った。

特に僕が参考になったのは、「仕事をやらない人がなぜできるか」ということが書かれていた部分。

なぜこのパターンの人が出来上がるのかにはある程度パターンがあると思っていたんだけど、そのことについてもまとまった気がする。

【仕事をやらない人がなぜできるかパターン】

1. もともと優秀なんだけど、「なんでこれを俺がわざわざやらなあかんのだ」からのやらなくなるパターン
→能力値に対してレベルが低いタスクが割り当てられてしまうと起こる。

2. 給与が同じなのに何故か「別の誰か」の失態が回ってきて「それならできない方が得じゃね」ってなり、やらなくなるパターン
→やらない人がやらない人を生み出してしまう例。

3. できる人が全ての後処理やタスクをガンガンこなしてしまい、「あの人やってくれるから大丈夫」ってなり、やらなくなるパターン
→教育的な観点や、仕事に余裕がないシーンで、エース級の社員がいてしまった例。

これらは単発で起こるというよりも、同時多発的に起こるイメージが強くて、必ずしもこうするとうまくいくとかもなく、解決策も多種多様になると思います。

個人的に、「1.」や「3.」はまだ解決できると思うんですよね。「1.」であれば、本にも書かれているように2:6:2の法則を素直に受け入れて、そのような組織編成にするとか、「3.」であれば、エース級社員に教育的観点を持ってもらい、またプロジェクトに少し余裕を持たせればいい(余裕持たせるのが難しいのもあると思うんですけど)。

問題は「2.」の場合で、もし「2.」の「別の誰か」さんが責任を感じて頑張って成長をしていってくれる系だったらまだなんとかなると思うんだけど、以下の記事にもあるような「できなかったことに対して何も感じない、対処しない系」だと終わったンゴってなると思う。

news.yahoo.co.jp

個人的には、そんなヒーヒー回さないといけないプロジェクトであれば、もうそれはどこかしら問題があると思っていて、それはもうスケジュールを遅らせるとか、PMクラスがリスケとかプロジェクト進行に変更を加えるとかで動くしかないと思うんですよね。

でも、問題を解決するために、採用の時点とか、今の運営の方法とか、まぁそんないろんな要因をぶっ潰していく必要はあるわけなんだけど、現場の人からすると中長期的(年スパン)な視点だけじゃなくて「今ココ1,2ヶ月で」なんとかしてくれよ!ってなると思うんですよね笑。

ここについてはまだ考え中なわけなんだけども、こういった本やこういった問題について世間で今取り上げられている背景には、ワークライフバランスとかが最近叫ばれるようになってきて、日本も変わろうと思っているからだと思うんですよね。

でも、僕の最近の考えとして、リモートワークたら、働くの多様化たら、ワークライフバランスたらを言えるのって、普通の「働く」よりも圧倒的に難しいことを要求しているんじゃないかなって思っていて、それは現場のこういったことを解決した先にあるのであって、先にそれを求めちゃうのはなんだかなぁと思わんでもないなぁと。

とりとめもない感じになってしまった。
それでは。

Effective python シリーズ7:Use List Comprehensions Instead of map and filter

こんにちは。

○読んでいる本

以下の本を勉強がてら読んでいます。

www.effectivepython.com

ここにある通り、Pythonプログラムを改良する59項目が掲載されています。詳細は本に書かれているので、それを読めば良しとして、大事そうなところと、これに関連して勉強したことを書きます。

まとめページは以下より。

st-hakky.hatenablog.com


さて、今回は7つ目:「Use List Comprehensions Instead of map and filter」をやります。

○Use List Comprehensions Instead of map and filter

mapやfilterの代わりにリスト内包表記を使おうという話ですね。

■結論

まとめると以下の2点。

  • リスト内包表記は、lambda式がいらないしmapとfilterの合わせ技も簡潔にかける
  • 辞書と集合にもリスト内包表記使えて便利

主張として、lambdaはややこしく見えるという話ですね。まぁ言わんことはわからんでもないのと、PEP8だと関数化しろって言われますし(あれはあれでどうなのって思うんですが)。

プログラムの規模が大きくなると、小さい処理とかのために、いちいち関数化しているとコードが煩雑になり、わかりにくくなるのもあるので、lambdaを関数化で回避するのもいただけない。

というので、リスト内包表記を使いましょうという話ですね。

■コード比較:2乗計算をして見る

実際にコードを見るのがいいとおもうので、そうします。

データは以下を用意。

a = [1,2,3,4,5,6,7,8,9,10]


これのデータを、リスト内包表記とmapで書いて見る。

# リスト内包表記
_list_naiho = [x ** 2 for x in a]

# map
_map = map(lambda x: x ** 2, a)

結果は同じになります。この程度のわかりやすさなら、好みかなと思ったりしなくはないですが笑んまぁ、この例だったら、ぶっちゃけどっちでもいいんじゃね笑

大量の処理をさせようとした時に色々速さはきになるところですが、以下のブログによれば、速さでいくと、リスト内包表記の方が早いと書いてありますが、ここは議論が分かれていますね(参考情報に参考リンクを貼った)

Pythonのリスト内包表記の速度 - Qiita

このような例だったら、一概に「こう」というわけでもなく、僕的には可読性を元に使い分ける感じでいいのではないかと思います。

■コード比較:2で割れる数だけ2乗する

今回もデータは以下を用意。

a = [1,2,3,4,5,6,7,8,9,10]


これに対して、2で割れる数だけ2乗するコードは以下の通り。

# リスト内包表記
_list_naiho = [x ** 2 for x in a if x % 2 == 0]  

# mapとfilter
_map = map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, a)) 

これは確かにリスト内包表記の方がわかりやすいですね。mapとfilterを両方使うとごちゃごちゃしだすな(このパターンはまぁリスト内包表記ですね)

Effective python シリーズ6:Avoid Using start, end, and stride in a Single Slice

こんにちは。

○読んでいる本

以下の本を勉強がてら読んでいます。

www.effectivepython.com

ここにある通り、Pythonプログラムを改良する59項目が掲載されています。詳細は本に書かれているので、それを読めば良しとして、大事そうなところと、これに関連して勉強したことを書きます。

まとめページは以下より。

st-hakky.hatenablog.com


さて、今回は6つ目:「Avoid Using start, end, and stride in a Single Slice」をやります。

○Avoid Using start, end, and stride in a Single Slice

はい、これですね。前回のエントリで僕が堂々とメモ書きしていたやつをやめなさいと言われていますね笑

■somelist[start:end:stride]

前回のエントリ以外にも、Pythonでは、リストをstartからendまでstrideずつ取ってくるという機能があり、例えば増分に2とか指定すると、偶数番目とか奇数番目のデータを取得できたりします。

somelist = ["odd", "even", "odd", "even", "odd", "even", "odd"]
odds = somelist[::2]
evens = somelist[1::2]
print(odds)
print(evens)

上記を実行すると、

['odd', 'odd', 'odd', 'odd']
['even', 'even', 'even']

ってな感じです。

■よくある文字列反転

なんかPythonっぽくて僕は好きなんですが、ぱっと見確かに何やっているかわからないというのはあると思います。笑

somestring[::-1]

これの問題点の一つに、ASCII文字のバイト列にはうまく働くが、UTF-8バイト列で符号化したUnicode文字列にはダメというのがあります。

somestring = "これは動かない"
x = somestring.encode("utf-8")
y = x[::-1]
z = y.decode("utf-8")  # error!!

わかりにくさの観点で行けば、負の値をstartやendに指定しだすと、読みにくくなるというのがあります(詳しくは本参照)。

■問題点まとめ
  • 文字列反転によく使うあれはASCII文字のバイト列はうまくいくけどutf-8バイト列で符号化したUnicode文字列にはダメなので、バグの原因にもなるし別の方法を取ろう(逆に言えばこれ以外の場合は、、)
  • 混乱を避けるために、できるだけ正のstride値を使い(負のstrideは使わない)、startかendのうちどちらか一方のみと一緒に使うようにする。

それでは。