ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 넘파이(Numpy)
    프로그래밍/Python 2020. 11. 23. 16:43

    넘파이

    ※ 라이브러리 사용법

    import numpy 
    
    A = numpy.array([1, 2])
    
    print("A == ", A, ", type == ", type(A))
    # 결과
    A ==  [1 2] , type ==  <class 'numpy.ndarray'>
    import numpy as np
    
    A = np.array([1, 2])
    
    print("A == ", A, ", type == ", type(A))
    # 결과
    A ==  [1 2] , type ==  <class 'numpy.ndarray'>
    from numpy import exp
    
    result = exp(1)
    
    print("result == ", result, ", type == ", type(result))
    # 결과
    result ==  2.718281828459045 , type ==  <class 'numpy.float64'>
    from numpy import *
    
    result = exp(1) + log(1.7) + sqrt(2)
    
    print("result == ", result, ", type == ", type(result))
    # 결과
    result ==  4.663123641894311 , type ==  <class 'numpy.float64'>

    넘파이(Numpy)

    vector / matrix 생성

    • numpy는 머신러닝 코드 개발할 경우 자주 사용되는 벡터, 행렬 등을 표현하고 연산할 때 반드시 필요한 라이브러리
    • 머신러닝에서는 숫자, 사람, 동물 등의 인식을 하기 위해서는 이미지(image) 데이터를 행렬(matrix)로 변환하는 것이 중요
    • 행렬을 나타내기 위해서 리스트를 사용할 수도 있지만, 행렬 연산이 직관적이지 않고, 오류 가능성이 높기 때문에 행렬 연산을 위해서 numpy 사용이 필수!
    # numpy vs list
    
    import numpy as np
    
    # list
    
    A = [[1, 0], [0, 1]]
    B = [[1, 1], [1, 1]]
    
    print(A + B)
    
    # numpy
    
    A = np.array([[1, 0], [0, 1]])
    B = np.array([[1, 1], [1, 1]])
    
    print(A + B)
    # 결과
    [[1, 0], [0, 1], [1, 1], [1, 1]]
    [[2 1]
     [1 2]]

     

    • 머신러닝 코드 구현시, 연산을 위해서 vector, matrix 등의 형상(shape), 차원(dimension)을 확인하는 것이 필요!
    A = np.array([1, 2, 3])
    B = np.array([4, 5, 6])
    
    # vector A, B 출력
    print("A == ", A, ", B == ", B)
    
    # vector A, B 형상 출력 => shape
    print("A.shape == ", A.shape, ", B.shape == ", B.shape)
    
    # vector A, B 차원 출력 => dimension
    print("A.ndim == ", A.ndim, ", B.ndim == ", B.ndim)
    # 결과
    A ==  [1 2 3] , B ==  [4 5 6]
    A.shape ==  (3,) , B.shape ==  (3,)
    A.ndim ==  1 , B.ndim ==  1

     

    • 벡터간 사칙연산(+, -, *, /)은 벡터의 각각의 원소에 대해서 수행됨
    print("A + B == ", A + B)
    print("A - B == ", A - B)
    print("A * B == ", A * B)
    print("A / B == ", A / B)
    # 결과
    A + B ==  [5 7 9]
    A - B ==  [-3 -3 -3]
    A * B ==  [ 4 10 18]
    A / B ==  [0.25 0.4  0.5 ]

     

    • 행렬은 벡터와 마찬가지로 np.array[[...], [...], [...])를 사용하여 생성
    • reshape() 함수를 사용하여 벡터를 행렬로 변경하거나, 행렬을 다른 현상의 행렬로 변경할 수 있음
    C = np.array([1, 2, 3])
    
    # 벡터 형상 출력
    print("C.shape == ", C.shape)
    
    # 벡터를 1x3 행렬로 형 변환
    C = C.reshape(1, 3)
    
    # 행렬 형상 출력
    print("C.shape == ", C.shape)
    # 결과
    C.shape ==  (3,)
    C.shape ==  (1, 3)

    행렬 곱 (dot product)

    • A 행렬과 B 행렬의 곱 (dot product)는 np.dot(A, B) 으로 나타내며, 행렬 A의 열벡터와 행렬 B의 행벡터가 같아야 함
    • 만약 같지 않다면, reshape() 또는 전치행렬(transpose) 등을 사용하여 형 변환을 한 후에 행렬 곱 실행
    A = np.array([[1, 2, 3], [4, 5, 6]]) # 2x3 행렬
    B = np.array([[-1, -2], [-3, -4], [-5, -6]]) # 3x2 행렬
    
    # (2x3) dot product (3x2) = (2x2) 행렬
    C = np.dot(A, B)
    
    # matrix A, B 형상 출력 => shape
    print("A.shape == ", A.shape, ", B.shape == ", B.shape)
    print("C.shape == ", C.shape)
    print(C)
    # 결과
    A.shape ==  (2, 3) , B.shape ==  (3, 2)
    C.shape ==  (2, 2)
    [[-22 -28]
     [-49 -64]]

     

    • 행렬 곱은 행렬의 원소 개수가 같아야만 계산할 수 있는 사칙연산의 한계를 벗어남
    • 행렬 곱 조건을 만족하는 다양한 크기의 행렬을 연속으로 만들고
    • 행렬 곱을 연속으로 계산하면서
    • 결과 값을 만들 수 있기 때문에 머신러닝과 이미지 프로세싱 분야에서 자주 사용됨
    • 만약 행렬 곱을 사용하지 않으면, 똑같은 크기를 가지는 특성 값만을 사용해야 하기 때문에 다양한 특성을 갖는 필터 개발이 불가

    전치행렬(transpose)

    • 원본 행렬의 행은 열, 열은 행으로 바꾼 행렬
    • 원본 행렬을 A라고하면 전치행렬은 A^T로 나타냄
    A = np.array([[1, 2], [3, 4], [5, 6]]) # 3x2 행렬
    B = A.T # A의 전치행렬 2x3
    
    print("A.shape == ", A.shape, ", B.shape == ", B.shape)
    print(A)
    print(B)
    # 결과
    A.shape ==  (3, 2) , B.shape ==  (2, 3)
    [[1 2]
     [3 4]
     [5 6]]
    [[1 3 5]
     [2 4 6]]
    # vector 전치행렬
    
    C = np.array([1, 2, 3, 4, 5])
    D = C.T # C가 vector이므로 transpose X
    
    E = C.reshape(1, 5) # 1x5 matrix
    F = E.T # E의 전치행렬 5x1
    
    print("C.shape == ", C.shape, ", D.shape == ", D.shape)
    print("E.shape == ", E.shape, ", F.shape == ", F.shape)
    print(F)
    # 결과
    C.shape ==  (5,) , D.shape ==  (5,)
    E.shape ==  (1, 5) , F.shape ==  (5, 1)
    [[1]
     [2]
     [3]
     [4]
     [5]]

    broadcast

    • 행렬의 사칙연산은 기본적으로 두 개의 행렬의 크기가 같은 경우에만 수행이 가능
    • 그러나 numpy에서는 크기가 다른 두 행렬 간의 사칙연산(+, -, *, /)을 할 수 있는데, 이를 브로드캐스트(broadcast) 라고 함
    • 차원이 작은 쪽이 큰 쪽의 행 단위로 반복적으로 크기를 맞춘 후 계산
    A = np.array([[1, 2], [3, 4]]) # [ [1, 2], [3, 4] ]
    B = 5 # [ [5, 5], [5, 5] ]
    C = np.array([4, 5]) # [ [4, 5] ]
    
    print(A + B)
    print(A + C)
    # 결과
    [[6 7]
     [8 9]]
    [[5 7]
     [7 9]]

    index / slice / iterator

    • 행렬 원소를 명시적으로 접근하기 위해서는 리스트에서 처럼 index / slice 모두 사용 가능함
    A = np.array([10, 20, 30, 40, 50, 60]).reshape(3, 2)
    
    print("A.shape == ", A.shape)
    print(A)
    # 결과
    A.shape ==  (3, 2)
    [[10 20]
     [30 40]
     [50 60]]
    print("A[0, 0] == ", A[0, 0], ", A[0, 1] == ", A[0, 1])
    print("A[1, 0] == ", A[1, 0], ", A[1, 1] == ", A[1, 1])
    print("A[2, 0] == ", A[2, 0], ", A[2, 1] == ", A[2, 1])
    # 결과
    A[0, 0] ==  10 , A[0, 1] ==  20
    A[1, 0] ==  30 , A[1, 1] ==  40
    A[2, 0] ==  50 , A[2, 1] ==  60
    print("A[0:-1, 1:2] == ",A[0:-1, 1:2])
    # 결과
    A[0:-1, 1:2] ==  [[20]
     [40]]
    print("A[ :, 0] == ", A[ :, 0])
    print("A[ :, :] == ", A[ :, :])
    # 결과
    A[ :, 0] ==  [10 30 50]
    A[ :, :] ==  [[10 20]
     [30 40]
     [50 60]]

     

    • 명시적 index / slice 이외에, 행렬 모든 원소를 access 하는 경우에는 iterator 사용 가능
    • numpy iterator는 next() 함수를 통해 데이터 값을 처음부터 끝까지 읽어 들이는 방법을 제공
    A = np.array([[10, 20, 30, 40], [50, 60, 70, 80]])
    
    print(A, "\n")
    print("A.shape == ", A.shape, "\n")
    
    # 행렬 A의 iterator 생성
    # flags = ['multi_index'] : iterator 생성후 반복할때 행렬처럼 (row, column) 형태의 multi_index 형태로 동작
    # op_flags = ['readwrite'] : iterator 를 R/W 형태로 생성
    it = np.nditer(A, flags = ['multi_index'], op_flags = ['readwrite'])
    
    while not it.finished:
        idx = it.multi_index
        print("current value => ", A[idx])
        it.iternext()
    # 결과
    [[10 20 30 40]
     [50 60 70 80]] 
    
    A.shape ==  (2, 4) 
    
    current value =>  10
    current value =>  20
    current value =>  30
    current value =>  40
    current value =>  50
    current value =>  60
    current value =>  70
    current value =>  80

    concatenate

    • 행렬에 행(row) 또는 열(column)을 추가하기 위해 사용하는 함수
    • 머신러닝의 회귀(regression) 코드 구현시 가중치(weight)와 바이어스(bias)를 별도로 구분하지 않고 하나의 행렬로 취급하기 위한 프로그래밍 구현 기술
    # 행렬에 열과 행 추가
    
    A = np.array([[10, 20, 30], [40, 50, 60]])
    
    print(A.shape)
    
    # A matrix에 행(row) 추가할 행렬, 1x3 reshape
    # 행을 추가하기 때문에 우선 열을 3열로 만들어야 함
    row_add = np.array([70, 80, 90]).reshape(1, 3)
    
    # A matrix에 열(column) 추가할 행렬, 2x1 reshape
    # 열을 추가하기 때문에 우선 행을 2행으로 만들어야 함
    column_add = np.array([1000, 2000]).reshape(2, 1)
    
    # numpy.concatenate 에서 axis = 0 (행 기준)
    B = np.concatenate((A, row_add), axis = 0)
    
    print(B)
    
    # numpy.concatenate 에서 axis = 1 (열 기준)
    C = np.concatenate((A, column_add), axis = 1)
    
    print(C)
    # 결과
    (2, 3)
    [[10 20 30]
     [40 50 60]
     [70 80 90]]
    [[  10   20   30 1000]
     [  40   50   60 2000]]

    useful functions (loadtxt(), rand(), argmax() ... )

    loadtxt()

    • seperator로 구분된 파일에서 데이터를 읽기 위해 사용하는 함수
    • 리턴 값은 행렬이기 때문에 index / slice 이용하여 데이터를 분리할 수 있음
    • 머신러닝 코드에서 입력 데이터와 정답 데이터를 분리하는 프로그래밍 기법
    # 데이터는 25x4 행렬이라고 가정
    loaded_data = np.loadtxt('./data-01.csv', delimiter = ',', dtype = np.float32)
    
    x_data = loaded_data[ :, 0:-1] # 모든 행, 3열까지의 데이터
    t_data = loaded_data[ :, [-1]] # 모든 행, 4열의 데이터
    
    print("x_data.ndim == ", x_data.ndim, ", x_data.shape == ", x_data.shape)
    print("t_data.ndim == ", t_data.ndim, ", t_data.shape == ", t_data.shape)
    
    # 결과
    # x_data.ndim == 2, x_data.shape == (25, 3)
    # t_data.ndim == 2, x_data.shape == (25, 1)

    rand()

    • 0과 1 사이 임의의 실수 값을 리턴해주는 함수
    • 가중치(weight)나 바이어스(bias)를 임의로 설정할 때 자주 사용하는 함수
    # 0 ~ 1 사이의 random number 발생
    
    random_number1 = np.random.rand(3)
    random_number2 = np.random.rand(1, 3)
    random_number3 = np.random.rand(3, 1)
    
    print("random_number1 == ", random_number1, ", random_number1.shape == ", random_number1.shape)
    print("random_number2 == ", random_number2, ", random_number2.shape == ", random_number2.shape)
    print("random_number3 == ", random_number3, ", random_number3.shape == ", random_number3.shape)
    # 결과
    random_number1 ==  [0.19724608 0.20855116 0.58046355] , random_number1.shape ==  (3,)
    random_number2 ==  [[0.33375994 0.84088436 0.94006071]] , random_number2.shape ==  (1, 3)
    random_number3 ==  [[0.8197173 ]
     [0.91239959]
     [0.30047281]] , random_number3.shape ==  (3, 1)

    max(), min(), argmax(), argmin()

    • max(), min() : 최대 최소를 리턴
    • argmax(), argmin() : 최대 최소의 인덱스를 리턴
    X = np.array([2, 4, 6, 8])
    
    print("np.max(X) == ", np.max(X))
    print("np.min(X) == ", np.min(X))
    print("np.argmax(X) == ", np.argmax(X))
    print("np.argmin(X) == ", np.argmin(X))
    # 결과
    np.max(X) ==  8
    np.min(X) ==  2
    np.argmax(X) ==  3
    np.argmin(X) ==  0
    X = np.array([[2, 4, 6], [1, 2, 3], [0, 5, 8]])
    
    print("np.max(X) == ", np.max(X, axis = 0)) # 열 기준
    print("np.min(X) == ", np.min(X, axis = 0)) # 열 기준
    
    print("np.max(X) == ", np.max(X, axis = 1)) # 행 기준
    print("np.min(X) == ", np.min(X, axis = 1)) # 행 기준
    
    print("np.argmax(X) == ", np.argmax(X, axis = 0)) # 열 기준
    print("np.argmin(X) == ", np.argmin(X, axis = 0)) # 열 기준
    
    print("np.argmax(X) == ", np.argmax(X, axis = 1)) # 행 기준
    print("np.argmin(X) == ", np.argmin(X, axis = 1)) # 행 기준
    # 결과
    np.max(X) ==  [2 5 8]
    np.min(X) ==  [0 2 3]
    np.max(X) ==  [6 3 8]
    np.min(X) ==  [2 1 0]
    np.argmax(X) ==  [0 2 2]
    np.argmin(X) ==  [2 1 1]
    np.argmax(X) ==  [2 2 2]
    np.argmin(X) ==  [0 0 0]

    ones(), zeros()

    A = np.ones([3, 3])
    
    print("A.shape == ", A.shape, ", A == ", A)
    
    B = np.zeros([3, 2])
    
    print("B.shape == ", B.shape, ", B == ", B)
    # 결과
    A.shape ==  (3, 3) , A ==  [[1. 1. 1.]
     [1. 1. 1.]
     [1. 1. 1.]]
    B.shape ==  (3, 2) , B ==  [[0. 0.]
     [0. 0.]
     [0. 0.]]

    matplotlib

    • 실무에서는 머신러닝 코드를 구현하기 전에, 입력 데이터의 분포와 모양을 먼저 그래프로 그려보고, 데이터의 특성과 분포를 파악한 후, 어떤 알고리즘을 적용할 지 결정하고 있음
    • 데이터 시각화를 위해 matplotlib 라이브러리를 사용함
    • 일반적으로 line plot, scatter plot 등을 통해 데이터의 분포와 형태를 파악함
    import matplotlib.pyplot as plt
    import numpy as np
    
    # 주피터 노트북을 사용하는 경우 노트북 내부에 그림 표시
    %matplotlib inline
    
    # x data, y data 생성
    x_data = np.random.rand(100)
    y_data = np.random.rand(100)
    
    plt.title('scatter plot')
    plt.grid()
    plt.scatter(x_data, y_data, color = 'b', marker = 'o')
    plt.show()

    # x data, y data 생성
    x_data = [x for x in range(-5, 5)]
    y_data = [y*y for y in range(-5, 5)]
    
    plt.title('line plot')
    plt.grid()
    plt.plot(x_data, y_data, color = 'b')
    plt.show()

    # x data, y data 생성
    x_data = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    y_data = [-8, -13, 0, 3, 6, -1, -5, -7, 1, 8, 7, 12, 13]
    
    plt.title('line plot')
    plt.grid()
    plt.plot(x_data, y_data, color = 'b')
    plt.show()

     

     

     

    참고

    www.youtube.com/playlist?list=PLS8gIc2q83OjStGjdTF2LZtc0vefCAbnX

     

    머신러닝/딥러닝 강의

    머신러닝과 딥러닝의 동작원리와 이러한 알고리즘을 파이썬으로 구현한 강의 자료입니다.

    www.youtube.com

     

    '프로그래밍 > Python' 카테고리의 다른 글

    [Python] 파이썬 문법 정리  (0) 2022.01.22
    [Python] 클래스, 예외처리  (0) 2020.11.21
    [Python] 함수, 람다  (0) 2020.11.21
    [Python] 조건문, 반복문  (0) 2020.11.21
    [Python] 데이터 타입(Data Type)  (0) 2020.11.21

    댓글

Designed by Tistory.