2.4 선형 연립방정식과 역행렬#

선형 예측모형은 입력 데이터 벡터와 가중치 벡터의 내적으로 계산된 예측값이 실제 출력 데이터와 유사한 값을 출력하도록 하는 모형이다. 그럼 올바른 가중치 벡터는 어떻게 구할 수 있을까? 여기에서는 연립방정식과 역행렬을 이용하여 선형 예측모형의 가중치 벡터를 구하는 방법을 알아본다.

선형 연립방정식#

복수의 미지수를 포함하는 복수의 선형 방정식을 선형 연립방정식(system of linear equations) 또는 연립일차방정식이라고 한다.

다음은 3개의 미지수와 3개의 선형 방정식을 가지는 선형 연립방정식의 한 예다.

\[\begin{split} \begin{align} \begin{matrix} x_1 & + & x_2 & & & = & 2 \\ & & x_2 & + & x_3 & = & 2 \\ x_1 & + & x_2 & + & x_3 & = & 3 \\ \end{matrix} \tag{2.4.1} \end{align} \end{split}\]

\(x_1, x_2, \cdots, x_M\) 이라는 \(M\) 개의 미지수를 가지는 \(N\)개의 선형 연립방정식은 일반적으로 다음과 같은 형태가 된다. 이 식에서 \(a\)\(b\)는 방정식의 계수다.

\[\begin{split} \begin{align} \begin{matrix} a_{11} x_1 & + \;& a_{12} x_2 &\; + \cdots + \;& a_{1M} x_M &\; = \;& b_1 \\ a_{21} x_1 & + \;& a_{22} x_2 &\; + \cdots + \;& a_{2M} x_M &\; = \;& b_2 \\ \vdots\;\;\; & & \vdots\;\;\; & & \vdots\;\;\; & & \;\vdots \\ a_{N1} x_1 & + \;& a_{N2} x_2 &\; + \cdots + \;& a_{NM} x_M &\; = \;& b_N \\ \end{matrix} \tag{2.4.2} \end{align} \end{split}\]

행렬과 벡터의 곱셈을 이용하면 위 선형 연립방정식은 다음처럼 간단하게 쓸 수 있다.

\[\begin{split} \begin{align} \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1M} \\ a_{21} & a_{22} & \cdots & a_{2M} \\ \vdots & \vdots & \ddots & \vdots \\ a_{N1} & a_{N2} & \cdots & a_{NM} \\ \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_M \end{bmatrix} = \begin{bmatrix} b_1 \\ b_2 \\ \vdots \\ b_N \end{bmatrix} \tag{2.4.3} \end{align} \end{split}\]

이 식에서

\[\begin{split} \begin{align} A = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1M} \\ a_{21} & a_{22} & \cdots & a_{2M} \\ \vdots & \vdots & \ddots & \vdots \\ a_{N1} & a_{N2} & \cdots & a_{NM} \\ \end{bmatrix} , \;\; x = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_M \end{bmatrix} , \;\; b= \begin{bmatrix} b_1 \\ b_2 \\ \vdots \\ b_N \end{bmatrix} \tag{2.4.4} \end{align} \end{split}\]

라고 하면 다음처럼 쓸 수 있다.

\[ \begin{align} Ax = b \tag{2.4.5} \end{align} \]

\(A, x, b\) 는 각각 **계수행렬(coefficient matrix), 미지수벡터(unknown vector), 상수벡터(constant vector)**라고 부른다.

이 표현을 따르면 앞에서 예로 든 선형 연립방정식은 다음처럼 표현할 수 있다.

\[ \begin{align} Ax = b \tag{2.4.6} \end{align} \]
\[\begin{split} \begin{align} A = \begin{bmatrix} 1 & 1 & 0 \\ 0 & 1 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix}, \;\;\; x = \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix}, \;\;\; b = \begin{bmatrix} 2 \\ 2 \\ 3 \end{bmatrix} \tag{2.4.7} \end{align} \end{split}\]

만약 \(A, x, b\)가 행렬이 아닌 스칼라 실수라면 이 방정식은 나눗셈을 사용하여 다음처럼 쉽게 풀 수도 있을 것이다.

\[ \begin{align} x = \dfrac{b}{A} \tag{2.4.8} \end{align} \]

그러나 행렬에서는 나눗셈이 정의되지 않으므로 이 방법은 사용할 수 없다. 행렬에서는 나눗셈 대신 역행렬이라는 것을 사용한다.

역행렬#

정방 행렬 \(A\)에 대한 역행렬(inverse matrix) \(A^{-1}\)은 원래의 행렬 \(A\)와 다음 관계를 만족하는 정방 행렬을 말한다. \(I\)는 항등 행렬(identity matrix)이다.

\[ \begin{align} A^{-1} A = A A^{-1} = I \tag{2.4.9} \end{align} \]

역행렬은 항상 존재하는 것이 아니라 행렬 A에 따라서는 존재하지 않을 수도 있다. 역행렬이 존재하는 행렬을 가역행렬(invertible matrix), 정칙행렬(regular matrix) 또는 비특이행렬(non-singular matrix)이라고 한다. 반대로 역행렬이 존재하지 않는 행렬을 비가역행렬(non-invertible matrix) 또는 특이행렬(singular matrix), 퇴화행렬(degenerate matrix)이라고 한다.

연습 문제 2.4.1#

대각행렬의 역행렬은 각 대각성분의 역수로 이루어진 대각행렬과 같다.

\[\begin{split} \begin{align} \begin{bmatrix} \lambda_{1} & 0 & \cdots & 0 \\ 0 & \lambda_{2} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \lambda_{N} \\ \end{bmatrix}^{-1} = \begin{bmatrix} \dfrac{1}{\lambda_{1}} & 0 & \cdots & 0 \\ 0 & \dfrac{1}{\lambda_{2}} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \dfrac{1}{\lambda_{N}} \\ \end{bmatrix} \tag{2.4.10} \end{align} \end{split}\]

\(N=3\)일 때 위 식을 증명하라.

역행렬의 성질#

역행렬은 다음 성질을 만족한다. 이 식에서 행렬 \(A\), \(B\), \(C\)는 모두 각각 역행렬 \(A^{-1}\), \(B^{-1}\), \(C^{-1}\)이 존재한다고 가정한다.

  • 전치 행렬의 역행렬은 역행렬의 전치 행렬과 같다. 따라서 대칭 행렬의 역행렬도 대칭 행렬이다.

\[ \begin{align} (A^{T})^{-1} = (A^{-1})^{T} \tag{2.4.11} \end{align} \]
  • 두 개 이상의 정방 행렬의 곱은 같은 크기의 정방 행렬이 되는데 이러한 행렬의 곱의 역행렬은 다음 성질이 성립한다.

\[ \begin{align} (AB)^{-1} = B^{-1} A^{-1} \tag{2.4.12} \end{align} \]
\[ \begin{align} (ABC)^{-1} = C^{-1} B^{-1} A^{-1} \tag{2.4.13} \end{align} \]

역행렬의 계산#

역행렬은 행렬식을 이용하여 다음처럼 계산할 수 있다. 증명은 생략한다.

\[\begin{split} \begin{align} A^{-1} = \dfrac{1}{\det (A)} C^T = \dfrac{1}{\det (A)} \begin{bmatrix} C_{1,1} & \cdots & C_{N,1} \\ \vdots & \ddots & \vdots \\ C_{1,N} & \cdots & C_{N,N} \\ \end{bmatrix} \tag{2.4.14} \end{align} \end{split}\]

이 식에서 \(C_{i,j}\)\(A\)\({i,j}\)번째 원소에 대해 정의한 코팩터(cofactor)다.

코팩터로 이루어진 행렬 \(C\)을 **여인수행렬(matrix of cofactors, 또는 cofactor matrix, comatrix)**이라고 한다. 또 여인수행렬의 전치행렬 \(C^T\)어드조인트행렬(adjoint matrix, adjugate matrix, 수반행렬)이라고 하며 **\(\text{adj}(A)\)**로 표기하기도 한다.

위 식에서 \(\det(A)=0\)이면 역수가 존재하지 않으므로 역행렬은 행렬식이 0이 아닌 경우에만 존재한다는 것을 알 수 있다.

연습 문제 2.4.2#

코팩터 식을 사용하여 다음 공식을 증명하라.

\[\begin{split} \begin{align} \begin{bmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{bmatrix}^{-1} = \dfrac{1}{a_{11}a_{22} - a_{12}a_{21}} \begin{bmatrix} a_{22} & -a_{12} \\ -a_{21} & a_{11} \end{bmatrix} \tag{2.4.15} \end{align} \end{split}\]

연습 문제 2.4.3#

다음 역행렬을 계산하라.

(1) $\( \begin{align} \begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix}^{-1} \tag{2.4.16} \end{align} \)$

(2) $\( \begin{align} \begin{bmatrix} \dfrac{1}{\sqrt{2}} & -\dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \end{bmatrix}^{-1} \tag{2.4.17} \end{align} \)$

(3) $\( \begin{align} \begin{bmatrix} \dfrac{3}{\sqrt{13}} & -\dfrac{1}{\sqrt{2}} \\ \dfrac{2}{\sqrt{13}} & \dfrac{1}{\sqrt{2}} \end{bmatrix}^{-1} \tag{2.4.18} \end{align} \)$

(4) $\( \begin{align} \begin{bmatrix} 1 & 1 & 0 \\ 0 & 1 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix}^{-1} \tag{2.4.19} \end{align} \)$

연습 문제 2.4.4#

두 정방행렬 \(A,B\)에 대해서 \(AB = I\)이면 \(BA= I\)임을 증명하라.

\[ \begin{align} AB = I \;\; \rightarrow \;\; BA = I \tag{2.4.20} \end{align} \]

역행렬에 대한 정리#

역행렬에 대한 몇 가지 정리를 알아두면 도움이 된다.

셔먼-모리슨(Sherman–Morrison) 공식#

정방행렬 \(A\)와 벡터 \(u, v\)에 대해 다음 공식이 성립한다.

\[ \begin{align} (A+uv^T)^{-1} = A^{-1} - {A^{-1}uv^T A^{-1} \over 1 + v^T A^{-1}u} \tag{2.4.21} \end{align} \]

우드베리(Woodbury) 공식#

정방행렬 \(A\)와 이에 대응하는 적절한 크기의 행렬 \(U,V,C\)에 대해 다음 공식이 성립한다.

\[ \begin{align} \left(A+UCV \right)^{-1} = A^{-1} - A^{-1}U \left(C^{-1}+VA^{-1}U \right)^{-1} VA^{-1} \tag{2.4.22} \end{align} \]

분할행렬의 역행렬#

4개 블록(block)으로 분할된 행렬(partitioned matrix)의 역행렬은 각 분할행렬을 이용하여 계산할 수 있다.

\[\begin{split} \begin{align} \begin{bmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \end{bmatrix}^{-1} = \begin{bmatrix} A_{11}^{-1}(I + A_{12}FA_{11}^{-1}) & -A_{11}^{-1}A_{12}F \\ -FA_{21}A_{11}^{-1} & F \end{bmatrix} \tag{2.4.23} \end{align} \end{split}\]

이 식에서 \(F\)는 다음과 같이 주어진다.

\[ \begin{align} F = (A_{22} - A_{21}A_{11}^{-1}A_{12})^{-1} \tag{2.4.24} \end{align} \]

또는

\[ \begin{align} F = (A_{11} - A_{12}A_{22}^{-1}A_{21})^{-1} \tag{2.4.25} \end{align} \]

넘파이를 사용한 역행렬 계산#

넘파이의 linalg 서브패키지에는 역행렬을 구하는 inv() 라는 명령어가 존재한다. 앞에서 예로 든 선형 연립방정식의 행렬 \(A\)의 역행렬은 다음처럼 구할 수 있다.

import numpy as np

A = np.array([[1, 1, 0], [0, 1, 1], [1, 1, 1]])
A
array([[1, 1, 0],
       [0, 1, 1],
       [1, 1, 1]])
Ainv = np.linalg.inv(A)
Ainv
array([[ 0., -1.,  1.],
       [ 1.,  1., -1.],
       [-1.,  0.,  1.]])

역행렬과 선형 연립방정식의 해#

선형 연립방정식에서 미지수의 수와 방정식의 수가 같다면 계수행렬 \(A\)는 정방행렬이 된다. 만약 행렬 \(A\)의 역행렬 \(A^{-1}\) 이 존재한다면 역행렬의 정의로부터 선형 연립방정식의 해는 다음처럼 구할 수 있다. 행렬과 벡터의 순서에 주의하라.

\[ \begin{align} Ax = b \tag{2.4.26} \end{align} \]
\[ \begin{align} A^{-1}Ax = A^{-1}b \tag{2.4.27} \end{align} \]
\[ \begin{align} Ix = A^{-1}b \tag{2.4.28} \end{align} \]
\[ \begin{align} x = A^{-1}b \tag{2.4.29} \end{align} \]

넘파이를 이용하여 앞에서 예로 든 선형 연립방정식의 해 \(x\)를 구하는 방법은 다음과 같다.

b = np.array([[2], [2], [3]])
b
array([[2],
       [2],
       [3]])
x = Ainv @ b
x
array([[1.],
       [1.],
       [1.]])

이 벡터를 원래의 연립방정식에 대입하여 상수벡터 \(b\)와 값이 일치하는지 확인해보자.

A @ x - b
array([[0.],
       [0.],
       [0.]])

lstsq() 명령은 행렬 \(A\)\(b\)를 모두 인수로 받고 뒤에서 설명할 최소자승문제(least square problem)의 답 x, 잔차제곱합(residual sum of squares) resid, 랭크(rank) rank, 특잇값(singular value) s를 반환한다. 미지수와 방정식의 개수가 같고 행렬 \(A\)의 역행렬이 존재하면 최소자승문제의 답과 선형 연립방정식의 답이 같으므로 lstsq() 명령으로 선형 연립방정식을 풀 수도 있다. 최소자승문제, 랭크, 특잇값에 대해서는 뒤에서 자세히 설명할 것이다.

다음 코드에서 lstsq() 명령으로 구한 답이 inv() 명령으로 구한 답과 같음을 알 수 있다.

x, resid, rank, s = np.linalg.lstsq(A, b)
x
array([[1.],
       [1.],
       [1.]])

lstsq() 명령을 사용하는 것이 inv() 명령을 사용하는 것보다 수치오차가 적고 코드도 간단하므로 선형 연립방정식의 해를 구할 때도 lstsq() 명령을 사용하는 것을 권장한다.

선형 연립방정식과 선형 예측모형#

선형 예측모형의 가중치벡터를 구하는 문제는 선형 연립방정식을 푸는 것과 같다. 예를 들어 \(N\)개의 입력차원을 가지는 특징벡터 \(N\)개를 입력 데이터로 이용하고 이 입력에 대응하는 목푯값벡터를 출력하는 선형 예측모형을 생각하자.

\[\begin{split} \begin{align} \begin{matrix} x_{11} w_1 & + \;& x_{12} w_2 &\; + \cdots + \;& x_{1N} w_N &\; = \;& y_1 \\ x_{21} w_1 & + \;& x_{22} w_2 &\; + \cdots + \;& x_{2N} w_N &\; = \;& y_2 \\ \vdots\;\;\; & & \vdots\;\;\; & & \vdots\;\;\; & & \;\vdots \\ x_{N1} w_1 & + \;& x_{N2} w_2 &\; + \cdots + \;& x_{NN} w_N &\; = \;& y_N \\ \end{matrix} \tag{2.4.30} \end{align} \end{split}\]

즉,

\[ \begin{align} Xw = y \tag{2.4.31} \end{align} \]

이 예측 모형의 가중치벡터 \(w\)를 찾는 것은 계수행렬이 \(X\), 미지수벡터가 \(w\), 상수벡터가 \(y\)인 선형 연립방정식의 답을 찾는 것과 같다. 그리고 만약 계수행렬, 여기에서는 특징행렬 \(X\)의 역행렬 \(X^{-1}\)이 존재하면 다음처럼 가중치벡터를 구할 수 있다.

\[ \begin{align} w = X^{-1} y \tag{2.4.32} \end{align} \]

연습 문제 2.4.5#

보스턴 집값 문제는 미국 보스턴내 각 지역(town)의 주택 가격을 그 지역의 범죄율이나 공기 오염도 등의 특징을 사용하여 예측하는 문제다. Scikit-Learn 패키지에서 임포트할 수 있다. 보스턴 집값 문제를 선형 예측모형 \(Ax=\hat{b}\)로 풀었을 때의 가중치 벡터 \(x\)를 구하라. 행렬과 벡터 데이터는 다음과 같이 얻을 수 있다. 여기에서는 문제를 간단하게 하기 위해 입력 데이터를 범죄율(CRIM), 공기 오염도(NOX), 방의 개수(RM), 오래된 정도(AGE)의 4종류로 제한했고 데이터도 4개만 사용했다.

from sklearn.datasets import load_boston
boston = load_boston()
X = boston.data
y = boston.target
A = X[:4, [0, 4, 5, 6]]  # 'CRIM', 'NOX', 'RM', 'AGE'
b = y[:4]

이렇게 구한 가중치의 크기나 부호가 우리의 직관이나 경험과 일치하는지 살펴보라.

미지수의 수와 방정식의 수#

지금까지는 미지수의 수와 방정식의 수가 같은 선형 연립방정식에 대해서만 생각했다. 그런데 만약 미지수의 수와 방정식의 수가 다르다면 어떻게 해야 할까?

미지수의 수와 방정식의 수를 고려해 볼 때 연립방정식에는 다음과 같은 세 종류가 있을 수 있다.

  1. 방정식의 수가 미지수의 수와 같다. (\(N = M\))

  2. 방정식의 수가 미지수의 수보다 적다. (\(N < M\))

  3. 방정식의 수가 미지수의 수보다 많다. (\(N > M\))

1번의 경우, 즉 방정식의 수가 미지수의 수와 같은 경우는 앞에서 다루었다.

2번의 경우, 즉 방정식의 수가 미지수의 수보다 적을 때는 무수히 많은 해가 존재할 수 있다. 예를 들어 다음 선형 연립방정식을 생각해보자. 미지수는 3개지만 방정식은 2개뿐이다.

\[\begin{split} \begin{align} \begin{matrix} x_1 & + & x_2 & & & = & 2 \\ & & x_2 & + & x_3 & = & 2 \\ \end{matrix} \tag{2.4.33} \end{align} \end{split}\]

이때는 \(x_2\)가 어떤 값이 되더라도 \(x_1 = x_3 = 2 - x_2\)만 만족하면 되므로 무한히 많은 해가 존재한다. 예들 들어 다음 \(x\) 벡터는 모두 위 선형 연립방정식의 해다.

\[\begin{split} \begin{align} x = \begin{bmatrix} 2 \\ 0 \\ 2 \end{bmatrix} ,\;\; x = \begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} ,\;\; x = \begin{bmatrix} 0 \\ 2 \\ 0 \end{bmatrix} ,\;\; \cdots \tag{2.4.34} \end{align} \end{split}\]

3번의 경우, 즉 방정식의 수가 미지수의 수보다 많을 때는 2번과 반대로 모든 조건을 만족하는 해가 하나도 존재할 수 없을 수 있다. 예를 들어 다음 선형 연립방정식을 생각해보자. 미지수는 3개지만 방정식은 4개다.

\[\begin{split} \begin{align} \begin{matrix} x_1 & + & x_2 & & & = & 2 \\ & & x_2 & + & x_3 & = & 2 \\ x_1 & + & x_2 & + & x_3 & = & 3 \\ x_1 & + & x_2 & + & 2x_3 & = & 5 \\ \end{matrix} \tag{2.4.35} \end{align} \end{split}\]

위의 3개 방정식을 동시에 만족하는 해는 \(x_1 = x_2 = x_3 = 1\)인데 이 값은 4번째 방정식을 만족하지 못한다.

\[ \begin{align} x_1 + x_2 + 2x_3 = 4 \tag{2.4.36} \end{align} \]

따라서 4개의 방정식을 모두 만족하는 해는 존재하지 않는다.

선형 예측모형을 구하는 문제는 계수행렬이 특징행렬 \(X\), 미지수벡터가 가중치벡터 \(w\)인 선형 연립방정식 문제이다. 그런데 보통 데이터의 수는 입력차원보다 큰 경우가 많다. 예를 들어 면적, 층수, 한강이 보이는지의 여부로 집값을 결정하는 모형을 만들기 위해서 딱 3가구의 아파트 가격만 조사하는 경우는 없을 것이다. 보통은 10 가구 혹은 100 가구의 아파트 가격을 수집하여 이용하는 것이 일반적이다. 다시 말해 선형 예측모형을 구할 때는 3번과 같은 경우가 많다는 것을 알 수 있다.

이때는 선형 연립방정식의 해가 존재하지 않으므로 선형 연립방정식을 푸는 방식으로는 선형 예측모형의 가중치벡터를 구할 수 없다.

최소자승문제#

이렇게 선형 연립방정식의 해가 존재하지 않는다면 선형 예측모형은 어떻게 구할까? 모형을 구하는 것을 포기해야 하는가? 그럴 필요는 없다. 이 문제에 대한 힌트를 얻기 위해 다음과 같은 선형 연립방정식을 생각해보자.

\[\begin{split} \begin{align} \begin{matrix} x_1 & + & x_2 & & & = & 2 \\ & & x_2 & + & x_3 & = & 2 \\ x_1 & + & x_2 & + & x_3 & = & 3 \\ x_1 & + & x_2 & + & 2x_3 & = & 4.1 \\ \end{matrix} \tag{2.4.37} \end{align} \end{split}\]

위에서 보았듯이 이 선형 연립방정식의 해는 존재하지 않는다.

하지만 꼭 양변이 정확하게 똑같지 않아도 된다면 어떨까? \(x_1 = x_2 = x_3 = 1\)를 위 방정식에 대입하면 결과는 다음과 같다.

\[\begin{split} \begin{align} \begin{matrix} x_1 & + & x_2 & & & = & 2 & &\\ & & x_2 & + & x_3 & = & 2 & &\\ x_1 & + & x_2 & + & x_3 & = & 3 & &\\ x_1 & + & x_2 & + & 2x_3 & = & 4 & \approx & 4.1 \end{matrix} \tag{2.4.38} \end{align} \end{split}\]

선형 예측모형에서 좌변을 예측값, 우변을 목푯값이라고 생각한다면 100% 정확히 예측하지는 못했지만 상당히 비슷하게 예측한 값이라고 할 수 있다.

따라서 미지수의 개수보다 방정식의 개수가 많아서 선형 연립방정식으로 풀수 없는 문제는 좌변과 우변의 차이를 최소화하는 문제로 바꾸어 풀 수 있다. 앞서 예측값과 목푯값의 차이를 잔차(residual)라고 한다고 했다.

\[ \begin{align} e = Ax - b \tag{2.4.39} \end{align} \]

잔차는 벡터이므로 최소자승문제에서는 벡터의 크기 중에서 벡터의 놈(norm)을 최소화하는 문제를 푼다. 앞 절에서 놈을 최소화하는 것은 놈의 제곱을 최소화하는 것과 같다고 했다. 여기에서는 잔차제곱합이 놈의 제곱이 된다.

\[ \begin{align} e^Te = \Vert e \Vert^2 = (Ax-b)^T(Ax-b) \tag{2.4.40} \end{align} \]

이 값을 최소화하는 \(x\)값은 수식으로 다음처럼 표현한다.

\[ \begin{align} x = \text{arg} \min_x e^Te = \text{arg} \min_x \; (Ax-b)^T(Ax-b) \tag{2.4.41} \end{align} \]

위 식에서 \(\text{arg} \min_x f(x)\)는 함수 \(f(x)\)를 가장 작게 만드는 \(x\)값을 의미한다. 이러한 문제를 **최소자승문제(least square problem)**라고 한다.

\(A^TA\)가 항상 정방 행렬이 된다는 점을 이용하여 다음과 같이 최소 자승 문제의 답이 어떤 형태가 되는지 살펴보자. 여기에서는 답의 형태만 살펴보고 엄밀한 증명은 하지 않을 것이다.

\[ \begin{align} Ax \approx b \tag{2.4.42} \end{align} \]

이 식의 양변에 \(A^T\)를 곱하면 각각 \(A^TAx\)\(A^Tb\) 가 된다. 이 두 개의 벡터의 값이 같다고 일단 가정하자.

\[ \begin{align} A^TAx = A^Tb \tag{2.4.43} \end{align} \]

만약 정방 행렬 \(A^TA\)의 역행렬 \((A^TA)^{-1}\)이 존재한다면

\[ \begin{align} (A^TA)^{-1}(A^TA)x = (A^TA)^{-1}A^Tb \tag{2.4.44} \end{align} \]

이 식을 정리하면 다음과 같다.

\[ \begin{align} x = ((A^TA)^{-1}A^T) b \tag{2.4.45} \end{align} \]

위에서 보인 것은 수학적 증명이라고 할 수 없지만 엄밀한 수학적 증명을 통해 최소자승문제의 해를 구해도 위와 같은 결과를 얻을 수 있다. 자세한 내용은 행렬의 미분과 최적화를 공부한 뒤에 다루도록 한다.

여기에서 행렬 \((A^TA)^{-1}A^T\) 를 행렬 \(A\)의 **의사역행렬(pseudo inverse)**이라고 하며 다음처럼 \(A^{+}\) 로 표기한다.

\[ \begin{align} A^{+} = (A^TA)^{-1}A^T \tag{2.4.46} \end{align} \]
\[ \begin{align} x = A^+ b \tag{2.4.47} \end{align} \]

넘파이의 lstsq() 명령은 사실 이러한 최소자승문제를 푸는 명령이다.

위에서 예로 든 선형 연립방정식을 넘파이를 사용하여 풀어보자.

A = np.array([[1, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 2]])
A
array([[1, 1, 0],
       [0, 1, 1],
       [1, 1, 1],
       [1, 1, 2]])
b = np.array([[2], [2], [3], [4.1]])
b
array([[2. ],
       [2. ],
       [3. ],
       [4.1]])

우선 의사역행렬을 직접 계산하여 해를 구해보자.

Apinv = np.linalg.inv(A.T @ A) @ A.T
Apinv
array([[ 0.33333333, -1.        ,  0.33333333,  0.33333333],
       [ 0.5       ,  1.        ,  0.        , -0.5       ],
       [-0.5       ,  0.        ,  0.        ,  0.5       ]])
x = Apinv @ b
x
array([[1.03333333],
       [0.95      ],
       [1.05      ]])

이 해를 이용하여 b값을 구하면 다음처럼 우변과 소수점 아래 한자리 오차내에 있는 것을 볼 수 있다.

A @ x
array([[1.98333333],
       [2.        ],
       [3.03333333],
       [4.08333333]])

lstsq() 명령으로 바로 구해도 같은 값이 나온다.

x, resid, rank, s = np.linalg.lstsq(A, b)
x
array([[1.03333333],
       [0.95      ],
       [1.05      ]])

위 코드에서 resid는 잔차벡터의 \(e=Ax-b\)의 제곱합, 즉 놈의 제곱이다.

resid, np.linalg.norm(A @ x - b) ** 2
(array([0.00166667]), 0.001666666666666655)

연습 문제 2.4.6#

보스턴 집값 문제를 선형 예측모형 \(Xw=\hat{y}\)로 풀었을 때의 가중치벡터 \(w\)를 최소 자승 방법으로 구하라. 행렬과 벡터 데이터는 다음과 같이 얻을 수 있다.

from sklearn.datasets import load_boston
boston = load_boston()
X = boston.data
y = boston.target

행렬 X의 각 열이 의미하는 바는 다음과 같다.

  1. CRIM: 범죄율

  2. INDUS: 비소매상업지역 면적 비율

  3. NOX: 일산화질소 농도

  4. RM: 주택당 방 수

  5. LSTAT: 인구 중 하위 계층 비율

  6. B: 인구 중 흑인 비율

  7. PTRATIO: 학생/교사 비율

  8. ZN: 25,000 평방피트를 초과 거주지역 비율

  9. CHAS: 찰스강의 경계에 위치한 경우는 1, 아니면 0

  10. AGE: 1940년 이전에 건축된 주택의 비율

  11. RAD: 방사형 고속도로까지의 거리

  12. DIS: 보스톤 직업 센터 5곳까지의 가중평균거리

  13. TAX: 재산세율

이렇게 구한 가중치 벡터의 각 원소의 부호가 우리의 직관이나 경험과 일치하는지 살펴보라. 또 연습문제 2.4.5에서 구한 값과 어떻게 달라지는지 살펴보라.