강의 복습 내용
- numpy의 사용법과 함수들
- 행렬과 벡터의 연산방법
- 역행렬과 같은 행렬 관련 연산법
얻은 지식
- numpy
- numpy로 배열선언
- numpy관련 함수
- 행렬 계산 함수
- 벡터
- 행렬
- 선형회귀분석하기
numpy
- 넘파이
- numerical python의 약자
- 단순한 행렬 표현은 가능하지만 계산하는데 처리속도등의 문제가 있다.
- 고성능 과학 계산용 패키지
특징
- 일반적 list에 비해 빠르고, 메모리 효율적
- 반복문 없이 데이터 배열 처리지원
- 선형대수와 관련된 다양한 기능을 제공
- c,c++,포트란 등의 언어와 통합 가능
설치
conda insall numpy # conda를 이용해 설치
ndarray
- numpy의 array
np.array
로 배열 선언 타입은ndarray
로 나타난다.
import numpy as np # 일반적으로 np로 호출
#한가지 데이터 type만 넣을 수 있음
# list와 차이가 있다.
# dynamic typing not supported
# c의 array
test_array = np.array([1,2,4,5],float)
#np.array 함수를 통해 배열 생성
hadling shape
slicing
- list와 달리 행과 열부분을 나눠서 slicing이 가능함
- 부분집합 추출할때 유용
[row,column]
으로 표현됨
1:3
이면 마지막은 포함 안됨
start:end:step
으로 표현
a=np.array([1,2,3,4],[5,6,7,8]],int)
# 전체 row, 2번째 column이상 자르기
a[:,2:]
# 1번 row만, 1부터 3까지의 column만 자르기
a[1,1:3]
# 1번 row부터 3번 row까지만
a[1:3] # column부분은 생략해서
creation function
- 생성 함수
np.arange()
range와 같은 효과로 배열을 생성
np.zeros(모양)
- 0으로 가득한 ndarray생성
np.zeros(shape,dtype,order)
np.ones(모양)
- 1로 가득한 ndarray생성
np.ones(shpae,dtype,order)
np.empty(모양)
- shape만 주어지고 비어있는 ndarray생성
- memory initialization이 되지 않음
- 값을 출력하면 누군가 쓴 값이 보여준다 (엿보기)
np.empty(shapte,type)
np.something_like(이름)
기존 ndarray
의 shape만큼 1,0,empty array를 반환
np.ones_like(기존ndarray명)
- arrya와 같은 모양으로 1채우기
np.zeros_like(기존ndarray명)
- arrya와 같은 모양으로 0채우기
np.empty_like(기존ndarray명)
- arrya와 같은 모양으로 empty한거채우기
identity
- 단위행렬을 생성함
np.identity(row길이,dtype)
eye
- 대각선이 1인 행렬(단위행렬과 유사하지만 다름)
np.eye(3)
단위행렬과 같은 결과를 보인다.
np.eye(row,column,k값 대각선이 시작되는 index)
diag
- 대각 행렬의 값을 추출
np.diag(matrix,[k 시작되는 index])
random sampling
- 데이터 분포에 따라 sampling으로 array를 생성
(모수,모수,데이터크기)
로 들어간다.
np.random.uniform(0,1,10).reshap(2,5)
- 균등분포
np.random.normal(0,1,10).reshap(2,5
- 정규분포
- 그외 여러가지 있다.
operation functions
- array내의 계산
axis
- operation function을 실행할때 기준이 되는 축
- 2차원일때는
(axix=0,axis=1)
과 같이 기준을 추가해줄수있다.
- 0이면 row기준으로 더하기, 1이면 모든 column기준으로 더하기
sum
- array의 모든 요소를 더하기
sum(axis=1)
로 axis를 지정할 수 있다.
concatenate
- array를 합치는 함수
np.vstack((array,array))
- row붙이기
np.hstack((array,array))
- column붙이기
concatenate
np.concatenate((a,b),axis)
로 합친다.
array operation
- array간의 계산
- array간의 shape이 같을때 일어나는 연산
element-wise operations
라고 한다.
- 같은 위치끼리 연산되는것
- +,-,*가 가근
dot product
- 행렬 기본연산으로 dot함수 사용
a.dot(b)
또는 a @ b
로도 표현 가능
transpose
transpose()
또는 T attribute
사용
a.T
를쓰면 행과 열의 위치가 변경된다.
[1,2,3],[4,5,6]
->
[1,4],[2,5],[3,6]
broadcasting
- shape이 다른 배열간 연산 지원
- 낮은부분이 알아서 퍼져서 계산이 된다.
- 따로 함수가 있는게 아니라 알아서 채워주는것
- 예) vector + scalar - scalar가 vector모양으로 알아서 채워서 더해진다.
- matrix + scalar - 위와 같음 각 요소를 scalar가 더해진다.
- matrix + vector - 남은자리를 matrix처럼 늘어난다.
- 대신 vector는 matrix와 열이 같아야한다.
timeit
% timeit
을 앞에 된다.
comparisons
- array 는 대소비교도 가능하다
all
은 모든 배열의 요소가 조건이 참인지
any
은 배열중 하나라도 조건이 참인지
a = np.array(5)
a<2 # 각각의 array요소마다 진행한다.
# [True,True,False,False,False
np.any(a<2)
# True
np.all(a<2)
# False
- 같은 크기면 요소간의대소비교 결과를 boolean type으로 반환한다.
logical
- 둘다 boolean type일때
np.logical_and(a,b)
- 두 배열을 and 연산
np.logical_or(a,b)
- 두 배열을 or연산
np.logical_not(a)
- not을 반환
np.where
- 많이 사용됨
where(조건,true일때,false일때)
-조건에따라 배열을 만든다.
where(조건)
-조건에 맞는 배열을 반환
isnan
isfinite
a=np.arange(10)
np.where(a>4,3,2)
#[2,2,2,2,3,3,3,3,3,3]
np.where(a>4)
#[5,6,7,8,9]
np.isnan(a)#not a number 메모리 값이 존재하지 않을때
np.isfinite(a)#한정되지 않을때 발산하지 않을때
- argmax,argmin
- 최대값, 최소값의 index를 반환
np.argmax(a)
np.argmin(a)
np.argsort()
오름차순으로 index값을 반환한다.
a= np.array([1,2,4,5,8,78,23,3])
np.argsort()
#[0,1,7,2,3,4,6,5]
np.argsort()[::-1]#반대
np.argmax(a)
#5
#axis도 적용 가능
boolean, fancy index
boolean index
- 특정 조건에 따른 값을 배열 형태로 추출
comparison operation
함수들도 사용 가능하다.
a[조건]
- 조건에는 같은 shape여야 한다.
a = np.arange(10)
a[a>3] # 조건이 true인 index의 요소만 추출
#[4,5,6,7,8,9]
fancy index
- index value를 이용해 값 추출
- matrix형태도 가능
take
함수를 사용
a = np.array([2,4,6,8],float)
b = np.array([0,0,1,3,2,1],int)
# b는 무조건 int타입이어야 한다.
# b의 값들은 a의 index범위를 벗어나면 안된다.
a[b]
#[2,2,4,8,6,4]
a.take(b)#위와 같다
#[2,2,4,8,6,4]
numpy i/o
- text를 읽고 저장하는게 가능
np.load(txt)
a.astype(int)
np.savetext(파일명, array명, delimiter=",")
- text형식으로 저장
- delimiter로 중간마다 넣을 단어를 정할수있다.
np.save(이름,arr="저장할 nparray")
벡터
벡터란
- 숫자를 원소로 가지는 리스트 또는 배열
- 행백터
\[\begin{matrix} 1\\2\\3 \end{matrix}\]
\[\begin{matrix} 1&2&3 \end{matrix}\]
- 공간에서 한 점을 나타낸다.
- 원점을 기준으로 상대적 위치를 표현
- 숫자를 곱하면 방향은 그대로면서 길이만 변합니다.
- 같은 모양이면 덧셈,뺄셈이 가능
- 같은 모양일때 곱하는
성분곱
- 덧셈이 진행되는 방식
- 두개의 벡터가 더해질때
- a가 0을 상대적으로 가는 방향일때, b는 a의 위치를 기준으로 상대적 위치 이동을 표현하게 됩니다.
노름(norm)
- 원점에서부터의 거리
L1-노름
L2-노름
- 피타고라스 정리를 이용해 유클리드 거리를 계산하기
- 노름의 종류에 따라 기하학적 성질이 달라진다.
- 원이라는 것에서 두가지 노름이 계산하는결과가 다르다.
- L1은 마름모 형태가 된다.
- L2가 우리가 아는 원 형태로 계산한다.
- 최적화, 학습방법, 정규화에 사용될 수 있다.
- 목적에 따라 적절한 노름을 사용
- 두 백터의 거리계산 방식
- 두 벡터의 각도 계산
- 제2 코사인 법칙을 통해 계산이 가능하다.
- L2 노름으로 계산이 가능
- 내적
- 두벡터들을 성분곱 하고, 더한값
inner product
np.inner(x,y)
로 표현가능
- 내적 해석
- 정사영(orthogonal projection)된 벡터의 길이
- X벡터를 Y벡터 기준으로 수직으로 내릴때 생기는 그림자를 의미한다.
- 그림자의 길이는 코사인 법칙에 의해 \(\Vert x \Vert cos \theta\) 와 같다
- 내적은 이 그림자의 길이를 \(\Vert y \Vert\) 만큼 조정한값
- 두 벡터가 얼만큼 유사한가를 측정할때 사용한다.
행렬
행렬이란
- matrix은 벡터를 원소로 가지는 2차원 배열
- i는 행, j는 열
Tranpose matrix
- 행과 열이 바뀐 행렬
- 표현은 \(X^T = (x_{ji})\)
- 행렬도 모양이 같으면 덧셈,뺄셈, 성분곱도 가능
- 스칼라곱도 벡터와 차이없다.
- 두데이터를 연결하는
연산자(operator)
로 이해할 수 있따.
- 행렬 곱을 통해 벡터를 다른 차원의 공간으로 보낸다.
- 이때의 행렬을 연산자라고 한다.
- 데이터에서 패턴을 추출, 데이터 압축할 수 있다.
linear transform
이라고 한다.
행렬곱셈
- 두행렬(x,y) 행렬곱셈은 a의 i행과 b의 j열의 내적을 성분으로 가지는 행렬
- 행렬 내적np.inner로 계산하면
- 두 행렬의 각 행끼리의 내적을 성분으로 가지는 행렬을 계산한다.
역행렬
- 행렬에 행렬곱셈을 통해 항등행렬(대각선으로 1)을 만드는 행렬
- 행과 열의 숫자가 같아야 한다.
- \(A^{-1 }\)이라 표현한다.
np.linalg.inv(x)
로 계산할 수 있다.
유사역행렬(psudo-inverse)
- 역행렬을 구하지 못할때 사용한다.
- 무어-펜로스(moore-penrose)역행렬\(A^+\)을 이용한다.
np.linalg.pinv(x)
로 계산할 수 있다.
- n>=m으로 행이 큰경우 \(A^+ = (A^TA)^{-1}A^T, A^+ A=I\)가 성립
- n<=m으로 열이 큰경우 \(A^+ = A^T(AA^T)^{-1}, AA^+=I\)만 성립
Y = np.array([[0,1],[1,-1],[-2,1]])
np.linalg.pinv(Y) @ Y # 항등행렬 비슷하게 계산이 된다.
# 행이 크기때문에 유사역행렬이 앞에서 계산해야한다.
응용1
- 연립방정식 풀기
- n<=m으로 식이 해의 개수보다 작거나 같아야 해를 구할 수 있다.
\[\begin{matrix}
a_{11}x_1+a_{12}x_2+ \cdots +a_{1m}x_m = b_1 \\
a_{21}x_1+a_{22}x_2+ \cdots +a_{1m}x_m = b_1 \\
\vdots \\
a_{n1}x_1+a_{n2}x_2+ \cdots +a_{nm}x_m = b_n \\
\end{matrix}\]
- 위의 공식은
Ax = b
로 행렬식으로 표현이 된다.
- \(x=A^+b\)가 돤다
- n<=m이므로 \(x=A^T(AA^T)^{-1}b\)를 계산하면 된다.
응용2
- n>=m 경우인 변수보다 식이 더 많은 경우
- 선형회귀분석
np.linalg.pinv
를 이용하여 선형 모델로 해석하는 선형회귀식을 찾을 수 있다.
- 행이 많아서
- 식은 \(X\beta = \hat y \approx y\)
- 예측한 \(\hat y\) 와 \(y\)의 L2노름이 최소화할때 예측을 잘했다고 볼 수 있다.
- \(\beta=(X^TX)^{-1}X^Ty\)로 \(\beta\)를 구하고 y에 근접한 \(\hat y\)를 구할 수 있다.
sklearn
의 LinearRegression
으로 구할 수 있다.
from sklean.linear_model import LinearRegression
model = LinearRegression
model.fit(X,y)#X는 식, y는 결과
#x_test는 [값1,값2,...값m]으로 X의 열만큼 있는 배열이다.
y_test = model.predict(x_test)#x_test란 값을 넣어서 y_test를 확인
#x_test가 X의 행의 값과 동일하게 넣으면 같은행의 y값이 나온다.
# 역행렬로 근사한 값 구하기
X_ = np.array([np.append(x,[1]) for x in X])# 각 행마다 1을 추가
beta = np.linalg.pinv(X_) @ y # Xb=y일때 b구하기
y_test2 = np.append(x_test,[1]) @ beta
# 새로운 행인 [...x_test,1]를 append하고, beta를 행렬곱셈으로 예측값 확인
# y_test와 y_test2가 유사하다.
좀더 찾아보기
- Robust
- Lasso
- Lablace
- Ridge
피어세션 정리
- numpy
- isfinite? 언제쯤 사용할지
- 수렴하지 않을때
- m1에서 numpy설치가 어렵다.
- 굉장히 큰 매트릭스는?
- rnn(자연어처리)
- 책
- 이번주할거
- numpy함수를 실제 딥러닝 코드에서 어떻게 쓰는지 예시 코드 공부
의문사항
- 선형회귀할때 다시 y_test를 구하려고 intercept항을 추가하는 이유?
- 이미 model.predict로 구한거 아닌지?