선형대수
벡터
유한차원공간에 존재하는 점으로 표현한다. ex) (키, 몸무게, 나이), (국어점수, 수학점수, 영어점수)
typing 모듈
타입에 대한 힌트(주석)를 IDE등의 써드파티 등에 주기 위한 용도이다. 단, 파이썬 인터프리터는 주어진 힌트를 강제하지 않는다.
함수주석
함수의 매개변수와 반환값에 주석작성이 가능하다 강제성이 없어 무시하고 사용도 가능하다. 콜론(:)을 사용해 매개변수에 할당되어야 하는 타입을 할당하고, 화살표를 사용해 반환값에 할당되어야 하는 형식을 할당한다.
def func(a: str, b: float = 3.5) -> int:
return a+b
value = func(3)
print(value)
벡터의 연산
[1,2] + [2,1] = [1+2, 2+1] = [3, 3]
assert
디버깅이 편리하다. 이후의 값이 True가 아니면, AssertionError가 발생한다.
assert 'expression', "에러메시지 문자열" 형태로 작성한다.
from typing import List
Vector = List[float]
def add(v: Vector, w: Vector) -> Vector:
assert len(v) == len(w), "Vectors must be the same length"
return [v_i + w_i for v_i, w_i in zip(v, w)]
assert add([1, 2, 3], [4, 5, 6]) == [5, 7, 9]
def subtract(v: Vector, w: Vector) -> Vector:
assert len(v) == len(w), "Vectors must be the same length"
return [v_i - w_i for v_i, w_i in zip(v, w)]
assert subtract([5, 7, 9], [4, 5, 6]) == [1, 2, 3]
벡터 성분의 합
from typing import List
Vector = List[float]
def add(v: Vector, w: Vector) -> Vector:
assert len(v) == len(w), "Vectors must be the same length"
return [v_i + w_i for v_i, w_i in zip(v, w)]
assert add([1, 2, 3], [4, 5, 6]) == [5, 7, 9]
def vector_sum(vectors: List[Vector]) -> Vector:
answer = vectors.pop()
while(len(vectors)>0):
answer = add(answer, vectors.pop())
return answer
assert vector_sum([[1, 2], [3, 4], [5, 6], [7, 8]]) == [16, 20], "vector_sum error"
벡터와 스칼라 곱
from typing import List
Vector = List[float]
def scalar_multiply(c: float, v: Vector) -> Vector:
"""Multiplies every element by c"""
return [c * v_i for v_i in v]
벡터의 성분별 평균
from typing import List
Vector = List[float]
def vector_mean(vectors: List[Vector]) -> Vector:
"""Computers the element-wise average"""
n = len(vectors)
return scalar_multiply(1 / n, vector_sum(vectors))
assert vector_mean([[1, 2], [3, 4], [5, 6]]) == [3, 4]
벡터의 내적(dot product)
성분 별 값을 곱한 합이다. 크기가 1인 벡터 w와 v의 내적은 v가 w의 방향으로 프로젝션된 크기라고 할 수 있다.
from typing import List
Vector = List[float]
def dot(v: Vector, w: Vector) -> float:
"""Computes v_1 * w_1 + ... + v_n * w_n"""
assert len(v) == len(w), "vectors must be smame length"
return sum(v_i * w_i for v_i, w_i in zip(v, w))
assert dot([1, 2, 3], [4, 5, 6]) == 32 #fixme 1 * 4 + 2* 5 + 3* 6
벡터의 제곱의 합
from typing import List
Vector = List[float]
ef dot(v: Vector, w: Vector) -> float:
"""Computes v_1 * w_1 + ... + v_n * w_n"""
assert len(v) == len(w), "vectors must be smame length"
return sum(v_i * w_i for v_i, w_i in zip(v, w))
assert dot([1, 2, 3], [4, 5, 6]) == 32 #fixme 1 * 4 + 2* 5 + 3* 6
def sum_of_squares(v: Vector) -> float:
"""Returns v_1 * v_1 + ... + v_n * v_n"""
return dot(v, v)
assert sum_of_squares([1, 2, 3]) == 14 # 1 * 1 + 2 * 2 + 3 * 3
벡터의 크기
from typing import List
import math
Vector = List[float]
def dot(v: Vector, w: Vector) -> float:
"""Computes v_1 * w_1 + ... + v_n * w_n"""
assert len(v) == len(w), "vectors must be smame length"
return sum(v_i * w_i for v_i, w_i in zip(v, w))
assert dot([1, 2, 3], [4, 5, 6]) == 32 #fixme 1 * 4 + 2* 5 + 3* 6
def sum_of_squares(v: Vector) -> float:
"""Returns v_1 * v_1 + ... + v_n * v_n"""
return dot(v, v)
assert sum_of_squares([1, 2, 3]) == 14 #fixme 1 * 1 + 2 * 2 + 3 * 3
def magnitude(v: Vector) -> float:
"""Returns the magnitude (or Length) v"""
return math.sqrt(sum_of_squares(v))
assert magnitude([3, 4]) == 5
벡터의 거리
from typing import List
import math
Vector = List[float]
def dot(v: Vector, w: Vector) -> float:
"""Computes v_1 * w_1 + ... + v_n * w_n"""
assert len(v) == len(w), "vectors must be smame length"
return sum(v_i * w_i for v_i, w_i in zip(v, w))
assert dot([1, 2, 3], [4, 5, 6]) == 32 #fixme 1 * 4 + 2* 5 + 3* 6
def sum_of_squares(v: Vector) -> float:
"""Returns v_1 * v_1 + ... + v_n * v_n"""
return dot(v, v)
assert sum_of_squares([1, 2, 3]) == 14 # 1 * 1 + 2 * 2 + 3 * 3
def magnitude(v: Vector) -> float:
"""Returns the magnitude (or Length) v"""
return math.sqrt(sum_of_squares(v))
assert magnitude([3, 4]) == 5
def squared_distance(v: Vector, w: Vector) -> float:
"""Computes (v_1 - w_1) ** 2 + ... + (v_n - w_n) ** 2"""
return sum_of_squares(subtract(v, w))
def distance(v: Vector, w: Vector) -> float:
"""Computes the distance between v and w"""
return math.sqrt(squared_distance(v, w))
def distance2(v: Vector, w: Vector) -> float:
"""Computes the distance between v and w"""
return magnitude(subtract(v, w))
행렬
2차원으로 구성된 숫자의 집합인 list of list로 구현
Matrix = List[List[float]]
A = [[1, 2, 3,], [4, 5, 6]]
B = [[1, 2], [3, 4], [5, 6]]
행렬의 구조: n x m의 행렬의 경우, (n, m)
from typing import Tuple
Vector = List[float]
Matrix = List[List[float]]
def shape(A: Matrix) -> Tuple[int, int]:
return (len(A), len(A[0]) if A else 0)
assert shape([[1, 2, 3], [4, 5, 6]]) == (2, 3)
i번째 행 얻기
from typing import List
Vector = List[float]
Matrix = List[List[float]]
def get_row(A: Matrix, i: int) -> Vector:
"""#fixme Returns the i-th row of A(as a Vector)"""
return A[i] #fixme A[i] is already the ith row
j번째 열 얻기
from typing import List
Vector = List[float]
Matrix = List[List[float]]
def get_column(A: Matrix, j: int) -> Vector:
"""Returns the j-th column of A(as a Vector"""
return [A_i[j] for A_i in A] #fixme ith element of row A_i for each row A_i
행렬 만들기
A[i, j] 값을 f(i, j)로 생성하는 함수
from typing import List
Matrix = List[List[float]]
def make_matrix(num_rows: int, num_cols: int, entry_fn: Callable[[int, int], float]) -> Matrix:
return [[entry_fn(i, j) for i in range(num_rows)] for j in range(num_cols)]
단위행렬 만들기
from typing import List
Matrix = List[List[float]]
def identity_matrix(n: int) -> Matrix:
"""Returns the n x n identity matrix"""
return make_matrix(n, n, lambda i, j: 1 if i == j else 0)
assert identity_matrix(5) == [[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]]
통계
데이터 파악 방법
히스토그램, 통계값;최댓값: max(v: List), 최솟값: min(v: List)
중심값
평균: mean(v: List)
from typing import List
def mean(xs: List[float]) -> float:
return sum(xs) / len(xs)
중앙값
데이터 수가 홀수이면 가운데 순번의 값, 데이터 수가 짝수이면 가운데 순번 두개 값의 평균
from typing import List
def median(v: List[float]) -> float:
return sorted(v)[len(v)//2] if len(v)%2 == 1 else (sorted(v)[len(v)//2]+sorted(v)[len(v)//2-1])/2
assert median([1, 10, 2, 9, 5]) == 5
assert median([1, 9, 2, 10]) == (2 + 9) / 2
개별 값의 변화에 영향을 받지 않는 특성이 있다.
활용 : 이상치에 영향을 받지 않는 대표값을 구하고자 할 때, 소득분위 등
분위(Quantile)
from typing import List
def quantile(xs: List[float], p: float) -> float:
"""Returns the pth-percentile value in x"""
p_index = int(p * len(xs))
return sorted(xs)[p_index]
최빈값(mode)
가장 자주 나오는 값, 동일 회수일 경우 복수개가 나올 수 있다.
from typing import List
num_friends = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 6, 6]
def mode(x: List[float]) -> List[float]:
return [m for m in Counter(x).keys() if Counter(x)[m] == max(Counter(x).values())]
assert set(mode(num_friends)) == {1, 6}
산포도
- 데이터가 퍼져있는 정도. 큰 값일수록 많이 퍼진다.
- 범위 값 : 최대값 - 최소값
- 분산
- 표준편차 : 분산의 단뒤가 제곱인 점을 개선
- 분위 범위 : 이상치 값의 영향을 배제(3/4분위값 - 1/4분위값)
from typing import List
from collections import Counter
import math
# fixme import modules for sum_of_squares
from datascience.mathematics.vector import sum_of_squares
def de_mean(xs: List[float]) -> List[float]: # fixme 평균과의 차이
"""Translate xs by subtracting its mean (so the result has mean 0)"""
x_bar = mean(xs)
return [x - x_bar for x in xs]
def variance(xs: List[float]) -> float: # fixme 분산
"""Almost the average squared deviation from the mean"""
assert len(xs) >= 2, "variance requires at least two elements"
n = len(xs)
deviations = de_mean(xs)
return sum_of_squares(deviations) / (n - 1)
def standard_deviation(xs: List[float]) -> float:
"""The standard deviation is the square root of the variance"""
return math.sqrt(variance(xs))
def interquartile_range(xs: List[float]) -> float:
"""Returns the difference between the 75%-ile and the 25%-ile"""
return quantile(xs, 0.75) - quantile(xs, 0.25)
상관관계
두변수가 퍼진 경향의 표현
공분산
두 변수의 선형상 관계 표현
- Cov(X, Y) > 0 : X가 증가할 때 Y도 증가한다.
- Cov(X, Y) < 0 : X가 증가할 때 Y는 감소한다.
- Cov(X, Y) = 0 : 두 변수간에는 선형 관계가 없다.
특성 : X, Y가 독립이면, 공분산은 0
from typing import List
from datascience.mathematics.vector import dot
num_friends = [1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 6, 6]
def covariance(xs: List[float], ys: List[float]) -> float:
assert len(xs) == len(ys), "sx and ys must have same number of elements"
return dot(de_mean(xs), de_mean(ys)) / (len(xs) - 1)
assert 22.42 < covariance(num_friends, daily_minutes) < 22.43