오늘의 감상: 그래도 git과 numpy 모두 지난 <ssacxfast campus 빅데이터 분석가 과정> 에서 강의를 들었던 과정이라 week 1의 알고리즘 week2 인공지능을 위한 수학 수업 보다는 마음 편하게 들을 수 있었다.
지난 week2에서 배운 선형대수학 개념을 numpy로 구현하는 것은 numpy 문법 보다 선형대수학에 대한 복습이 필요한 것 같다.
행렬식
sigular matrix
고유값, 고유벡터
L@ norm
1. 파이썬의 컴퓨팅 라이브러리, numpy
numpy를 이용해서 데이터를 다뤄봅시다!
I. Numpy 시작하기
import numpy as np
II. Numpy로 연산하기
vector와 scalar 사이의 연산
벡터의 원소에 대해서 연산을 진행
x = np.array([1,2,3])
c = 5
print("더하기: {}".format(x+c))
print("빼기: {}".format(x-c))
print("곱하기: {}".format(x*c))
print("나누기: {}".format(x/c))
더하기: [6 7 8]
빼기: [-4 -3 -2]
곱하기: [ 5 10 15]
나누기: [0.2 0.4 0.6]
a = [1,2,3]
a*c # 그냥리스트는 연산이 되는게 아니라 리스트의 반복이 되어버린다.
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
vector와 vector와 사이의 연산
벡터의 같은 인덱스끼리 연산
y = np.array([1,3,5])
z = np.array([2,9,20])
print("더하기: {}".format(y + z))
print("빼기: {}".format(y - z))
print("곱하기: {}".format(y * z))
print("나누기: {}".format(y / z))
더하기: [ 3 12 25]
빼기: [ -1 -6 -15]
곱하기: [ 2 27 100]
나누기: [0.5 0.33333333 0.25 ]
array의 인덱싱
- 리스트와 유사
- 리스트와 달리 리스트 내 리스트를 불러올 때 [][]가 아니라 [,]로 인덱스한다
w= np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print(w[0,0])
print(w[2,3])
1
12
array의 슬라이싱
- 리스트와 유사
w= np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
# 일부 행 전체를 가져오고 싶을 때 -3가지 방법이 있음
w[0:2]
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
w[0:2,:]
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
w[0:2,0:4]
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# 일부 열 전체를 가져오고 싶을 때 -2가지 방법이 있음
w[0:3, 2:4]
array([[ 3, 4],
[ 7, 8],
[11, 12]])
w[:, 2:4]
array([[ 3, 4],
[ 7, 8],
[11, 12]])
# 2,3 과 6,7 을 불러오고 싶을 때
# 행은 0,1행 -> [0:2] 열은1,2열 -> [1:3]에 있는 데이터들
print(w[0:2, 1:3])
[[2 3]
[6 7]]
array 의 broadcasting
numpy의 연산을 진행하는 특수한 방법
기본적으로 같은 type의 data에 대해서만 연산 적용이 가능
그러나 만약 피연산자가 연산 가능하도록 변환이 가능하다면, 연산이 가능해집니다.
이를 broadcasting이라고 합니다.
- MxN, Mx1(열벡터) 행렬이 있는 경우 -> 뒷 행렬의 열을 복사시켜서 element-wise 계산할 수 있다. (행렬곱이 아니다)
- MxN, 1xN(행벡터) 행렬이 있는 경우 -> 뒷 행렬의 행을 복사시켜서 element-wise 계산할 수 있다. (행렬곱이 아니다)
- Mx1(열벡터), 1xN(행벡터) 행렬이 있는 경우 -> MxN 행렬의 연산이 진행됨
# 1. MxN, Mx1
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
x = np.array([0,1,0])
print(a+x)
[[1 3 3]
[4 6 6]
[7 9 9]]
# 기본적으로 행벡터이기 때문에 x를 열벡터로 transpose해줘야 한다.
x = x[:, None] #x를 전치
print(a+x)
[[1 2 3]
[5 6 7]
[7 8 9]]
#2. MxN, 1xN
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
y = np.array([0,1, -1])
print(a * y)
[[ 0 2 -3]
[ 0 5 -6]
[ 0 8 -9]]
#3. Mx1(열벡터), 1xN(행벡터)
t = np.array([1,2,3])
u = np.array([2,0,-2])
t = t[:,None] # 열벡터로 전치
print(t + u)
[[ 3 1 -1]
[ 4 2 0]
[ 5 3 1]]
III. Numpy로 선형대수 지식 끼얹기
영벡터(영행렬)
원소가 모두 0인 벡터(행렬)
np.zeros(dim)으로 생성
dim은 값 또는 튜플(,)
np.zeros(3)
array([0., 0., 0.])
np.zeros((3,3))
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
일벡터(일행렬)
원소가 모두 1인 벡터(행렬)
np.ones(dim)으로 생성
dim은 값 또는 튜플(,)
np.ones(3)
array([1., 1., 1.])
np.ones((3,3))
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
대각행렬 (diagonal matrix)
main diagonal을 제외한 성분이 0인 행렬
np.diag((main_diagonals))을 통해 생성
np.diag((2,4))
array([[2, 0],
[0, 4]])
np.diag((1,3,5))
array([[1, 0, 0],
[0, 3, 0],
[0, 0, 5]])
항등행렬 (identity matrix)
main diagonal이 1인 행렬
np.eye(n, (dtype))을 통해 생성 (default는 float)
dtype을 파라미터로 넣을 수 있다 (int, float, uint, complex...)
np.eye(2)
array([[1., 0.],
[0., 1.]])
np.eye(2, dtype=int).dtype
dtype('int64')
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
행렬곱 (dot product)
np.dot() or @ 사용
mat_1 = np.array([[1,4],[2,3]])
mat_2 = np.array([[7,9],[0,6]])
mat_1.dot(mat_2)
array([[ 7, 33],
[14, 36]])
mat_1 @ mat_2
array([[ 7, 33],
[14, 36]])
트레이스 (trace)
main diagonal의 합
np.trace()
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
arr.trace()
15
arr = np.eye(2, dtype=int)
arr.trace()
2
행렬식 (determinat)
- 행렬을 대표하는 값들 중 하나
- 선형변환 과정에서 어떤 벡터의 스케일링 척도
- 선형변화를 진행했을 때 얼마나 원벡터가 변화하는가
ad-bc (2x2 일때)
np.linalg.det()
arr_2 = np.array([[2,3],[1,6]])
arr_2
array([[2, 3],
[1, 6]])
np.linalg.det(arr_2)
9.000000000000002
arr_3 = np.array([[1,4,7],[2,5,8], [3,6,9]])
arr_3
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
np.linalg.det(arr_3) # det = 0 -> 즉 full rank 가 아니고 선형변환에서 차원의 손실이 일어난다.
0.0
역행렬 (Inverse Matrix)
- 행렬A에 대해 AB = BA = I를 만족하는 행렬
- B = A^-1
- np.linalg.inv()
mat = np.array([[1,4],[2,3]])
mat
array([[1, 4],
[2, 3]])
mat_inv = np.linalg.inv(mat)
mat_inv
array([[-0.6, 0.8],
[ 0.4, -0.2]])
mat @ mat_inv
array([[1., 0.],
[0., 1.]])
고유값과 고유벡터 (engenvalue eigenvecter)
- 정방 행렬A에 대해 $Ax = (\lambda)x$ 를 만족하는 상수 $(\lambda)$와 이에 대응하는 벡터
- np.linalg.eig()
mat = np.array([[2,0,-2],[1,1,-2],[0,0,1]])
mat
array([[ 2, 0, -2],
[ 1, 1, -2],
[ 0, 0, 1]])
np.linalg.eig(mat)
(array([1., 2., 1.]),
array([[0. , 0.70710678, 0.89442719],
[1. , 0.70710678, 0. ],
[0. , 0. , 0.4472136 ]]))
###validation
eigen_val, eigen_vec = np.linalg.eig(mat)
mat @ eigen_vec[:,0] #Ax
array([0., 1., 0.])
eigen_val[0] * eigen_vec[:,0] # (lambda)x
array([0., 1., 0.])
IV. Exercises
1. 어떤 벡터가 주어졌을 때 L2 norm을 구하는 함수 get_L2_norm()
을 작성하세요
- 매개변수 : 1차원 벡터 (
np.array
) - 반환값 : 인자로 주어진 벡터의 L2 Norm값 (
number
)
L2-norm이란?
def get_L2_norm(arr):
return (sum(arr**2))**0.5
arr = np.array([1,2,3])
get_L2_norm(arr)
3.7416573867739413
L2_norm = np.linalg.norm(arr, 2)
print(L2_norm)
3.7416573867739413
(sum(arr**2))**0.5
array([4.12310563, 5.38516481, 6.70820393])
2. 어떤 행렬이 singular matrix인지 확인하는 함수 is_singular()
를 작성하세요
- 매개변수 : 2차원 벡터(
np.array
) - 반환값 : 인자로 주어진 벡터가 singular하면 True, non-singular하면 False를 반환
sigular matrix : 역행렬이 존재하지 않는 행렬
행렬식 = 0인 행렬
def is_singular(arr):
return np.linalg.det(arr) == 0
arr = np.array([[1,2],[2,4]])
is_singular(arr)
True
'Programming > Python' 카테고리의 다른 글
배열에 아이템을 추가하는 메서드 .append(), .extend(), .insert() 비교 (0) | 2021.06.21 |
---|---|
딕셔너리에서 value를 가지고 key 얻기 (0) | 2021.05.07 |
filter() 리스트, 튜플 등에서 조건에 맞는 요소만 추려내는 내장함수 (0) | 2021.05.04 |
.get() 딕셔너리에서 key를 사용해 value 얻기 (0) | 2021.05.04 |
map() - 리스트, 튜플 등에서의 각 요소를 지정된 함수로 처리해주는 내장함수 (0) | 2021.04.26 |