파이썬으로 다변량 정규 분포를 그래프로하여 이미지를 잡아라.

세상의 다양한 현상을 표현하는 정규 분포.
그 다변량판인 다변량 정규 분포에 대해 파이썬으로 여러가지 해 보았습니다.
jupyter notebook에서 할 수 있습니다.

※이 기사는 제가 운영하는 블로그의 아래 기사를 다시 작성한 것입니다.
복어 "파이썬으로 다변량 정규 분포"

목차


  • 다변량 정규 분포란?
  • 2 차원 케이스
  • 3 차원 케이스
  • 요약

  • 다변량 정규 분포란?



    n차원의 다변량 정규 분포는 다음과 같이 표현됩니다.
    $$ f(\vec{x}) =\frac{1}{(2\pi)^{n/2}\sqrt{|\Sigma|}}\exp(\frac{1}{2}(\vec{x}-\vec{\mu} )^T\Sigma^{-1}(\vec{x}-\vec{\mu} )) $$

    1차원의 정규 분포는 평균과 분산의 2개의 파라미터로 표현할 수 있지만,
    다변량의 경우, 이것은 방정식에서 나오는 다음 벡터와 행렬로 대체됩니다.
     \begin{equation}\vec{\mu}=\begin{pmatrix}\mu_1 \\ \mu_2 \\ \vdots \\ \mu_n \\  \end{pmatrix} , \ \ \ \Sigma =  \begin{pmatrix} \sigma_{1}^2 & \cdots & \sigma_{1i} & \cdots & \sigma_{1n}\\ \vdots & \ddots & & & \vdots \\ \sigma_{i1} & & \sigma_{i}^2 & & \sigma_{in} \\ \vdots & & & \ddots & \vdots \\ \sigma_{n1} & \cdots & \sigma_{ni} & \cdots & \sigma_{n}^2 \end{pmatrix} \end{equation}
    

    여기서 $\mu_{i},\\\\sigma_{i}^2 $ 는 $i$ 번째 변수의 평균, 분산이며,
    $\sigma_{ij}=\sigma_{ji}\\(i\neq j) $ 는 $i$ 번째와 $j$ 번째 변수 사이의 공분산입니다.
    이 비대각항의 성분이 있으면, 그 변수간에 상관이 있는 것 같은 이미지가 됩니다.

    그런 다음 파이썬에서 다변량 좌석 분포 그래프를 플롯하여 어떤 것인지 이미지를 잡아 보겠습니다.

    ■2차원 케이스


    from numpy.random import *
    from matplotlib import pyplot as plt
    from pylab import rcParams
    import numpy as np
    rcParams['figure.figsize'] = 20,20
    
    #2次元正規分布version
    
    #平均
    mu1=10
    mu2=20
    #分散
    sigma1=30
    sigma2=30
    sigma12=20
    sigma1_2=90
    sigma2_2=10
    sigma12_2=30
    
    #平均ベクトルと共分散行列
    mu = [mu1, mu2]
    sigma = [[sigma1, sigma12], [sigma12, sigma2]]
    sigma_2 = [[sigma1_2, sigma12], [sigma12, sigma2_2]]
    sigma_3 = [[sigma1, sigma12_2], [sigma12_2, sigma2]]
    
    #2次元正規乱数
    values = multivariate_normal(mu, sigma, 5000)
    values_2 = multivariate_normal(mu, sigma_2, 5000)
    values_3 = multivariate_normal(mu, sigma_3, 5000)
    
    #グラフをプロット
    fig = plt.figure()
    ax0 = fig.add_subplot(2,2,1)
    ax0.plot(values[:,0], values[:,1], 'o', c='b',label="2d", alpha=0.1)
    ax0.set_title("2d normalplot")
    ax0.set_xlim(-50, 50)
    ax0.set_ylim(-50, 50)
    ax0.grid()
    #パラメータをいじってみる
    ax = fig.add_subplot(2,2,2)
    ax.plot(values[:,0], values[:,1], 'o', c='b',label="2d", alpha=0.1)
    ax.plot(values_2[:,0], values_2[:,1], 'o', c='r',label="2d", alpha=0.1)
    ax.plot(values_3[:,0], values_3[:,1], 'o', c='g',label="2d", alpha=0.1)
    ax.set_title("2d normalplot")
    ax.set_xlim(-50, 50)
    ax.set_ylim(-50, 50)
    ax.grid()
    fig.show()
    



    왼쪽의 그래프를 보면, 평균 $(x_1, x_2) = (10, 20)$ 주위에서 분산에 따라 분포하고 있는 것을 알 수 있다.
    변수 $x_1 x_2$ 사이의 공분산도 sigma12$ = 20$ 로 설정하고 있기 때문에, 상관관계를 가지는 플롯이 되었다.

    오른쪽의 그래프에서는 파라미터를 더욱 변동시켜 보았다.
    적색은 분산을 가로로 크게 하고 있다.
    녹색은 변수 $x_1 x_2$ 사이의 공분산을 sigma12_2$ = 20$ 로 하고 있어, 정확히 직선을 타는 것 같은 그래프로 되어 있다.

    상관 계수를 설정 값과 그래프의 실제 값으로 비교하면 다음과 같습니다.
    같은 값으로 확실하다.
    특히 녹색은 상관 계수가 1이므로 직선을 타는 그래프가 되었다.
    #相関係数の理論計算値
    corr1_theory =sigma12 / np.sqrt(sigma1 * sigma2)
    corr2_theory =sigma12 / np.sqrt(sigma1_2 * sigma2_2)
    corr3_theory =sigma12_2 / np.sqrt(sigma1 * sigma2)
    print(corr1_theory,corr2_theory,corr3_theory)
    
    #相関係数の実測値
    corr1 = np.corrcoef(values[:,0],values[:,1])[0,1]
    corr2 = np.corrcoef(values_2[:,0],values_2[:,1])[0,1]
    corr3 = np.corrcoef(values_3[:,0],values_3[:,1])[0,1]
    print(corr1,corr2,corr3)
    0.6666666666666666 0.6666666666666666 1.0
    0.6670848283319503 0.6527793760878543 0.9999999999999999
    

    ■3차원 케이스



    3차원에서도 마찬가지로 그래프를 플롯했다.
    %matplotlib inline
    from numpy.random import *
    from matplotlib import pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    from pylab import rcParams
    rcParams['figure.figsize'] = 20,20
    
    #3次元正規分布version
    
    #平均
    mu = [0, 0, 0]
    
    #分散
    sigma1 = 40
    sigma2 = 40
    sigma3 = 40
    sigma12 = 20
    sigma23 = 20
    sigma31 = 20
    sigma1_2 = 90
    sigma2_2 = 10
    sigma3_2 = 30
    sigma12_2 = 40
    sigma23_2 = 40
    sigma31_2 = 40
    
    sigma =  [[sigma1, sigma12, sigma31], [sigma12, sigma2, sigma23], [sigma31, sigma23, sigma3]]
    sigma_2 = [[sigma1_2, sigma12, sigma31], [sigma12, sigma2_2, sigma23], [sigma31, sigma23, sigma3_2]]
    sigma_3 = [[sigma1, sigma12_2, sigma31_2], [sigma12_2, sigma2, sigma23_2], [sigma31_2, sigma23_2, sigma3]]
    
    # 3次元正規乱数
    values1 = multivariate_normal(mu, sigma, 5000)
    values2 = multivariate_normal(mu, sigma_2, 5000)
    values3 = multivariate_normal(mu, sigma_3, 5000)
    
    #グラフをプロット
    fig = plt.figure()
    ax0 = fig.add_subplot(221, projection='3d')
    ax0.set_xlim([-50,50])
    ax0.set_ylim([-50,50])
    ax0.set_zlim([-50,50])
    ax0.scatter(values1[:,0], values1[:,1], values1[:,2], s=10, alpha=0.1, c='b')
    ax0.legend()
    #パラメータをいじってみる
    ax1 = fig.add_subplot(222, projection='3d')
    ax1.set_xlim([-50,50])
    ax1.set_ylim([-50,50])
    ax1.set_zlim([-50,50])
    ax1.scatter(values1[:,0], values1[:,1], values1[:,2], s=10, alpha=0.1, c='b')
    ax1.scatter(values2[:,0], values2[:,1], values2[:,2], s=10, alpha=0.1, c='r')
    ax1.scatter(values3[:,0], values3[:,1], values3[:,2], s=10, alpha=0.1, c='g')
    ax1.legend()
    plt.show()
    



    요약



    다변량 정규 분포에 대한 개념을 학습. 파이썬을 사용하여 2D와 3D 그래프를 플롯하여 이미지를 잡을 수있었습니다.

    좋은 웹페이지 즐겨찾기