본문 바로가기

AI & Data Science

BoostCourse AI Pre-Course) 기초 수학(numpy,벡터,행렬)

728x90
반응형

Numpy)

Numpy = Numerical Python

고성능 과학 계산용 패키지이다. matrix, vector과 같은 array 연산의 사실상 표준, 일반 리스트에 비해 빠름, 반복문 없이 배열 처리 지원, 선형대수와 관련된 기능 지원, c, c++ 등의 언어와 통합 가능

import numpy as np

arr = np.array([1,4,5,8],float) #numpy로 리스트를 만드는데 이때 자료형은 float로 한다. 즉 하나의 데이터 타입만 배열에 넣을 수 있다.
f_arr = np.array([[1,4,5,8]],float) #1차원 np배열
t_arr = np.array([[1,2,3,4],[5,6,7,8]]) #2차원 np배열

print(arr) # -> [1. 4. 5. 8.]
print(arr[2]) #기존 리스트 처럼 인덱스로도 접근 가능 -> 5.0
print(arr.dtype) #배열 전체의 datatype 반환 -> float64

print(arr.shape) #0차원에 shape이 4이다. -> (4,)
print(f_arr.shape) #1차원에 shape이 4이다. -> (1, 4)
print(t_arr.shape) #2차원에 shape이 4이다. -> (2, 4)

a = np.array(t_arr).reshape(8,) #(2,4)를 reshape을 통해서 (8,)로 변환 최종적으로 원소의 개수는 동일해야 한다. 따라서 2*4인 8이 된다.
print(a)

b = np.array(t_arr).flatten() #flatten 함수를 사용해서 다차원 배열을 1차원 배열로 변형 시킨다.
print(b)

print(t_arr[1,1]) #t_arr[1][1]과 같다.
print(t_arr[1][1]) #t_arr[1,1]과 같다.
print(t_arr[:,1:3]) #파이썬의 리스트 슬라이싱 기능은 2차원 배열에서 사용하지 못했는데 numpy는 가능하다.

c = np.arange(27) # 0 부터 n-1 까지 원소로 np배열 생성
print(c)

c = np.array(c).reshape(3,9) #3행 9열 2차원 배열로 변환
print(c)

k = np.arange(0,27,2) # 0 ~ 26 까지 2간격으로 np 배열 생성
print(k)
print(k.sum()) #원소들의 합

d = np.zeros(shape=(10,),dtype=np.int8) #0차원 원소가 10개인 0으로만 이루어진 np 배열
e = np.ones(shape=(10,),dtype=np.int8) #0차원 원소가 10개인 1으로만 이루어진 np 배열
f = np.empty((3,5)) #3차원 각 차원 원소가 5개인 빈 np배열을 생성 -> 메모리 초기화가 되지 않음
print(d)
print(e)
print(f)

g = np.ones_like(f) #f배열의 크기와 같은 1로만 이루어진 배열을 반환
print(g)

h = np.identity(n=3,dtype = np.int8) #크기가 n인 단위행렬 생성
print(h)

i = np.eye(N=3, M=5, k=2) #N차원에 각 차원이 M개의 원소를 가진 0 배열을 만들고 k 부터 대각선으로 1을 가진다. N,M은 대문자 k는 소문자로 쓴다.
print(i)

j = np.diag(c,k=2) #특정 배열의 첫번째 행의 k번째 값부터 대각선으로 값을 출력
print(j)

k = np.random.uniform(0,1,10).reshape(2,5) #0~1 사이로 10개의 원소를 균등분포로 생성후 2차원 배열로 변환
l = np.random.normal(0,1,10).reshape(2,5) #0~1 사이로 10개의 원소를 정규분포로 생성후 2차원 배열로 변환
print(k)
print(l)

x = np.load("파일경로 + 파일명") #파일 호출
np.save('파일명',배열명, delimiter ==',') #호출한 파일 저장

필요한 numpy 기능이 있을 때마다 찾아서 공부해보는 것이 중요하다.

 

Vector)

벡터는 숫자를 원소로 가지는 리스트, 공간상에서 한 점, 원점으로 부터 상대적 위치 표현, 같은 모양끼리는 덧셈, 뺄셈, 곱셈 가능

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) #성분곱

덧셈과 뺄셈은 상대적 위치 이동을 의미한다. 같은 모양일 가질 때만 성분곱(Hadmard Product)이 가능하다.

벡터의 노름(norm)은 원점에서 부터의 거리를 의미한다.

L1-norm은 변화량의 절대값을 모두 더해주면 된다.

L2-norm은 유클리드 거리를 계산한다.

 

import numpy as np

x = np.array([1,7,2])

def L1Norm(x):
    ans = np.abs(x) #절대값
    ans = np.sum(ans)
    return ans

def L2Norm(x):
    ans = x*x #피타고라스의 정리에 근거한 제곱
    ans = np.sum(ans)
    ans = np.sqrt(ans)
    return ans

print(L1Norm(x))
print(L2Norm(x))

import numpy as np

x = np.array([1,7,2])
y = np.array([3,4,5])

def L2Norm(x):
    ans = x*x
    ans = np.sum(ans)
    ans = np.sqrt(ans)
    return ans

def Angle(x,y):
    v = np.inner(x,y) / ((L2Norm(x)) * L2Norm(y)) #제2코사인 법칙 v는 코사인theta 값이 된다.
    theta = np.arccos(v)
    return theta

def distance(x,y):
    a = x-y
    ans = L2Norm(a)
    return ans

print(Angle(x,y))

벡터의 내적을 이용한 제 2 코사인 법칙으로 두 벡터의 각도를 구할 수 있다.

두 벡터 사이의 거리는 뺄셈을 이용해서 구할 수 있다.

Matrix)

행렬은 벡터를 원소로 가지는 2차원 배열이다. 이름처럼 행(가로)과 열(세로)로 이루어져 있다. 특정행을 고정하면 행 벡터, 열을 고정하면 열 벡터로 부를 수 있다. 행렬끼리 같은 모양을 가지면 덧셈, 뺄셈, 성분곱 가능

 

import numpy as np

x = np.array([[1,-2,3],
             [7,5,0],
             [-2,-1,2]])

y = np.array([[3,4,5],
              [6,7,8],
              [9,10,11]])

z = np.array([[0,1],
              [1,-1],
              [-2,1]])

print(x*y) #성분곱
#print(x*z) #행렬의 크기가 다르기 때문에 성분곱 오류

print(x@y) #행렬곱 두 행렬의 크기가 같음
print(y@x) #행렬곱 두 행렬의 크기가 같으나 순서가 다르기 때문에 값도 다름
print(x@z) #행렬곱 앞의 행렬의 행의 크기가와 뒤에 행렬의 열의 크기가 같음
#print(z@x) #행렬곱 앞의 행렬의 행의 크기가 뒤에 행렬의 열의 크기가 다르기 때문에 오류
#행렬곱은 순서가 중요하다

print(np.inner(x,y)) #행끼리 내적, 수학에서의 내적과는 다르다.

행렬은 벡터 공간에서 사용되는 연산자(Operator)로 이해한다.

행렬곱을 통해서 벡터를 다른 차원으로 보낼 수 있고 패턴추출, 데이터 압축도 가능하다.

 

어떤 행렬의 연산을 거꾸로 돌리는 행렬을 역행렬 이라한다.

역행렬은 행과 열의 숫자가 같고 행렬식(Determinant)이 0이 아닌 경우에만 계산 가능하다.

import numpy as np

x = np.array([[1,-2,3],
             [7,5,0],
             [-2,-1,2]])

y = np.array([[3,4,5],
              [6,7,8],
              [9,10,11]])

z = np.array([[0,1],
              [1,-1],
              [-2,1]])


inv_x = np.linalg.inv(x) #x의 역행렬(행과 열의 크기가 같음)
print(inv_x)

pinv_z = np.linalg.pinv(z) #z의 펜로즈 역행렬(행과 열의 크기가 다름)
print(pinv_z)

'''
2x + 2y + z = 4
x + 3y + 2z = 6
-3x + 4y + 3z = 5
'''
k = np.array([[2,2,1],
              [-3,4,3]])
ans = np.array([[4],[5]])
pinv_k = np.linalg.pinv(k)
print(pinv_k@ans) #연립 방정식의 해 구하기
728x90
반응형