C.W.K.
Stream
Lesson 08 of 08 · published

Eigen 응용: PCA, PageRank, 양자

~10 min · pca, pagerank, svd, quantum

Level 0수학 초심자
0 XP0/59 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

세 세계, 한 아이디어

Eigen-decomposition = 같은 연산이 급격히 다른 세 맥락에서 등장. 각 30초 가치.

PCA — 데이터의 큰 방향 찾기

각 행이 sample, 각 열이 feature 인 데이터셋. Covariance 행렬 이 feature 가 어떻게 co-vary 하는지 말해. PCA 가 그 고유벡터 계산: 그 고유벡터들이 데이터에 변동이 가장 많은 방향, 고유값 크기로 ranked. 데이터를 top 고유벡터에 투영 = 100차원 데이터를 차원으로 최소 정보 손실로 축소.

이게 1000차원 임베딩을 2D scatter 에 시각화하는 법. PCA 가 데이터 "모양" 을 최대한 보존하는 2 방향 골라.

PageRank — 중요한 페이지 찾기

Google 의 원래 ranking 알고리즘이 웹을 그래프로 모델: 각 페이지 = 노드, 각 링크 = edge. 행렬 만들어 = 페이지 jump 확률. dominant 고유벡터 (가장 큰 고유값의 고유벡터) = stationary 확률 분포: "random surfer 가 영원히 링크 클릭하면 각 페이지에 시간 어느 비율?" 그 분포가 중요도 점수.

웹은 수십억 페이지. 정확한 고유벡터 계산 불가능, 근데 iterative 알고리즘 (power iteration) 이 놀랄 만큼 빠르게 수렴. 그게 PageRank.

양자역학 — 상태와 관측

양자역학에서 물리 시스템 상태 = 복소 벡터 공간의 벡터. 관측 가능 양 (에너지, 운동량, 위치) = 연산자 (행렬). 관측치 측정 = 연산자의 고유값 얻기, 시스템 상태가 해당 고유벡터 로 collapse. "고양이가 살아있고 동시에 죽어있다 — 볼 때까지" 의 수학 = 중첩이 고유상태의 합; 측정이 한 곳에 투영.

SVD — 직사각 행렬용 Eigen

고유값은 정방 행렬에만. 특이값 분해 가 일반화: 어떤 행렬이든 로 인수분해, 의 특이값이 고유값 역할. SVD 가 추천 시스템, latent semantic 분석, 이미지 압축 굴려.

시스템에 구조 있으면 그 구조엔 보통 이름 있고 이름은 "eigen-something". 메서드 hood 아래 eigen-decomposition 있는지 알면 실제 뭐가 계산되는지 앎.

트랙 보상

아이겐 던전 걸어서 살아남았어. 행렬은 변환. 단위는 do-nothing. 역행렬은 undo. 행렬식은 영혼. 고유벡터는 선호 방향. 여기서부터 누가 "transformer attention" 이나 "covariance projection" 이나 "spectral 메서드" 말하면 hood 아래 chassis 알 거야.

Code

PCA 4줄에·python
import numpy as np

# 작은 PCA — 강한 상관관계 있는 2D 데이터, 주축 찾기
np.random.seed(0)
X = np.random.randn(200, 2)
X[:, 1] = 0.7 * X[:, 0] + 0.3 * X[:, 1]   # 상관관계 induce

# 1) 데이터 center
X = X - X.mean(axis=0)

# 2) Covariance 행렬
C = (X.T @ X) / (len(X) - 1)

# 3) Eigendecomposition
eigvals, eigvecs = np.linalg.eigh(C)       # 대칭 행렬엔 eigh 사용
print("고유값:", eigvals)                  # 작은 거, 큰 거
print("첫 번째 주방향:", eigvecs[:, -1])   # 최대 고유값 고유벡터
PageRank 4줄에·python
import numpy as np

# 장난감 PageRank — 4페이지 웹
M = np.array([[0,   0.5, 0.5, 0  ],
              [0.5, 0,   0,   1  ],
              [0.5, 0,   0,   0  ],
              [0,   0.5, 0.5, 0  ]])

# Power iteration — dominant 고유벡터로 수렴
rank = np.ones(4) / 4
for _ in range(50):
    rank = M @ rank
    rank = rank / rank.sum()
print("PageRank 점수:", rank)

External links

Exercise

100×5 데이터셋 (임의나 실제). 각 열 표준화. Covariance 행렬의 eigendecomposition 으로 PCA 계산. 처음 두 주성분 서로 plot 하고 데이터가 어떻게 퍼지는지 봐.
Hint
X = (X - X.mean(axis=0)) / X.std(axis=0), 그러고 C = X.T @ X / (len-1), 그러고 eigvals, eigvecs = np.linalg.eigh(C). 처음 두 주축 = eigvecs[:, -1]eigvecs[:, -2].

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파happy

댓글 2

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.
  1. Elechemist
    Elechemist

    아직 완전히 와닿진 않지만 eigen을 이렇게 쓰는거구나. pagerank알고리즘은 천재적이다

    import numpy as np import matplotlib.pyplot as plt

    rng = np.random.default_rng(42)

    잠재 구조가 있는 100x5 데이터: 두 숨은 요인이 5개 열을 만든다

    n = 100 f1 = rng.standard_normal(n) f2 = rng.standard_normal(n) X = np.column_stack([ f1 + 0.3rng.standard_normal(n), f1 + 0.3rng.standard_normal(n), f2 + 0.3rng.standard_normal(n), f2 + 0.3rng.standard_normal(n), 0.5f1 + 0.5f2 + 0.3*rng.standard_normal(n), ])

    1) 열별 표준화 (평균 0, 표준편차 1)

    Xs = (X - X.mean(axis=0)) / X.std(axis=0)

    2) 공분산 행렬

    C = (Xs.T @ Xs) / (n - 1)

    3) 대칭행렬 고유분해

    vals, vecs = np.linalg.eigh(C)

    4) 큰 고유값 순으로 정렬

    order = np.argsort(vals)[::-1] vals = vals[order] vecs = vecs[:, order]

    5) 처음 두 주성분으로 사영

    PC = Xs @ vecs[:, :2]

    print("고유값:", np.round(vals, 4)) print("분산 설명 비율:", np.round(vals / vals.sum(), 4)) print("누적:", np.round(np.cumsum(vals / vals.sum()), 4))

    6) PC1 vs PC2 산점도

    fig, ax = plt.subplots(figsize=(7, 6)) ax.scatter(PC[:, 0], PC[:, 1], s=40, alpha=0.7, edgecolor='white', linewidth=0.5) ax.axhline(0, color='gray', lw=0.5) ax.axvline(0, color='gray', lw=0.5) ax.set_xlabel(f"PC1 ({vals[0]/vals.sum()*100:.1f}%)") ax.set_ylabel(f"PC2 ({vals[1]/vals.sum()*100:.1f}%)") ax.set_title("PCA: first two principal components") ax.set_aspect('equal', adjustable='datalim') plt.tight_layout() plt.savefig('pca_scatter.png', dpi=130)

    💛 by 피파happy
    1. 피파
      피파· warmElechemistElechemist

      맞아요, 아직 손에 완전히 잡히지 않아도 PCA 코드가 eigen의 쓰임을 아주 잘 보여줘요. 공분산 행렬의 eigenvector가 “데이터가 가장 많이 퍼지는 방향”이고, 큰 eigenvalue가 “그 방향에 실린 정보량”이라고 보면 됩니다. PageRank도 같은 뿌리예요: 연결 구조 행렬에서 오래 남는 방향을 찾는 거니까요.