A A
[Data Mining] Linear Algebra (μ„ ν˜•λŒ€μˆ˜)

Linear Algebra

Linear Algebra (μ„ ν˜•λŒ€μˆ˜ν•™)은 벑터 곡간, ν–‰λ ¬, μ„ ν˜• λ³€ν™˜ λ“±μ˜ κ°œλ…μ„ μ—°κ΅¬ν•˜λŠ” μˆ˜ν•™μ˜ ν•œ λΆ„μ•Όμž…λ‹ˆλ‹€
  • 주둜 닀차원 κ³΅κ°„μ—μ„œμ˜ 벑터와 ν–‰λ ¬μ˜ μ—°μ‚° 및 이듀 κ°„μ˜ 관계λ₯Ό 닀루며, 곡학, 물리학, 컴퓨터 κ³Όν•™ λ“± λ‹€μ–‘ν•œ λΆ„μ•Όμ—μ„œ μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€.
  • λ˜ν•œ λ§Žμ€ 데이터 κ³Όν•™ κ°œλ…κ³Ό κΈ°μˆ μ„ λ’·λ°›μΉ¨ν•©λ‹ˆλ‹€.
import re, math, random # regexes, math functions, random numbers
import matplotlib.pyplot as plt # pyplot
from collections import defaultdict, Counter
from functools import partial, reduce

 


Vectors

VectorsλŠ” μ–΄λ–€ finite-dimensional 곡간에 μžˆλŠ” μ μž…λ‹ˆλ‹€.
  • 데이터λ₯Ό λ²‘ν„°λ‘œ μƒκ°ν•©λ‹ˆλ‹€
  • numeric(숫자) 데이터λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 쒋은 방법 μž…λ‹ˆλ‹€.
  • 3차원 벑터(ν‚€, λͺΈλ¬΄κ²Œ, λ‚˜μ΄)
  • 4차원 λ²‘ν„°λ‘œμ„œμ˜ 학생성적(μ‹œν—˜1, μ‹œν—˜2, μ‹œν—˜3, μ‹œν—˜4)
  • 3차원 κ³΅κ°„μ˜ 벑터에 ν•΄λ‹Ήν•˜λŠ” 3개의 숫자 λͺ©λ‘
height_weight_age = [70,  # inches,
                     170, # pounds,
                     40 ] # years

grades = [95,   # exam1
          80,   # exam2
          75,   # exam3
          62 ]  # exam4

Vector에 κ΄€ν•œ Arithmetic(μ‚°μˆ )

벑터 연산을 μ •μ˜ν•©λ‹ˆλ‹€
  • 이 파이썬 μ½”λ“œλ“€μ„ μ„€λͺ…을 μœ„ν•œ μˆ˜ν•™μ  μ •μ˜λ‘œ 상상해 λ³΄μ‹­μ‹œμ˜€
  • λͺ©λ‘μ˜ μ„±λŠ₯이 ν˜•νŽΈμ—†μŠ΅λ‹ˆλ‹€
  • λŒ€μš©λŸ‰ 데이터가 μžˆλŠ” μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ numpy Arrayλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

Adding two vectors

# Jupyter Notebookμ—μ„œ κ·Έλž˜ν”„λ₯Ό 인라인 λͺ¨λ“œλ‘œ ν‘œμ‹œν•˜κΈ° μœ„ν•΄ 맀직 λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
%matplotlib inline

# ν•„μš”ν•œ 라이브러리 κ°€μ Έμ˜€κΈ°
import numpy as np  # 숫자 연산을 μœ„ν•œ numpy 라이브러리
import matplotlib.pyplot as plt  # κ·Έλž˜ν”„ μž‘μ„±μ„ μœ„ν•œ matplotlib.pyplot

# 5x5 크기의 κ·Έλž˜ν”„ 생성
plt.figure(figsize=(5, 5))

# x좕은 0λΆ€ν„° 4κΉŒμ§€, y좕은 0λΆ€ν„° 4κΉŒμ§€ μ„€μ •
plt.axis([0, 4, 0, 4])

# 벑터 v와 wλ₯Ό λ°°μ—΄λ‘œ μ •μ˜
v = np.array([1, 2])
w = np.array([2, 1])

# 벑터 vλ₯Ό νŒŒλž€μƒ‰ ν™”μ‚΄ν‘œλ‘œ ν‘œμ‹œ
plt.arrow(0, 0, v[0], v[1], head_width=0.05, head_length=0.1, fc='b', ec='b')

# 벑터 wλ₯Ό 녹색 ν™”μ‚΄ν‘œλ‘œ ν‘œμ‹œ
plt.arrow(0, 0, w[0], w[1], head_width=0.05, head_length=0.1, fc='g', ec='g')

# 벑터 v + wλ₯Ό 녹색 ν™”μ‚΄ν‘œλ‘œ ν‘œμ‹œ
# μ‹œμž‘μ μ€ 벑터 v의 끝점이며, κΈΈμ΄λŠ” 벑터 w의 κ°’κ³Ό 동일
plt.arrow(v[0], v[1], w[0], w[1], head_width=0.05, head_length=0.1, fc='g', ec='g')

# 벑터 v + wλ₯Ό 빨간색 ν™”μ‚΄ν‘œλ‘œ ν‘œμ‹œ
plt.arrow(0, 0, v[0] + w[0], v[1] + w[1], head_width=0.2, head_length=0.1, fc='r', ec='r')

# 각 λ²‘ν„°μ˜ 끝점에 라벨을 μΆ”κ°€
offset = np.array([-0.2, -0.2])
plt.annotate('v', xy=v + offset)
plt.annotate('w', xy=w + offset)
plt.annotate('v+w', xy=v + w + offset)

# κ·Έλž˜ν”„ ν‘œμ‹œ
plt.show()

def vector_add(v, w):
    """두 벑터λ₯Ό μš”μ†Œλ³„λ‘œ λ”ν•΄μ£ΌλŠ” ν•¨μˆ˜
    
    λ§€κ°œλ³€μˆ˜:
    v -- 첫 번째 벑터 (리슀트 ν˜•νƒœ), w -- 두 번째 벑터 (리슀트 ν˜•νƒœ)
    
    λ°˜ν™˜κ°’:
    두 λ²‘ν„°μ˜ 각 μš”μ†Œλ₯Ό λ”ν•œ κ²°κ³Ό 벑터 (리슀트 ν˜•νƒœ)
    """
    # zip ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 λ²‘ν„°μ˜ μš”μ†Œλ₯Ό 쌍으둜 λ¬ΆμŠ΅λ‹ˆλ‹€.
    # 각 μš”μ†Œ 쌍 v_i, w_i에 λŒ€ν•΄ μš”μ†Œλ³„λ‘œ λ”ν•œ 값을 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    return [v_i + w_i for v_i, w_i in zip(v, w)]
def vector_subtract(v, w):
    """두 벑터λ₯Ό μš”μ†Œλ³„λ‘œ λΉΌμ£ΌλŠ” ν•¨μˆ˜
    
    λ§€κ°œλ³€μˆ˜:
    v -- 첫 번째 벑터 (리슀트 ν˜•νƒœ) w -- 두 번째 벑터 (리슀트 ν˜•νƒœ)
    
    λ°˜ν™˜κ°’:
    두 λ²‘ν„°μ˜ 각 μš”μ†Œλ₯Ό λΊ€ κ²°κ³Ό 벑터 (리슀트 ν˜•νƒœ)
    """
    # zip ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 λ²‘ν„°μ˜ μš”μ†Œλ₯Ό 쌍으둜 λ¬ΆμŠ΅λ‹ˆλ‹€.
    # 각 μš”μ†Œ 쌍 v_i, w_i에 λŒ€ν•΄ μš”μ†Œλ³„λ‘œ λΉΌλŠ” 값을 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    return [v_i - w_i for v_i, w_i in zip(v, w)]
def vector_sum(vectors):
    """λ²‘ν„°μ˜ 리슀트λ₯Ό μž…λ ₯λ°›μ•„ λͺ¨λ“  λ²‘ν„°μ˜ μš”μ†Œλ³„ 합을 κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜
    
    λ§€κ°œλ³€μˆ˜:
    vectors -- λ²‘ν„°μ˜ 리슀트
    
    λ°˜ν™˜κ°’:
    λ²‘ν„°μ˜ μš”μ†Œλ³„ ν•© (리슀트 ν˜•νƒœ)
    """
    # functools.reduce ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ `vector_add` ν•¨μˆ˜λ₯Ό ν™œμš©ν•΄ 벑터λ₯Ό μš”μ†Œλ³„λ‘œ ν•©ν•©λ‹ˆλ‹€.
    return reduce(vector_add, vectors)
def scalar_multiply(c, v):
    """μŠ€μΉΌλΌμ™€ λ²‘ν„°μ˜ μš”μ†Œλ³„ 곱을 κ³„μ‚°ν•˜λŠ” ν•¨μˆ˜
    
    λ§€κ°œλ³€μˆ˜:
    c -- 슀칼라 (μˆ«μžν˜•), v -- 벑터 (리슀트 ν˜•νƒœ)
    
    λ°˜ν™˜κ°’:
    슀칼라 c와 벑터 v의 각 μš”μ†Œλ₯Ό κ³±ν•œ κ²°κ³Ό 벑터 (리슀트 ν˜•νƒœ)
    """
    # 벑터 v의 각 μš”μ†Œ v_i에 슀칼라 cλ₯Ό κ³±ν•˜μ—¬ 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    return [c * v_i for v_i in v]
def vector_mean(vectors):
    """μž…λ ₯ λ²‘ν„°μ˜ i번째 μš”μ†Œμ˜ 평균을 κ³„μ‚°ν•˜μ—¬ μƒˆλ‘œμš΄ 벑터λ₯Ό μƒμ„±ν•˜λŠ” ν•¨μˆ˜
    
    λ§€κ°œλ³€μˆ˜:
    vectors -- λ²‘ν„°μ˜ 리슀트
    
    λ°˜ν™˜κ°’:
    각 λ²‘ν„°μ˜ μš”μ†Œλ³„ 평균을 κ³„μ‚°ν•˜μ—¬ 얻은 μƒˆλ‘œμš΄ 벑터 (리슀트 ν˜•νƒœ)
    """
    n = len(vectors)  # λ²‘ν„°μ˜ λ¦¬μŠ€νŠΈμ— μžˆλŠ” λ²‘ν„°μ˜ 수
    # λ²‘ν„°λ“€μ˜ μš”μ†Œλ³„ 평균을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄ λ¨Όμ € λ²‘ν„°μ˜ 합을 κ΅¬ν•˜κ³ ,
    # 슀칼라 1/n을 κ³±ν•˜μ—¬ 평균을 κ΅¬ν•©λ‹ˆλ‹€.
    return scalar_multiply(1/n, vector_sum(vectors))

Numpy Version

# numpy λ²„μ „μ˜ 벑터 μ—°μ‚° ν•¨μˆ˜
import numpy as np

# μ„Έ 개의 벑터λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
u = np.array([1,1,1])
v = np.array([1,0,0])
w = np.array([0,1,0])

print(v + w)  # 벑터 v와 wλ₯Ό λ”ν•©λ‹ˆλ‹€.
print(v - w)  # 벑터 vμ—μ„œ wλ₯Ό λΊλ‹ˆλ‹€.
vs = np.array([u, v, w])  # u, v, w μ„Έ 개의 벑터λ₯Ό 묢은 배열을 λ§Œλ“­λ‹ˆλ‹€.

print(np.sum(vs, axis=0))  # vs λ°°μ—΄μ˜ 각 μ—΄μ˜ 합을 κ³„μ‚°ν•©λ‹ˆλ‹€.
# axis=0을 μ‚¬μš©ν•˜λ©΄ 각 λ²‘ν„°μ˜ μš”μ†Œλ₯Ό ν•©μ³μ„œ ν•˜λ‚˜μ˜ λ²‘ν„°λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.

print(10 * v)  # 벑터 v에 슀칼라 10을 κ³±ν•©λ‹ˆλ‹€.
print(np.mean(vs, axis=0))  # vs λ°°μ—΄μ˜ 각 μ—΄μ˜ 평균을 κ³„μ‚°ν•©λ‹ˆλ‹€.
# axis=0을 μ‚¬μš©ν•˜λ©΄ 각 λ²‘ν„°μ˜ μš”μ†Œλ₯Ό ν•©μ³μ„œ ν•˜λ‚˜μ˜ λ²‘ν„°λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
[1 1 0]
[ 1 -1  0]
[2 2 1]
[10  0  0]
[0.66666667 0.66666667 0.33333333]

 

def dot(v, w):
    """v_1 * w_1 + ... + v_n * w_n ν˜•νƒœμ˜ 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return sum(v_i * w_i for v_i, w_i in zip(v, w))

def sum_of_squares(v):
    """v_1 * v_1 + ... + v_n * v_n ν˜•νƒœμ˜ μ œκ³±ν•©μ„ κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return dot(v, v)

def magnitude(v):
    """λ²‘ν„°μ˜ μ œκ³±ν•©μ„ κ³„μ‚°ν•œ ν›„ μ œκ³±κ·Όμ„ κ΅¬ν•©λ‹ˆλ‹€."""
    return math.sqrt(sum_of_squares(v))
  • dot(v, w) ν•¨μˆ˜λŠ” 두 벑터 v와 w의 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€. 각 μš”μ†Œ v_i와 w_i의 곱을 κ³„μ‚°ν•œ ν›„ λͺ¨λ‘ ν•©ν•©λ‹ˆλ‹€.
  • sum_of_squares(v) ν•¨μˆ˜λŠ” 벑터 v의 μ œκ³±ν•©μ„ κ³„μ‚°ν•©λ‹ˆλ‹€. 벑터 v와 μžμ‹ κ³Όμ˜ 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€.
  • magnitude(v) ν•¨μˆ˜λŠ” 벑터 v의 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    • sum_of_squares(v) ν•¨μˆ˜λ‘œ κ³„μ‚°ν•œ μ œκ³±ν•©μ˜ μ œκ³±κ·Όμ„ κ³„μ‚°ν•˜μ—¬ λ²‘ν„°μ˜ 크기λ₯Ό κ΅¬ν•©λ‹ˆλ‹€.

 

v = np.array([1,0,0])    # 벑터 vλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
w = np.array([0,1,0])    # 벑터 wλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

print(np.dot(v,w))       # 벑터 v와 w의 내적
print(v.dot(w))          # 벑터 v와 w의 내적
print(np.dot(v,v))       # 벑터 v의 μ œκ³±ν•©
print(np.sqrt(np.dot(v,v)))  # 벑터 v의 크기
print(np.linalg.norm(v))  # 벑터 v의 크기
0
0
1
1.0
1.0
  • np.dot(v, w)와 v.dot(w)λŠ” 벑터 v와 w의 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€. 두 λ²‘ν„°λŠ” μ§κ΅ν•˜λ―€λ‘œ κ²°κ³ΌλŠ” 0μž…λ‹ˆλ‹€.
  • np.dot(v, v)λŠ” 벑터 v의 각 μš”μ†Œλ₯Ό μ œκ³±ν•œ ν›„ λ”ν•˜μ—¬ 벑터 v의 μ œκ³±ν•©μ„ κ³„μ‚°ν•©λ‹ˆλ‹€. κ²°κ³ΌλŠ” 1μž…λ‹ˆλ‹€.
  • np.sqrt(np.dot(v, v))λŠ” 벑터 v의 μ œκ³±ν•©μ„ κ³„μ‚°ν•œ ν›„, μ œκ³±κ·Όμ„ κ΅¬ν•˜μ—¬ 벑터 v의 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. κ²°κ³ΌλŠ” 1.0μž…λ‹ˆλ‹€.
  • np.linalg.norm(v)λŠ” np.linalg.norm() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 벑터 v의 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    • κ²°κ³ΌλŠ” 1.0으둜 np.sqrt(np.dot(v, v))의 결과와 λ™μΌν•©λ‹ˆλ‹€.

Vector Projection으둜 Dot Product(점 곱)

μ„€λͺ… → 𝐯's projection on 𝐰: 𝐯1
  • v1 = v⋅w / |w|² * w:
    • v1: 벑터 v의 벑터 w에 λŒ€ν•œ 투영 λ²‘ν„°μž…λ‹ˆλ‹€. 즉, vκ°€ 벑터 w와 같은 λ°©ν–₯으둜 투영된 λ²‘ν„°μž…λ‹ˆλ‹€.
    • v⋅w: 벑터 v와 w의 내적(dot product)μž…λ‹ˆλ‹€. μ΄λŠ” 두 벑터 μ‚¬μ΄μ˜ 각도에 따라 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
    • |w|²: 벑터 w의 크기(μ ˆλŒ€κ°’)인 |w|의 μ œκ³±μž…λ‹ˆλ‹€.
    • w: 벑터 w μžμ²΄μž…λ‹ˆλ‹€.
  • μœ„ 식은 벑터 v의 벑터 w에 λŒ€ν•œ νˆ¬μ˜μ„ κ³„μ‚°ν•©λ‹ˆλ‹€. 투영된 벑터 v1λŠ” 벑터 w와 같은 λ°©ν–₯의 벑터이며, ν¬κΈ°λŠ” v⋅w / |w|²μž…λ‹ˆλ‹€.
  • μ‹μ˜ μž‘λ™ 방식은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
    1. v와 w의 내적을 κ³„μ‚°ν•˜μ—¬ 두 벑터 μ‚¬μ΄μ˜ 관계λ₯Ό μΈ‘μ •ν•©λ‹ˆλ‹€. μ΄λŠ” 벑터 vκ°€ 벑터 w와 μ–΄λŠ 정도 λ°©ν–₯이 같은지λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    2. 이 값을 벑터 w의 크기의 제곱(즉, |w|²)으둜 λ‚˜λˆ„μ–΄ μ •κ·œν™”ν•©λ‹ˆλ‹€.
    3. 이 값에 벑터 wλ₯Ό κ³±ν•˜μ—¬ 벑터 v1λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
def squared_distance(v, w):
    """두 벑터 v와 w μ‚¬μ΄μ˜ 제곱 거리(squared distance)λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return sum_of_squares(vector_subtract(v, w))
   
  • vector_subtract(v, w)λŠ” 벑터 vμ—μ„œ 벑터 wλ₯Ό λΊ€ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
  • sum_of_squares(vector_subtract(v, w))λŠ” μœ„μ˜ κ²°κ³Ό λ²‘ν„°μ˜ 각 μš”μ†Œλ₯Ό μ œκ³±ν•˜κ³  λͺ¨λ‘ ν•©ν•œ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • 이λ₯Ό 톡해 두 벑터 μ‚¬μ΄μ˜ 제곱 거리λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.

Euclidean Distance between two vectors

μ„€λͺ… → Euclidean Distance between two vectors: 𝐩,πͺ
  • 벑터 p와 qκ°€ 각각 λ‹€μŒκ³Ό 같은 μ’Œν‘œλ₯Ό 가진닀고 κ°€μ •ν•©λ‹ˆλ‹€.
  • p = [p1,p2,...,pn]
  • [𝑝1,𝑝2,...,𝑝𝑛]
  • q = [q1,q2,...,qn]
  • [π‘ž1,π‘ž2,...,π‘žπ‘›]
  • 이 λ•Œ, p와 q μ‚¬μ΄μ˜ μœ ν΄λ¦¬λ“œ κ±°λ¦¬λŠ” λ‹€μŒκ³Ό 같이 계산할 수 μžˆμŠ΅λ‹ˆλ‹€:

  • μ΄λŠ” 두 벑터 μ‚¬μ΄μ˜ 각 μ’Œν‘œ 차이의 μ œκ³±μ„ λͺ¨λ‘ λ”ν•œ ν›„, κ·Έ κ°’μ˜ μ œκ³±κ·Όμ„ μ·¨ν•œ κ²ƒμž…λ‹ˆλ‹€.
  • λ‹€λ₯Έ ν‘œν˜„μœΌλ‘œ, 두 벑터 μ‚¬μ΄μ˜ μœ ν΄λ¦¬λ“œ κ±°λ¦¬λŠ” 두 벑터 p와 q의 차이 벑터λ₯Ό κ΅¬ν•œ ν›„, κ·Έ 차이 λ²‘ν„°μ˜ 크기λ₯Ό κ³„μ‚°ν•œ 값이라고도 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
  • distance = βˆ₯𝑝−π‘žβˆ₯
def distance(v, w):
    """두 벑터 v와 w μ‚¬μ΄μ˜ μœ ν΄λ¦¬λ“œ 거리λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return math.sqrt(squared_distance(v, w))
  • squared_distance(v, w) ν•¨μˆ˜λŠ” v와 w μ‚¬μ΄μ˜ 제곱 거리λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • math.sqrtλŠ” μœ„μ—μ„œ κ³„μ‚°λœ 제곱 거리λ₯Ό μ œκ³±κ·Όμ„ κ΅¬ν•˜μ—¬ μœ ν΄λ¦¬λ“œ 거리λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • 이 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 벑터 μ‚¬μ΄μ˜ 거리λ₯Ό μΈ‘μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Manhattan distance

λ§¨ν•΄νŠΌ 거리(Manhattan distance)λŠ” 두 벑터 λ˜λŠ” 두 점 μ‚¬μ΄μ˜ 거리λ₯Ό κ³„μ‚°ν•˜λŠ” 방법 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.
  • κ±°λ¦¬λŠ” 각 μ’Œν‘œ 차이의 μ ˆλŒ€κ°’μ„ ν•©ν•˜μ—¬ κ³„μ‚°ν•©λ‹ˆλ‹€. λ§¨ν•΄νŠΌ κ±°λ¦¬λŠ” μ§μ„ μœΌλ‘œλ§Œ 이동할 수 μžˆλŠ” 도심(Manhattan) κ±°λ¦¬μ—μ„œ λΉ„λ‘―λœ μ΄λ¦„μœΌλ‘œ, μΆ•λ°©ν–₯ 거리(axis-aligned distance)라고도 ν•©λ‹ˆλ‹€.
  • 두 벑터 p와 qκ°€ λ‹€μŒκ³Ό 같은 μ’Œν‘œλ₯Ό 가진닀고 κ°€μ •ν•©λ‹ˆλ‹€:
  • p = [p1,p2,...,pn]
  • [𝑝1,𝑝2,...,𝑝𝑛]
  • q = [q1,q2,...,qn]
  • [π‘ž1,π‘ž2,...,π‘žπ‘›]
  • 이 λ•Œ, p와 q μ‚¬μ΄μ˜ λ§¨ν•΄νŠΌ κ±°λ¦¬λŠ” λ‹€μŒκ³Ό 같이 계산할 수 μžˆμŠ΅λ‹ˆλ‹€:

  • μ΄λŠ” 두 벑터 μ‚¬μ΄μ˜ 각 μ’Œν‘œ 차이의 μ ˆλŒ€κ°’μ„ λͺ¨λ‘ ν•©ν•œ κ²ƒμž…λ‹ˆλ‹€.
def manhattan_distance(v, w):
    """두 벑터 v와 w μ‚¬μ΄μ˜ λ§¨ν•΄νŠΌ 거리λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return sum(math.fabs(v_i - w_i) for v_i, w_i in zip(v, w))
  • zip(v, w)λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 벑터 v와 w의 μš”μ†Œλ₯Ό 쌍으둜 짝지어 μˆœνšŒν•©λ‹ˆλ‹€.
  • v_i와 w_i의 μ ˆλŒ€κ°’ 차이λ₯Ό κ³„μ‚°ν•˜κ³ , μ΄λŸ¬ν•œ μ°¨μ΄λ“€μ˜ 합을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • λ§¨ν•΄νŠΌ κ±°λ¦¬λŠ” 각 μ°¨μ›μ—μ„œ 두 벑터 μ‚¬μ΄μ˜ μ ˆλŒ€ 차이의 합을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • 이 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 벑터 μ‚¬μ΄μ˜ λ§¨ν•΄νŠΌ 거리λ₯Ό μΈ‘μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Cosine similarity

코사인 μœ μ‚¬λ„(Cosine similarity)λŠ” 두 벑터 μ‚¬μ΄μ˜ λ°©ν–₯성을 λΉ„κ΅ν•˜λŠ” μ²™λ„μž…λ‹ˆλ‹€.
  • 이 μ²™λ„λŠ” 두 벑터 μ‚¬μ΄μ˜ 코사인 각도(cosine of the angle)λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 λ²‘ν„°μ˜ μœ μ‚¬λ„λ₯Ό μΈ‘μ •ν•©λ‹ˆλ‹€.
  • μœ μ‚¬λ„λŠ” 두 벑터가 μ„œλ‘œ μ–Όλ§ˆλ‚˜ λΉ„μŠ·ν•œ λ°©ν–₯을 가지고 μžˆλŠ”μ§€ λ‚˜νƒ€λ‚΄λ©°, -1μ—μ„œ 1 μ‚¬μ΄μ˜ 값을 κ°€μ§‘λ‹ˆλ‹€.
  • 코사인 μœ μ‚¬λ„λŠ” λ‹€μŒκ³Ό 같이 계산할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • v⋅w: 벑터 v와 w의 내적(dot product)μž…λ‹ˆλ‹€. μ΄λŠ” 두 λ²‘ν„°μ˜ 각 μ’Œν‘œλ₯Ό κ³±ν•œ ν›„ λͺ¨λ‘ λ”ν•œ κ°’μž…λ‹ˆλ‹€.
  • βˆ₯𝑣βˆ₯βˆ₯vβˆ₯와 βˆ₯𝑀βˆ₯: 각각 벑터 v와 w의 크기(μ ˆλŒ€κ°’)μž…λ‹ˆλ‹€. λ²‘ν„°μ˜ ν¬κΈ°λŠ” 각 μ’Œν‘œμ˜ μ œκ³±ν•©μ˜ 제곱근으둜 κ³„μ‚°ν•©λ‹ˆλ‹€.
  • λΆ„λͺ¨λŠ” 두 λ²‘ν„°μ˜ 크기λ₯Ό κ³±ν•œ 값이며, λΆ„μžλŠ” 두 λ²‘ν„°μ˜ λ‚΄μ μž…λ‹ˆλ‹€.

코사인 μœ μ‚¬λ„λŠ” -1μ—μ„œ 1 μ‚¬μ΄μ˜ 값을 κ°€μ§‘λ‹ˆλ‹€.

1: 두 벑터가 μ™„μ „νžˆ 같은 λ°©ν–₯을 가지고 μžˆμŠ΅λ‹ˆλ‹€.
0: 두 벑터가 수직(직각) λ°©ν–₯μž…λ‹ˆλ‹€.
-1: 두 벑터가 μ™„μ „νžˆ λ°˜λŒ€ λ°©ν–₯μž…λ‹ˆλ‹€.
def cosine_similarity(v, w):
    """두 벑터 v와 w μ‚¬μ΄μ˜ 코사인 μœ μ‚¬λ„λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return dot(v, w) / (magnitude(v) * magnitude(w))

v = [0,1,1,0]
w = [0,100,100,0]
u = [1,0,0,1]
y = [-1,0,0,-1]

print(cosine_similarity(v, w))
print(cosine_similarity(u, v))
print(cosine_similarity(u,y)
0.9999999999999999
0.0
-0.9999999999999998
  • dot(v, w)λŠ” v와 w의 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€.
  • magnitude(v)와 magnitude(w)λŠ” 각각 v와 w의 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • 코사인 μœ μ‚¬λ„λŠ” 두 λ²‘ν„°μ˜ 내적을 각 λ²‘ν„°μ˜ 크기λ₯Ό κ³±ν•œ κ°’μœΌλ‘œ λ‚˜λˆˆ κ°’μž…λ‹ˆλ‹€.
  • 이 값은 두 λ²‘ν„°μ˜ λ°©ν–₯이 μ–Όλ§ˆλ‚˜ μœ μ‚¬ν•œμ§€(각도가 μ–Όλ§ˆλ‚˜ μž‘μ€μ§€)λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • 코사인 μœ μ‚¬λ„μ˜ 값은 -1μ—μ„œ 1κΉŒμ§€μ˜ λ²”μœ„λ₯Ό 가지며, 1에 κ°€κΉŒμšΈμˆ˜λ‘ 두 λ²‘ν„°μ˜ λ°©ν–₯이 μœ μ‚¬ν•¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

Numpy Version

import numpy as np

v = np.array([1,1])
w = np.array([10,10])

print(np.dot(v - w, v - w)) # 제곱 거리
print(np.sqrt(np.dot(v - w, v - w))) # μœ ν΄λ¦¬λ“œ 거리
print(np.sum(np.fabs(v - w))) # λ§¨ν•΄νŠΌ 거리
print(np.dot(v, w) / (np.sqrt(np.dot(v, v)) * np.sqrt(np.dot(w, w)))) # 코사인 μœ μ‚¬λ„
162
12.727922061357855
18.0
0.9999999999999998
  • λ¬Έμ„œ λ²‘ν„°μ—μ„œ λͺ¨λ“  ꡬ성 μš”μ†Œκ°€ μŒμˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ 코사인 μœ μ‚¬λ„λŠ” 0κ³Ό 1 사이이며 μ½”μ‚¬μΈκ±°λ¦¬λŠ” μ•„λž˜μ˜ μ½”λ“œμ²˜λŸΌ ν‘œν˜„λ©λ‹ˆλ‹€.
cosine_distance(v, w) = 1 - cosine_similarity(v, w)
def cosine_distance(v, w):
    """벑터 v와 w μ‚¬μ΄μ˜ 코사인 거리λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€."""
    return 1 - cosine_similarity(v, w)

Matrics (ν–‰λ ¬)

ν–‰λ ¬(Matrix)은 μˆ˜ν•™ 및 κ³΅ν•™μ—μ„œ μ€‘μš”ν•œ λ„κ΅¬λ‘œ, μˆ«μžλ‚˜ λ³€μˆ˜μ˜ μ§μ‚¬κ°ν˜• 배열을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • 행렬은 λ‹€μ–‘ν•œ μ—°μ‚°κ³Ό λ³€ν™˜μ„ ν‘œν˜„ν•˜λŠ” 데 μ‚¬μš©λ˜λ©°, μ„ ν˜• λŒ€μˆ˜ν•™μ˜ 핡심 κ°œλ… 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.
  • 행렬을 λͺ©λ‘μœΌλ‘œ ν‘œμ‹œν•©λ‹ˆλ‹€
  • Aκ°€ 행렬이면 A[i][j]λŠ” i번째 ν–‰κ³Ό j번째 열에 μžˆλŠ” μ›μ†Œμž…λ‹ˆλ‹€.
A = [[1, 2, 3],
     [4, 5, 6]] # A has 2 rows and 3 columns

B = [[1, 2],
     [3, 4],
     [5, 6]] # B has 3 rows and 2 columns
  • λ§Œμ•½μ— 1,000λͺ…μ˜ ν‚€, λͺΈλ¬΄κ²Œ, 그리고 λ‚˜μ΄μ˜ 데이터λ₯Ό 가지고 μžˆλ‹€λ©΄, 그것을 행렬에 넣을 수 μžˆμŠ΅λ‹ˆλ‹€:
data = [[70, 170, 40],
        [65, 120, 26],
        [77, 250, 19],
        # ....
       ]
def shape(A):
    # ν–‰λ ¬ A의 ν–‰κ³Ό μ—΄ 수λ₯Ό λ°˜ν™˜
    num_rows = len(A)
    num_cols = len(A[0]) if A else 0
    return num_rows, num_cols

def get_row(A, i):
    # ν–‰λ ¬ A의 i번째 행을 λ°˜ν™˜
    return A[i]

def get_column(A, j):
    # ν–‰λ ¬ A의 j번째 열을 λ°˜ν™˜
    return [A_i[j] for A_i in A]

def make_matrix(num_rows, num_cols, entry_fn):
    # 주어진 크기의 행렬을 μƒμ„±ν•˜κ³  entry_fn에 따라 채움
    return [[entry_fn(i, j) for j in range(num_cols)]
            for i in range(num_rows)]

def is_diagonal(i, j):
    # λŒ€κ°μ„ μ— ν•΄λ‹Ήν•˜λŠ” 경우 1, κ·Έ μ™Έμ—λŠ” 0을 λ°˜ν™˜
    return 1 if i == j else 0

identity_matrix = make_matrix(5, 5, is_diagonal)  # 5x5 ν•­λ“± ν–‰λ ¬ 생성

import random
random_matrix = make_matrix(5, 5, lambda i, j: random.choice([0, 1]))  # 5x5 랜덀 ν–‰λ ¬ 생성
random_matrix
[[0, 1, 1, 1, 0],
 [0, 0, 1, 0, 1],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [1, 0, 0, 0, 1]]
  • shape(A):
    • μ—­ν• : ν–‰λ ¬ A의 ν–‰κ³Ό μ—΄μ˜ 수λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • μ‚¬μš©: ν–‰λ ¬μ˜ 크기λ₯Ό μ•Œκ³  싢을 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • get_row(A, i):
    • μ—­ν• : ν–‰λ ¬ A의 i번째 행을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • μ‚¬μš©: ν–‰λ ¬μ˜ νŠΉμ • 행을 μΆ”μΆœν•˜κ³ μž ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • get_column(A, j):
    • μ—­ν• : ν–‰λ ¬ A의 j번째 열을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • μ‚¬μš©: ν–‰λ ¬μ˜ νŠΉμ • 열을 μΆ”μΆœν•˜κ³ μž ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • make_matrix(num_rows, num_cols, entry_fn):
    • μ—­ν• : num_rows x num_cols 크기의 행렬을 μƒμ„±ν•©λ‹ˆλ‹€. ν–‰λ ¬μ˜ 각 μš”μ†ŒλŠ” entry_fn ν•¨μˆ˜μ— μ˜ν•΄ μ±„μ›Œμ§‘λ‹ˆλ‹€.
    • μ‚¬μš©: 주어진 크기의 행렬을 νŠΉμ •ν•œ κ·œμΉ™μ— 따라 μƒμ„±ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • is_diagonal(i, j):
    • μ—­ν• : 인덱슀 i와 jκ°€ 같은 경우 1을 λ°˜ν™˜ν•˜κ³ , λ‹€λ₯΄λ©΄ 0을 λ°˜ν™˜ν•©λ‹ˆλ‹€. λŒ€κ°μ„ μ— μžˆλŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.
    • μ‚¬μš©: ν–‰λ ¬μ˜ λŒ€κ°μ„  뢀뢄을 μ±„μš°λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
  • identity_matrix:
    • μ—­ν• : make_matrix ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ 5x5 크기의 ν•­λ“± 행렬을 μƒμ„±ν•©λ‹ˆλ‹€.
    • μ‚¬μš©: ν•­λ“± 행렬을 μƒμ„±ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.
  • random_matrix:
    • μ—­ν• : make_matrix ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ 5x5 크기의 랜덀 행렬을 μƒμ„±ν•©λ‹ˆλ‹€. 각 μš”μ†ŒλŠ” 0 λ˜λŠ” 1둜 λ¬΄μž‘μœ„λ‘œ μ±„μ›Œμ§‘λ‹ˆλ‹€.
    • μ‚¬μš©: 랜덀 행렬을 μƒμ„±ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

Numpy Version

A = np.array([[1, 2, 3],
               [4, 5, 6]])

B = np.array([[1, 2],
               [3, 4],
               [5, 6]])
A.shape    # ν–‰κ³Ό μ—΄μ˜ 개수λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
A[1, :]    # ν–‰ 1의 λͺ¨λ“  μ—΄ μš”μ†Œλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
A[:, 1]    # μ—΄ 1의 λͺ¨λ“  ν–‰ μš”μ†Œλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
np.eye(5, 5) # 5x5 λ‹¨μœ„ν–‰λ ¬μ„ μƒμ„±ν•©λ‹ˆλ‹€.

# 5x5 크기의 행렬을 [0,1] μ€‘μ—μ„œ λ¬΄μž‘μœ„λ‘œ μ„ νƒν•˜μ—¬ μƒμ„±ν•©λ‹ˆλ‹€.
np.array([np.random.choice([0, 1]) for _ in np.arange(25)]).reshape(5, 5)

# 5x5 크기의 행렬을 λ¬΄μž‘μœ„λ‘œ μƒμ„±ν•˜κ³ , 각 μš”μ†Œλ₯Ό 0.5 이상인지λ₯Ό νŒλ‹¨ν•˜μ—¬ 0 λ˜λŠ” 1둜 λ³€ν™˜ν•©λ‹ˆλ‹€.
np.vectorize(np.int)(np.random.rand(25) >= 0.5).reshape(5, 5)
array([[1, 1, 0, 0, 0],
       [0, 0, 1, 0, 1],
       [1, 1, 0, 0, 0],
       [0, 0, 1, 1, 0],
       [1, 0, 0, 1, 1]])
  • dot(v, w)λŠ” v와 w의 내적을 κ³„μ‚°ν•©λ‹ˆλ‹€.
  • magnitude(v)와 magnitude(w)λŠ” 각각 v와 w의 크기λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
  • 코사인 μœ μ‚¬λ„λŠ” 두 λ²‘ν„°μ˜ 내적을 각 λ²‘ν„°μ˜ 크기λ₯Ό κ³±ν•œ κ°’μœΌλ‘œ λ‚˜λˆˆ κ°’μž…λ‹ˆλ‹€.
  • 이 값은 두 λ²‘ν„°μ˜ λ°©ν–₯이 μ–Όλ§ˆλ‚˜ μœ μ‚¬ν•œμ§€(각도가 μ–Όλ§ˆλ‚˜ μž‘μ€μ§€)λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • 코사인 μœ μ‚¬λ„μ˜ 값은 -1μ—μ„œ 1κΉŒμ§€μ˜ λ²”μœ„λ₯Ό 가지며, 1에 κ°€κΉŒμšΈμˆ˜λ‘ 두 λ²‘ν„°μ˜ λ°©ν–₯이 μœ μ‚¬ν•¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

Two representations for friendships

  • representation in Chapter 1
friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 4),
               (4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]
  • Alternative notation
#          user 0  1  2  3  4  5  6  7  8  9
#
friendships = [[0, 1, 1, 0, 0, 0, 0, 0, 0, 0], # user 0
               [1, 0, 1, 1, 0, 0, 0, 0, 0, 0], # user 1
               [1, 1, 0, 1, 0, 0, 0, 0, 0, 0], # user 2
               [0, 1, 1, 0, 1, 0, 0, 0, 0, 0], # user 3
               [0, 0, 0, 1, 0, 1, 0, 0, 0, 0], # user 4
               [0, 0, 0, 0, 1, 0, 1, 1, 0, 0], # user 5
               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 6
               [0, 0, 0, 0, 0, 1, 0, 0, 1, 0], # user 7
               [0, 0, 0, 0, 0, 0, 1, 1, 0, 1], # user 8
               [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]] # user 9
friendships[0][2] == 1     # True, 0κ³Ό 2λŠ” μΉœκ΅¬μž…λ‹ˆλ‹€
friendships[0][8] == 1     # False, 0, 8은 μΉœκ΅¬κ°€ μ•„λ‹™λ‹ˆλ‹€
False
friends_of_five = [i                                              # only need
                   for i, is_friend in enumerate(friendships[5])  # to look at
                   if is_friend]                                  # one row

print(friends_of_five)
[4, 6, 7]

Numpy Version

friendships = np.array(friendships)  # 친ꡬ 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 2D 배열을 λ§Œλ“­λ‹ˆλ‹€.

# 0κ³Ό 2κ°€ μΉœκ΅¬μΈμ§€ ν™•μΈν•©λ‹ˆλ‹€. (0ν–‰, 2μ—΄ 값이 1이면 True)
print(friendships[0, 2] == 1)            

# 0κ³Ό 8이 μΉœκ΅¬μΈμ§€ ν™•μΈν•©λ‹ˆλ‹€. (0ν–‰, 8μ—΄ 값이 1이면 True)
print(friendships[0, 8] == 1)            

# 5의 친ꡬ λͺ©λ‘μ„ κ°€μ Έμ˜΅λ‹ˆλ‹€. (5ν–‰μ˜ κ°’ 쀑 1인 μš”μ†Œλ“€μ˜ 인덱슀λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.)
print(np.argwhere(friendships[5] == 1))  
array([[4],
       [6],
       [7]], dtype=int64)

Matrix Addition

def matrix_add(A, B):
    # 두 ν–‰λ ¬μ˜ 크기가 λ‹€λ₯Έ 경우 μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.
    if shape(A) != shape(B):
        raise ArithmeticError("cannot add matrices with different shapes")
    
    # ν–‰λ ¬ A와 B의 크기λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
    num_rows, num_cols = shape(A)
    
    # 각 μœ„μΉ˜μ˜ μš”μ†Œλ“€μ„ λ”ν•˜μ—¬ μƒˆλ‘œμš΄ 행렬을 μƒμ„±ν•©λ‹ˆλ‹€.
    def entry_fn(i, j): return A[i][j] + B[i][j]
    
    # `make_matrix` ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ κ²°κ³Ό 행렬을 μƒμ„±ν•©λ‹ˆλ‹€.
    return make_matrix(num_rows, num_cols, entry_fn)
  • shape(A) != shape(B): ν–‰λ ¬ A와 B의 크기λ₯Ό λΉ„κ΅ν•©λ‹ˆλ‹€. 크기가 λ‹€λ₯΄λ©΄ μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.
  • num_rows, num_cols = shape(A): ν–‰λ ¬ A의 ν–‰κ³Ό μ—΄μ˜ 수λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
  • def entry_fn(i, j): return A[i][j] + B[i][j]: 각 μœ„μΉ˜ (i, j)μ—μ„œ A와 B의 μš”μ†Œλ₯Ό λ”ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
  • return make_matrix(num_rows, num_cols, entry_fn): make_matrix ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ κ²°κ³Ό 행렬을 μƒμ„±ν•©λ‹ˆλ‹€.

Numpy Version

A = np.array([[1,1],[2,2]])
B = np.array([[3,3],[4,4]])
print(A + B)     # ν–‰λ ¬ A와 B의 μš”μ†Œλ³„ λ§μ…ˆ (μ›μ†Œλ³„ λ§μ…ˆ)
print(A * B)     # ν–‰λ ¬ A와 B의 μš”μ†Œλ³„ κ³±μ…ˆ (μ›μ†Œλ³„ κ³±μ…ˆ)
print(np.transpose(A))              # ν–‰λ ¬ A의 μ „μΉ˜ (ν–‰κ³Ό 열을 뒀집은 ν˜•νƒœ)
print(A.T)                          # ν–‰λ ¬ A의 μ „μΉ˜ (np.transpose(A)와 동일)
print(A.dot(B))                     # ν–‰λ ¬ A와 B의 ν–‰λ ¬ κ³±μ…ˆ
print(np.matmul(A, B))              # ν–‰λ ¬ A와 B의 ν–‰λ ¬ κ³±μ…ˆ (A.dot(B)와 동일)
C = np.array([[1., 2.], [3., 4.]])
print(np.linalg.det(C))             # ν–‰λ ¬ C의 행렬식 (determinant)
print(np.linalg.inv(C))             # ν–‰λ ¬ C의 μ—­ν–‰λ ¬ (inverse)
print(C.dot(np.linalg.inv(C)))      # ν–‰λ ¬ C와 C의 μ—­ν–‰λ ¬μ˜ κ³±μ…ˆ (κ²°κ³ΌλŠ” λ‹¨μœ„ ν–‰λ ¬)
print(np.linalg.eig(C))             # ν–‰λ ¬ C의 κ³ μœ κ°’κ³Ό κ³ μœ λ²‘ν„° (eigenvalues and eigenvectors)
[[4 4]
 [6 6]]
[[3 3]
 [8 8]]
[[1 2]
 [1 2]]
[[1 2]
 [1 2]]
[[ 7  7]
 [14 14]]
[[ 7  7]
 [14 14]]
-2.0000000000000004
[[-2.   1. ]
 [ 1.5 -0.5]]
[[1.00000000e+00 1.11022302e-16]
 [0.00000000e+00 1.00000000e+00]]
(array([-0.37228132,  5.37228132]), array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]]))

More on types of attributes

  1. λͺ…λͺ©(Nominal) 속성:
    • 속성 κ°’ 간에 μš°μ„ μˆœμœ„λ‚˜ μˆœμœ„κ°€ μ—†μŠ΅λ‹ˆλ‹€. 즉, λͺ¨λ“  값은 λ™λ“±ν•©λ‹ˆλ‹€.
    • 예: ID 번호, 눈 색깔, 우편번호 λ“±. 이듀은 μ„œλ‘œ κ΅¬λ³„λ˜μ§€λ§Œ μˆœμœ„λ‚˜ 크기가 μ—†μŠ΅λ‹ˆλ‹€.
  2. μ„œμ—΄(Ordinal) 속성:
    • 속성 κ°’ 간에 μš°μ„ μˆœμœ„λ‚˜ μˆœμœ„κ°€ μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ κ°’ μ‚¬μ΄μ˜ 차이가 μΌμ •ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    • 예: μˆœμœ„ (예: 감자 칩의 맛을 1~10κΉŒμ§€ 평가), ν•™λ…„, ν‚€ (예: ν‚€κ°€ 큰, 쀑간, μž‘μ€) 등이 μžˆμŠ΅λ‹ˆλ‹€.
  3. ꡬ간(Interval) 속성:
    • 속성 κ°’ κ°„μ˜ 차이λ₯Ό 비ꡐ할 수 μžˆμ§€λ§Œ, μ ˆλŒ€μ μΈ 영점(0)이 μ—†μŠ΅λ‹ˆλ‹€.
    • 예: 달λ ₯ λ‚ μ§œ, μ„­μ”¨λ‚˜ 화씨 μ˜¨λ„ λ“±. μ˜¨λ„μ˜ 경우 μ°¨μ΄λŠ” 비ꡐ할 수 μžˆμ§€λ§Œ, μ„­μ”¨λ‚˜ ν™”μ”¨λŠ” μ ˆλŒ€μ μΈ 영점이 μ—†μŠ΅λ‹ˆλ‹€.
  4. λΉ„μœ¨(Ratio) 속성:
    • μ ˆλŒ€μ μΈ 영점(0)이 있으며 속성 κ°’ κ°„μ˜ λΉ„μœ¨μ„ 비ꡐ할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 예: 켈빈 μ˜¨λ„, 길이, μ‹œκ°„, 개수 λ“±. μ΄λŸ¬ν•œ 속성은 0이 의미 μžˆλŠ” 값을 κ°€μ§€λ―€λ‘œ κ°’ κ°„μ˜ λΉ„μœ¨μ„ 비ꡐ할 수 μžˆμŠ΅λ‹ˆλ‹€.

Properties of Attribute Values

  • μ†μ„±μ˜ μœ ν˜•μ€ λ‹€μŒ 속성/μž‘μ—… 쀑 μ–΄λŠ 것을 μ†Œμœ ν•˜λŠ”μ§€μ— 따라 λ‹¬λΌμ§‘λ‹ˆλ‹€.
  • ꡬ별성(Distinctness): =
    • 속성 값이 μ„œλ‘œ λ‹€λ₯Έμ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” μ—°μ‚°μž…λ‹ˆλ‹€. 속성 κ°’ 사이에 ꡬ별성이 μžˆλ‹€λ©΄ ν•΄λ‹Ή 속성은 μ„œλ‘œ λ‹€λ₯Έ 값을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λͺ…λͺ©(Nominal), μ„œμ—΄(Ordinal), ꡬ간(Interval), λΉ„μœ¨(Ratio) 속성 λͺ¨λ‘μ— ν•΄λ‹Ήλ©λ‹ˆλ‹€.
  • μˆœμ„œ(Order): < >
    • 속성 κ°’ κ°„μ˜ μˆœμ„œλ₯Ό λΉ„κ΅ν•˜λŠ” μ—°μ‚°μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ–΄λŠ 값이 λ‹€λ₯Έ 값보닀 μž‘μ€μ§€, 큰지 등을 비ꡐ할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ„œμ—΄(Ordinal), ꡬ간(Interval), λΉ„μœ¨(Ratio) 속성에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.
  • 차이(Differences): + -
    • 속성 κ°’ κ°„μ˜ 차이λ₯Ό 계산할 수 μžˆλŠ” μ—°μ‚°μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 속성 κ°’ μ‚¬μ΄μ˜ 차이λ₯Ό κ³„μ‚°ν•˜μ—¬ 의미 μžˆλŠ” 정보λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” ꡬ간(Interval), λΉ„μœ¨(Ratio) 속성에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.
  • λΉ„μœ¨(Ratios): * /
    • 속성 κ°’ κ°„μ˜ λΉ„μœ¨μ„ 계산할 수 μžˆλŠ” μ—°μ‚°μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, ν•œ 속성 값이 λ‹€λ₯Έ 속성 κ°’μ˜ λͺ‡ 배인지λ₯Ό 계산할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λΉ„μœ¨(Ratio) 속성에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.

각 속성 μœ ν˜•μ€ μ΄λŸ¬ν•œ 속성/μ—°μ‚° 쀑 일뢀 λ˜λŠ” λͺ¨λ“  것을 κ°–κ³  μžˆμŠ΅λ‹ˆλ‹€.

  • λͺ…λͺ©(Nominal) 속성: ꡬ별성(Distinctness)
  • μ„œμ—΄(Ordinal) 속성: ꡬ별성(Distinctness)κ³Ό μˆœμ„œ(Order)
  • ꡬ간(Interval) 속성: ꡬ별성(Distinctness), μˆœμ„œ(Order), 의미 μžˆλŠ” 차이(Differences)
  • λΉ„μœ¨(Ratio) 속성: ꡬ별성(Distinctness), μˆœμ„œ(Order), 의미 μžˆλŠ” 차이(Differences), λΉ„μœ¨(Ratios)