분산과 공분산의 계산
대수적으로 분산($\sigma^2$)과 공분산(COV)은 식 1과 같이 계산됩니다.
\begin{align} \tag{식 1}\sigma^2&=\frac{1}{N-1} (x-\mu)^2\\ \text{Cov(x, y)}&=\frac{1}{N-1}(x-\mu_x)(y-\mu_y)\end{align}
즉, 분산은 관찰값 자신이 평균과 떨어져 있는 정도를 나타내며 공분산은 두 관찰값이 평균에 대한 변화정도를 나타내는 지표입니다. 아래에서 각 값 $x_1, x_2, x_3$가 평균을 고려한 값(관찰값-평균)이라면 그 값들의 벡터와 전치벡터의 곱은 분산과 공분산을 나타냅니다.
x1,x2,x3=symbols("x1,x2,x3") A=Matrix(3,1,[x1,x2,x3]);A
$\left[\begin{matrix}x_{1}\\x_{2}\\x_{3}\end{matrix}\right]$
A*A.T
$\left[\begin{matrix}x_{1}^{2} & x_{1} x_{2} & x_{1} x_{3}\\x_{1} x_{2} & x_{2}^{2} & x_{2} x_{3}\\x_{1} x_{3} & x_{2} x_{3} & x_{3}^{2}\end{matrix}\right]$
위 결과에서 대각원소들은 각 변수의 분산, 대각외요소들은 두 변수간의 공분산을 나타냅니다.
식 1로 계산되는 분산과 공분산을 벡터 또는 행렬로 구성되는 데이터로부터 다시 고려해 봅니다. 식 2는 $n \times p$ 차원인 관측값 S를 행렬로 나타낸 것입니다. 각 열은 변수이고 각 행은 샘플(인스턴스)이라고 합니다. 즉, 식 2는p개의 변수와 n개의 샘플로 구성된 것입니다.
$$\tag{식 2}S=\begin{bmatrix}x_{11} &x_{12} &\cdots & x_{1p}\\x_{21} &x_{22} &\cdots & x_{2p}\\\vdots &\vdots &\ddots & \vdots\\x_{n1} &x_{n2} &\cdots & x_{np} \end{bmatrix}$$
이 샘플 S의 평균(sample mean, M)은 각 변수의 평균을 나타내는 것으로 각 열의 합을 샘플 수 n으로 나눔으로 계산할 수 있습니다(식 3).
\begin{align}\tag{식 3}M&=\frac{1}{n}\left(\begin{bmatrix}x_{11}+x_{21}+\cdots+x_{n1}\\\qquad \vdots \\x_{1p} +x_{2p} +\cdots + x_{np} \end{bmatrix} \right)\\ &=\begin{bmatrix} \frac{\sum^n_{i=1}x_{i1}}{n}\\\vdots \\\frac{\sum^n_{i=1}x_{ip}}{n} \end{bmatrix} \\n:&\;\text{샘플의 수, 행의 수}\end{align}
식 4의 행렬 B는 각 값들에 대한 평균과의 차이를 나타낸 것입니다.
\begin{align}\tag{식 4}B&=X^T-M\\ &=\begin{bmatrix}x_{11}&x_{21}&\cdots&x_{n1}\\ \vdots&\vdots&\ddots&\vdots \\x_{1p} &x_{2p} &\cdots & x_{np} \end{bmatrix}-\begin{bmatrix} \frac{\sum^n_{i=1}x_{i1}}{n}\\\vdots \\\frac{\sum^n_{i=1}x_{ip}}{n} \end{bmatrix} \\n:&\;\text{샘플의 수, 행의 수}\end{align}
식 4는 결과적으로 평균을 0로 하기 위해 모든 관찰값들을 평균 만큼 이동시킨 것으로 관찰값들과 동일한 차원의 행렬 B로 생성됩니다. 이 행렬은 평균-편차 형태(mean-deviation form)이라고 합니다. 정방행렬이 아닌 행렬은 그 행렬의 전치행렬과의 곱으로 정방행렬을 생성할 수 있으며 이것은 이차형태를 나타내는 기본 구조입니다. 이것을 적용하여 샘플 S의 공분산 행렬(sample covariance matrix), covM은 식 5와 같이 $n \times n$ 행렬 S로 정의 됩니다.
$$\tag{식 5} \text{covM}=\frac{1}{n-1} BB^T$$
식 5에서 $BB^T$는 0을 포함하여 항상 양수이므로 양의 반정부호(semidefinite)입니다.
import numpy as np import numpy.linalg as LA import pandas as pd from sympy import * np.set_printoptions(precision=4, suppress=True)
예 1)
다음행렬의 평균과 공분산 행렬?
$$X_1=\begin{bmatrix}1\\2\\1\end{bmatrix}\quad X_2=\begin{bmatrix}4\\2\\13\end{bmatrix}\quad X_3=\begin{bmatrix}7\\8\\1\end{bmatrix}\quad X_4=\begin{bmatrix}8\\4\\5\end{bmatrix}$$
위 각 벡터를 결합하여 행렬로 나타냅니다.
x1=np.array([1,2,1]).reshape(3,1) x2=np.array([4,2,13]).reshape(3,1) x3=np.array([7,8,1]).reshape(3,1) x4=np.array([8,4,5]).reshape(3,1) X=np.c_[x1,x2,x3,x4] print(X)
[[ 1 4 7 8] [ 2 2 8 4] [ 1 13 1 5]]
np.mean(x, axis)
함수를 사용하여 평균을 계산합니다. 평균은 각 열당 계산하는 것으로 axis=0을 지정합니다(함수의 인자 axis에 대해 참조).
M=np.mean(X, axis=0) M.round(2)
array([1.33, 6.33, 5.33, 5.67])
B=X.T-M.reshape(-1,1) B.round(2)
array([[-0.33, 0.67, -0.33], [-2.33, -4.33, 6.67], [ 1.67, 2.67, -4.33], [ 2.33, -1.67, -0.67]])
covM=(B@B.T)/2 covM.round(2)
array([[ 0.33, -2.17, 1.33, -0.83], [ -2.17, 34.33, -22.17, -1.33], [ 1.33, -22.17, 14.33, 1.17], [ -0.83, -1.33, 1.17, 4.33]])
위 과정없이 np.cov(객체1, 객체2=None, rowvar=True)
함수를 적용하여 객체의 공분산을 계산할 수 있습니다. 이 함수에서 rowvar 인수에 의해 행렬에 대한 계산방향을 지정할 수 있습니다. rowvar는 분산 계산을 행방향으로 한다는 것으로 객체 X는 각 열이 하나의 변수이므로 분산은 각 열을 기준으로 계산해야 합니다. 그러므로 다음 코드와 같이 rowvar=False로 지정합니다.
covM2=np.cov(X, rowvar=False) covM2.round(2)
array([[ 0.33, -2.17, 1.33, -0.83], [ -2.17, 34.33, -22.17, -1.33], [ 1.33, -22.17, 14.33, 1.17], [ -0.83, -1.33, 1.17, 4.33]])
댓글
댓글 쓰기