[AITech] 20220119 - Vector&Matrix Basics

2 minute read


강의 복습 내용

벡터

  • 벡터는 숫자를 원소로 가지는 리스트 또는 배열이다.

    • 벡터의 차원은 벡터가 가진 원소의 개수이다.
  • 벡터는 n차원 공간에서 한 점을 나타낸다.
    • 벡터에 숫자를 곱해주면 길이만 변한다. (스칼라곱)
    • 벡터는 같은 모양을 가지면 덧셈, 뺄셈, 성분곱(Hadamard product)을 계산할 수 있다.
      • 벡터 덧셈은 다른 벡터로부터 상대적 위치 이동을 표현합니다.
      • 벡터 뺄셈은 벡터의 방향을 뒤집은 덧셈입니다.
    import numpy as np
      
    x = np.array([1,7,2])
    y = np.array([5,2,1])
      
    # 벡터 덧셈
    print(x+y)
    # 벡터 뺄셈
    print(x-y)
    # 벡터 내적
    print(x*y)
    '''
    [6 9 3]
    [-4  5  1]
    [ 5 14  2]
    '''
    
  • 벡터의 노름원점에서부터의 거리를 말합니다.

    노름(norm)

    def l1_norm(x):
        x_norm = np.abs(x)
        x_norm = np.sum(x_norm)
        return x_norm
      
    def l2_norm(x):
        x_norm = x*x
        x_norm = np.sum(x_norm)
        x_norm = np.sqrt(x_norm)
        return x_norm
      
    x = np.array([1,2,3])
    print(f"l1 norm: {l1_norm(x)}")
    print(f"l2 norm: {l2_norm(x)}")
    '''
    l1 norm: 6
    l2 norm: 3.7416573867739413
    '''
    
  • 서로 다른 노름이 중요한 이유

    • 노름의 종류에 따라 기하학적 성질이 달라진다.
    • 머신러닝에선 각 성질들이 필요할 대가 있으므로 둘 다 사용한다.

    image-20220119112430894

    • L1, L2 노름을 이용해 두 벡터 사이의 거리를 계산할 수 있다.
    • L2 노름을 이용해 두 벡터 사이 각도를 계산할 수 있다.
    def angle(x,y):
        v = np.inner(x,y) / (l2_norm(x)*l2_norm(y))
        theta = np.arccos(v)
        return theta # Pi 기준 표시
      
    x, y = np.array([1,10,3]), np.array([-1,-10,-3])
    print(angle(x,y))
    # 3.141592653589793
    
  • 내적정사영된 벡터의 길이와 관련 있다.

    • 내적은 두 벡터의 유사도를 측정하는 데 사용 가능하다.

    image-20220119113026170


행렬

  • 행렬은 벡터를 원소로 가지는 2차원 배열이다.

    • 행렬은 이라는 인덱스를 가진다.

    image-20220119113221006

    • 전치 행렬은 행과 열의 인덱스가 바뀐 행렬이다.

    image-20220119113259537

    • 행렬끼리 같은 모양을 가지면 덧셈, 뺄셈, 성분곱, 스칼라곱을 계산할 수 있다.
    • 행렬 곱셈i번째 행벡터와 j번재 열벡터 사이의 내적을 계산하고, 행렬 내적i번째 행벡터와 j번째 행벡터 사이의 내적(XYT을 계산한다.
      • 수학에서 말하는 내적과는 다르므로 주의!
    X = np.array([[1,-2,3],
                  [7,5,0],
                  [-2,-1,2]])
    Y = np.array([[0,1,10],
                  [1,-1,7],
                  [-2,1,0]])
      
    # 행렬곱
    print(X @ Y)
    # 행렬 내적
    print(np.inner(X,Y)) # = X @ Y.T
    '''
    [[ -8   6  -4]
     [  5   2 105]
     [ -5   1 -27]]
    [[28 24 -4]
     [ 5  2 -9]
     [19 13  3]]
    '''
    
  • 행렬을 이해하는 방법 1

    • 벡터가 공간에서 한 점을 나타낸다면, 행렬을 여러 점들을 나타낸다.
    • 행렬의 행벡터 xi는 i번째 데이터를 의미한다.
    • 행렬의 xij는 i번째 데이터의 j번째 변수의 값을 말한다.
  • 행렬을 이해하는 방법 2

    • 행렬은 벡터 공간에서 사용되는 연산자로 이해한다.
    • 행렬 곱을 통해 벡터를 다른 차원의 공간으로 보낼 수 있다.
    • 행렬 곱을 통해 패턴을 추출할 수도 있고, 데이터를 압축할 수도 있다.
      • 모든 선형변환은 행렬곱으로 계산할 수 있다!

    image-20220119114208634

    • 역행렬 이해하기

      • 어떤 행렬 A의 연산을 거꾸로 되돌리는 행렬을 역행렬이라 부르고 A-1라 표기한다. (AA-1 = A-1A = I)

        image-20220119114654455

        image-20220119114636254

      • 역행렬은 행과 열 숫자가 같고 행렬식이 0이 아닌 경우에만 계산할 수 있다.

      • 만일 역행렬을 계산할 수 없다면 유사 역행렬 또는 무어-펜로즈 역행렬 A+을 이용한다.

        image-20220119114552134

        image-20220119114535231

      X = np.array([[1,-2,3],
                    [7,5,0],
                    [-2,-1,2]])
          
      # 역행렬
      print(np.linalg.inv(X))
      print(X @ np.linalg.inv(X))
      # 유사 역행렬
      print(np.linalg.pinv(X))
      print(X @ np.linalg.pinv(X))
      '''
      [[ 0.21276596  0.0212766  -0.31914894]
       [-0.29787234  0.17021277  0.44680851]
       [ 0.06382979  0.10638298  0.40425532]]
      [[ 1.00000000e+00 -1.38777878e-17  0.00000000e+00]
       [-2.22044605e-16  1.00000000e+00 -5.55111512e-17]
       [-2.77555756e-17  0.00000000e+00  1.00000000e+00]]
      [[ 0.21276596  0.0212766  -0.31914894]
       [-0.29787234  0.17021277  0.44680851]
       [ 0.06382979  0.10638298  0.40425532]]
      [[ 1.00000000e+00 -2.08166817e-16  5.55111512e-16]
       [-1.66533454e-16  1.00000000e+00  3.33066907e-16]
       [ 1.66533454e-16  8.32667268e-17  1.00000000e+00]]
      '''
      

응용

  • 연립 방정식 풀기

    • np.linalg.pinv를 이용하면 연립방정식의 해를 구할 수 있다.

    image-20220119115006710

    • np.linalg.pinv를 이용하면 데이터를 선형 모델로 해석하는 선형 회귀식을 찾을 수 있다.

    image-20220119115141877

    # Scikit Learn을 활용한 회귀분석
    from sklearn.linear_model import LinearRegression
    model = LinearRegression()
    model.fit(X, y)
    y_test = model.predict(x_test)
      
    # Moore-Penrose 역행렬
    X_ = np.array([np.append(x,[1]) for x in X])
    beta = np.linalg.pinv(X_) @ y
    t_test = np.append(x,[1]) @ beta
    


Leave a comment