1.目的と結果
【目的】
2つの分布(ここでは平均0、分散1の正規分布)の散布図と相関係数の値の関係がざっくりわかるGIFファイルをつくること。
【結果】
以下のようにできた。
2.乱数の準備
それぞれ独立に平均0,分散1の正規分布に従う乱数$x_1,x_2$を生成。
(ここで分散1の分布を扱うので、以下では共分散算出値=相関係数として扱う)
import numpy as np
import pandas as pd
np.random.seed(1) #乱数を再現できるようにnp.random.seed(1)としておく
df=pd.DataFrame() #DataFrameに複数サンプルデータを格納する
df['x_1'] = np.random.normal(0, 1, 2000)
df['x_2'] = np.random.normal(0, 1, 2000)
3.乱数の変換
上で生成した相関のない乱数$x_1,x_2$を以下(1)式のような変数変換で相関のあるデータ$y_1,y_2$を生成。
\begin{eqnarray}
y_1 &=& x_1 \tag{1} \\
y_2 &=& x_1 \sin{\theta} + x_2 \cos{\theta} \tag{2}
\end{eqnarray}
ここでは$y_2$の分散を1にするため、式(2)右辺の$x_1$、$x_2$のそれぞれの係数を$\sin{\theta}$、$\cos{\theta}$としている。
「4.グラフ(gifファイル)作成」のグラフでは$\theta$を振ってグラフの分布を変えている。
相関係数は(1)、(2)より$\sin{\theta}$となる。
(gifファイル出力の「相関係数(計算値)」は$\sin{\theta}$。なお乱数から相関係数を算出した結果は「相関係数(実測値)」と暫定的に名付けた)
4.グラフ(gifファイル)作成
以下のコードでgifファイルを作成。
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.set_aspect('equal')
def plot(deg):
plt.cla()
theta = 2*np.pi*(10*deg)/360
y_1 = df['x_1'] # 式(1)部分
y_2 = np.sin(theta)*df['x_1'] + np.cos(theta)*df['x_2']# 式(2)部分
corr_cal = np.sin(theta) #グラフタイトルの相関係数(計算値)の値
corr_sample =y_1.corr(y_2) #グラフタイトルの相関係数(実測値)の値
plt.plot(y_1, y_2,"o", c='blue',alpha =0.1)
plt.xlim(-4,4)
plt.ylim(-4,4)
plt.xlabel('$y_1$')
plt.ylabel('$y_2$')
plt.grid()
plt.title('θ={}°、相関係数(計算値)={:.2f}、相関係数(実測)={:.2f}'
.format(deg*10,corr_cal,corr_sample),fontname="Meiryo")
# アニメーション作成
anim = FuncAnimation(fig, plot, frames=36,interval=750)
anim.save('相関θ依存.gif', writer='Pillow')
ここから出力される相関θ依存.gif
がつくりたかったgifファイル。
今回は正規分布に従う乱数で行ったが、
df['x_1'] = np.random.normal(0, 1, 2000)
とdf['x_2'] = np.random.normal(0, 1, 2000)
を変えれば
他の分布についても同様のことができるはず。
6.参考URL
以下のサイトを勉強し、参考にさせていただきました。
・[Python/matplotlib] FuncAnimationを理解して使う
・matplotlibのanimationで一枚ごとに違うタイトルを付けたい
以上。