by Yngie

행렬(Matrix)의 성질

|

이번 게시물은 한양대 이상화 교수님의 선형대수 강의를 바탕으로 작성되었습니다.

Matrix

위키피디아에 따르면 행렬(Matrix)이란 “수 또는 다항식 등을 직사각형 모양으로 배열한 것”입니다. 직사각형 모양으로 표현하고 있기에 가로줄을 행(Row)이라고 하며, 세로줄을 열(Column)이라고 합니다. 그리고 $m$개의 행, $n$개의 열을 가지고 있는 행렬 $A$를 $A_{m \times n}$ 으로 나타낼 수 있습니다.

Matrix Add & Substract

행렬은 스칼라와 다른 여러가지 성질을 가지고 있습니다. 첫 번째는 행렬의 덧셈과 뺄셈입니다. 크기가 같은 행렬끼리만 더하고 뺄 수 있습니다. 아래 식에서 첫 번째는 더할 수 있으며 두 번째는 불가능한 경우입니다.

[\begin{aligned} \left[\begin{array}{ccc} 1 & 2 & 3 \ 4 & 5 & 6 \end{array}\right] + \left[\begin{array}{ccc} 2 & 3 & 4 \ 9 & 7 & 5 \end{array}\right] &= \left[\begin{array}{ccc} 3 & 5 & 7 \ 13 & 12 & 11 \end{array}\right]
\left[\begin{array}{ccc} 1 & 2 \ 4 & 5 \end{array}\right] + \left[\begin{array}{ccc} 2 & 3 & 4 \ 9 & 7 & 5 \end{array}\right] & \end{aligned}]

첫 번째 식에 있는 행렬은 모두 $2 \times 3$ 크기의 행렬입니다. 그렇기 때문에 덧셈과 뺄셈이 가능하며 동일한 위치에 있는 원소끼리 더하거나 빼줍니다. 두 번째 식에 있는 행렬 중 앞에 있는 행렬의 크기는 $2 \times 2$ 이고 뒤에 있는 행렬의 크기는 $2 \times 3$ 입니다. 그렇기 때문에 서로 더하거나 빼줄 수 없습니다.

Commutative Property & Associated Law

행렬의 덧셈이나 뺄셈이 가능한 경우에는 교환법칙이 성립합니다. 위에서 사용했던 예를 다시 들어보겠습니다. 행렬의 덧셈 순서가 바뀌더라도 결과가 같은 것을 볼 수 있습니다.

[\begin{aligned} \left[\begin{array}{ccc} 1 & 2 & 3 \ 4 & 5 & 6 \end{array}\right] + \left[\begin{array}{ccc} 2 & 3 & 4 \ 9 & 7 & 5 \end{array}\right] &= \left[\begin{array}{ccc} 3 & 5 & 7 \ 13 & 12 & 11 \end{array}\right]
\left[\begin{array}{ccc} 2 & 3 & 4 \ 9 & 7 & 5 \end{array}\right] + \left[\begin{array}{ccc} 1 & 2 & 3 \ 4 & 5 & 6 \end{array}\right] &= \left[\begin{array}{ccc} 3 & 5 & 7 \ 13 & 12 & 11 \end{array}\right] \end{aligned}]

행렬의 덧셈과 뺄셈 연산은 결합법칙도 성립합니다. 행렬의 교환법칙 성립과 결합법칙 성립을 일반화하여 수식으로 아래와 같이 쓸 수 있습니다.

[A \pm B = B \pm A
A \pm (B \pm C) = (A \pm B) \pm C]

Matrix Multiply

두 번째는 행렬의 곱셈입니다. 행렬의 의 곱셈은 특이한 조건을 만족해야 합니다. 앞쪽에 위치한 행렬의 열의 개수와 뒤쪽에 위치한 행렬의 행의 개수가 동일해야 합니다. 예를 들어, 조건을 만족하는 두 행렬 $A,B$의 크기는 다음과 같습니다.

[A_{m \times n} B_{n \times l} = (AB)_{m \times l}]

예시로는 다음과 같은 것들이 있습니다.

[\left[\begin{array}{ccc} 1 & 2 & 3 \ 4 & 5 & 6 \end{array}\right] \left[\begin{array}{cc} 2 & 3 \ 1 & 2 \ 0 & 1 \end{array}\right] = \left[\begin{array}{ccc} 4 & 10 \ 13 & 28 \end{array}\right]]

$2 \times 3$ 행렬과 $3 \times 2$ 행렬을 곱해서 $2 \times 2$ 행렬이 나오는 것을 볼 수 있습니다. 위 두 행렬의 순서를 바꿔서 해보겠습니다.

[\left[\begin{array}{cc} 2 & 3 \ 1 & 2 \ 0 & 1 \end{array}\right] \left[\begin{array}{ccc} 1 & 2 & 3 \ 4 & 5 & 6 \end{array}\right] = \left[\begin{array}{ccc} 14 & 19 & 24 \ 9 & 12 & 15 \ 4 & 5 & 6 \end{array}\right]]

$3 \times 2$ 행렬과 $2 \times 3$ 행렬을 곱해서 $3 \times 3$ 행렬이 나오는 것을 볼 수 있습니다. 이 경우에는 두 행렬의 순서를 바꾸어도 곱셈이 가능했지만 그렇지 않은 경우도 있습니다. 다음 두 행렬의 예시를 보겠습니다.

[\begin{aligned} \left[\begin{array}{ccc} 1 & 2 & 3 \end{array}\right] \left[\begin{array}{cc} 2 & 3 \ 1 & 2 \ 0 & 1 \end{array}\right] &= \left[\begin{array}{cc} 4 & 10 \end{array}\right]
\left[\begin{array}{cc} 2 & 3 \ 1 & 2 \ 0 & 1 \end{array}\right] \left[\begin{array}{ccc} 1 & 2 & 3 \end{array}\right] &= \end{aligned}]

위 두 식 중에서 첫 번째 식은 $1 \times 3$ 행렬과 $3 \times 2$ 행렬을 곱하였으므로 $1 \times 2$행렬이 나오는 것을 볼 수 있습니다. 하지만 순서를 바꿔 $3 \times 2$ 행렬과 $1 \times 3$ 행렬을 곱하면 앞쪽 행렬의 열 개수와 뒤쪽 행렬의 행 개수가 같지 않으므로 곱할 수 없습니다.

Commutative Property & Associated Law

위에서 본 것처럼 행렬의 곱셈은 교환법칙이 성립하지 않습니다. 이를 일반화하여 수식으로 나타내면 아래와 같습니다.

[AB \neq BA]

바로 위의 예시와 같이 순서를 바꾸었을 때 곱셈이 불가능하거나, 결과로 나오는 행렬의 크기가 다른 경우가 일반적입니다. 게다가 결과로 나오는 행렬의 크기가 같더라도 요소의 값이 같지 않은 경우가 일반적입니다. 서로 다른 두 $2 \times 2$ 행렬의 순서를 바꾸어 곱하는 예시를 보도록 하겠습니다.

[\left[\begin{array}{cc} 1 & 2 \ 4 & 5 \end{array}\right] \left[\begin{array}{cc} 1 & 2 \ 0 & 1 \end{array}\right] = \left[\begin{array}{cc} 1 & 4 \ 4 & 13 \end{array}\right]
\left[\begin{array}{cc} 1 & 2 \ 0 & 1 \end{array}\right] \left[\begin{array}{cc} 1 & 2 \ 4 & 5 \end{array}\right] = \left[\begin{array}{cc} 9 & 12 \ 4 & 5 \end{array}\right]]

$2 \times 2$ 처럼 행과 열의 개수가 같은 행렬을 정방행렬(Square matrix)이라고 합니다. 두 정방행렬을 곱하는 경우는 순서를 바꾸어도 결과로 도출되는 행렬의 크기가 동일합니다. 하지만 결과로 나오는 행렬의 요소는 서로 같지 않은 것을 볼 수 있습니다.

반면 결합법칙은 일반적으로 성립합니다. 이를 수힉으로 나타내면 다음과 같습니다.

[A(BC) = (AB)C]

Identity Matrix

[\left[\begin{array}{c} 1 \end{array}\right] \qquad \left[\begin{array}{cc} 1 & 0 \ 0 & 1 \end{array}\right] \qquad \left[\begin{array}{ccc} 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 \end{array}\right]]

위처럼 왼쪽 위부터 오른쪽 아래까지의 대각 성분(Diagonal elements)이 모두 $1$이고 나머지 성분은 모두 $0$인 행렬을 단위 행렬(Identity matrix)이라고 합니다. 단위 행렬은 크기가 동일한 정방 행렬 곱셈의 항등원(Identity Element)입니다. 즉, 아래와 같은 수식을 만족합니다.

[AI = IA = A]

단위 행렬에 대해서는 곱셈의 교환법칙이 성립하며 그 결과는 항상 곱한 정방행렬 자기 자신이 나오는 것을 알 수 있습니다.

Inverse Matrix

행렬 $A$에 특정한 행렬을 곱했을 때 결과로 나오는 행렬이 단위 행렬 $I$라면 특정한 행렬은 행렬 $A$의 곱셈에 대한 역원이며, 이 행렬을 $A$의 역행렬(Inverse matrix, $A^{-1}$)이라고 합니다. 이 과정을 수식으로 나타내면 아래와 같습니다.

[AA^{-1} = I \quad \text{or} \quad A^{-1}A = I]

행렬 $A$가 역행렬이 존재하는 정방 행렬인 경우에는 $AA^{-1} =A^{-1}A = I$ 도 성립합니다. 하지만 정방 행렬이 아닐 경우에는 왼쪽에서 곱했을 때의 역행렬(Left inverse matrix)과 오른쪽에서 곱했을 때의 역행렬(Right inverse matrix)가 다릅니다.

역행렬은 다음과 같은 성질을 만족합니다. 먼저 특정한 두 행렬을 곱한 행렬의 역행렬은 각 행렬의 역행렬을 순서를 바꾸어 곱한 것과 같습니다. 말로는 헷갈리니 수식으로 알아보겠습니다. 아래 수식에서 위에서 알아보았던 곱셈의 결합법칙이 사용됩니다.

[(AB)^{-1} = B^{-1}A^{-1}
\begin{aligned} \because AB(AB)^{-1} &= ABB^{-1}A^{-1} \ &= A(BB^{-1})A^{-1} \ &= AA^{-1} \ &= I \end{aligned}]

특정 행렬에 스칼라 $k$ 를 곱해준 행렬의 역행렬은 어떻게 될까요? 스칼라 값의 $k$ 의 곱셈에 대한 역원은 $\frac{1}{k}$ 이므로 아래의 수식을 만족합니다.

[(kA)^{-1} = \frac{1}{k}A^{-1}]

Transpose Matrix

행렬 $A$의 $i$번째 행, $j$번째 열의 성분을 $a_{ij}$ 라고 할 때, 열과 행이 바뀌는 것을 전치 행렬(Transpose matrix)이라고 합니다. 전치 행렬은 $A^T$로 나타내며 수식으로는 아래와 같이 나타낼 수 있습니다.

[A^T \quad (a_{ij} \rightarrow a_{ji})]

아래는 행렬을 전치(Transpose)한 결과입니다. 각 행렬의 행의 성분이 전치 행렬의 열의 성분이 된 것을 볼 수 있습니다.

[\left[\begin{array}{cc} 2 & 3 \ 1 & 2 \ 0 & 1 \end{array}\right] \xrightarrow{\text{Transpose}} \left[\begin{array}{cc} 2 & 1 & 0 \ 3 & 2 & 1 \end{array}\right]]

전치 행렬은 덧셈에 대한 분배법칙이 성립하며, 역행렬에서와 같이 두 행렬의 곱연산의 결과로 나오는 행렬을 전치하면 각 행렬의 전치 행렬을 순서를 바꾸어 곱해준 것과 같습니다. 두 성질을 식으로 나타내면 아래와 같습니다.

[(A \pm B)^T = A^T \pm B^T
(AB)^T = B^TA^T]

또한 특정 행렬 $A$의 역행렬을 전치한 행렬은 전치한 행렬의 역행렬과 같은 행렬이 됩니다. 이를 수식으로 나타내면 아래와 같습니다.

[(A^{-1})^T = (A^T)^{-1}]

Comment  Read more

Pandas Basic

|

아래 내용은 파이썬 머신러닝 완벽 가이드 (권철민, 위키북스, 2019)를 참조하여 작성하였습니다. 아래에 존재하는 ‘col1’, ‘col2’ … 등은 가상의 이름입니다. 본인의 데이터에 맞게 변형하시면 됩니다.

Pandas Basic

  • Pandas 모듈 임포트하기
import pandas as pd
  • DataFrame 생성하기, 외부파일 읽어오기 : .read_csv()
df = pd.read_csv("file_name.csv")
  • .head(), .tail(), .shape(), .describe(), .value_counts()
df.head()	# .head(), .tail()은 각각 DataFrame의 맨 윗부분, 맨 아랫부분을 출력한다. default == 5
df.tail(3)
df.shape	# DataFrame의 모양 표현 (row의 수, column의 수)가 출력된다.
df.describe()	# DataFrame에 대한 대략적인 정보를 출력한다. [R의 str(), dplyr::glimpse()와 유사]
df.value_counts()	# column 내부에 어떤 value가 몇 개 있는지를 출력해준다.
  • Column Data set 생성, 수정, 삭제

    • 생성과 수정
    df['new_colname1'] = 0
    df['new_colname2'] = df['col1'] + df['col2'] * 10
    
    • 삭제
    df.drop('col1', axis=1)
    #axis=0 : 행을 삭제, axis=1 : 열을 삭제
    #inplace=True : 원본 데이터를 변형, inplace=False : 원본 데이터는 변형 없이 column이 drop된 DataFrame으로 새로운 객체 생성
    
    • Index 객체
    index_arr = df.index	#Index 객체를 추출한다.
    index_arr.values	#ndarray 형태로 반환한다.
    
  • 데이터 셀렉션 및 필터링

    • [] 연산자
    #[] 내부에는 column 이름 혹은 표현식이 들어가야 한다.
    df['col2']
    df[0:3]
    
    • iloc[] 연산자 : Row와 Column의 index순서(숫자)로 추출하기
    df.iloc[0, 1]	#df[row_index, col_index]
    
    • loc[] 연산자 : Row의 index value와 Column의 이름으로 추출하기
    df.loc[1,'col2']	#df['index_value', 'colname']
    df2.loc['a', 'col3']	#df2의 index가 'a','b','c' ... 일 때
    
    • 불린 인덱싱
    df_boolean = df[df['col1'] > 5]
    df[df['col1'] > 5][['col1','col2']]
    
  • 정렬, 결손 데이터 처리하기

    • .sort_values()
    df.sort_values(by=['col1'])	#디폴트 값은 ascending = True.
    df.sort_values(by=['col1', 'col2'], ascending=False)
    
    • .isna()
    df.isna()	#NaN 값을 True, 아닌 값을 False로 불린 인덱싱
    df.isna().sum()	#각 column에 있는 True의 개수(NaN값의 개수) 반환
    
    • .fillna()
    df['col4'] = titanic_df['col4'].fillna('val1')
    #col4에 있는 NaN 값을 val로 대체
    #이후 df['col4'].isna().sum() 실행시 0이 나오게 된다. 
    
  • apply lambda 식으로 데이터 가공

    • lambda 함수 만들기
    def get_sqr(num):
        return num ** 2		#인 함수를 lambda 함수로 바꾸면
      
    lambda_sqr = lambda x:x ** 2	#가 된다.
    
    • map() 함수와의 결합
    list_a = [1, 2, 3]
    squares = map(lambda x : x ** 2, list_a)
    list(squares)
    > [1, 4, 9]
    
    • Pandas 에서 apply()로 lambda 결합하기
    df['new_col1'] = df['col1'].apply(lambda x : len(x))
    df[['col1', 'new_col1']]
      
    df['new_col2'] = df['col2'].apply(lambda x : 'val2' if x < 10 else 'val3')
    df[['col2'], ['new_col2']]
    

Comment  Read more

Start :)

|

설 연휴를 맞이하야 드디어 github blog를 개설했다. 평소 자주 참고하던 ratsgo님의 블로그 가 마음에 들어 메일을 보낸 후 포크했다. 다시 한번 감사의 말씀을 전하고 싶다. 테마 컬러는 2020년 pantone컬러인 Classic Blue를 사용했다.
HTML을 배우긴 했으나 아직 익숙하지 못하다 보니 이거저거 바꾸는데 적지 않은 시간이 걸렸다. disqus를 이용한 댓글 기능 등은 차차 보강해나갈 예정. 내용은 additor에 있는 내용을 보완하여 통계부터 차차 채워나갈 생각이다.

Comment  Read more