본문으로 바로가기

특이값 분해(SVD): 꼭 알아야 할 핵심

특이값 분해(SVD)는 어떤 행렬이든 세 개의 더 단순한 구성 요소로 분해해, 그 기저 구조를 드러내는 행렬 분해 방법입니다.
업데이트됨 2026년 5월 22일  · 12분 읽다

AI로 탐색하기

ChatGPT에서 열기Claude에서 열기Perplexity에서 열기

수천 개의 특성을 가진 데이터셋에서 유용한 패턴을 추출하려고 해 본 적이 있으신가요?

방대한 데이터셋에는 분명 유의미한 구조가 숨어 있습니다. 문제는 원시 데이터셋에 잡음, 중복, 결측값이 많고 실제로 필요 이상으로 차원이 많다는 점이죠. 대부분의 머신 러닝 알고리즘은 이런 데이터를 이해하지 못하거나, 잘해도 학습 시간이 크게 늘어납니다.

특이값 분해(SVD)는 임의의 행렬(여기서는 데이터셋)을 세 개의 더 단순한 행렬로 쪼개 그 핵심 구조를 보여 줍니다. 추천 시스템, 이미지 압축, PCA 같은 차원 축소 기법의 수학적 기반이며, 한 번 이해하고 나면 업무 곳곳에서 접하게 될 겁니다.

이 글에서는 SVD가 무엇이고, 어떻게 동작하며, 데이터 사이언스에서 어디에 쓰이는지, 그리고 언제 다른 대안을 선택해야 하는지 차근차근 살펴보겠습니다.

벡터나 행렬식 같은 개념이 헷갈리시나요? 계속 읽기 전에 딥러닝을 위한 수학 개념 해설 글을 먼저 읽어 보세요.

특이값 분해(SVD)란?

SVD는 어떤 행렬이든 세 개의 더 단순한 행렬로 분해하는 방법입니다.

이렇게 생각해 보세요. 행렬 A 가 있습니다. 데이터셋일 수도, 이미지일 수도 있죠. SVD는 A 를 세 부분으로 나눕니다:

SVD formula

SVD 공식

  • Um x m 직교 행렬입니다. 열은 왼쪽 특이벡터라 부르며, A의 행들 간 관계를 설명합니다.

  • \Sigmam x n 대각 행렬입니다. 대각 원소는 특이값 으로, 항상 음이 아니며 큰 것부터 작은 것 순서로 정렬됩니다.

  • V*n x n 직교 행렬의 켤레 전치입니다. 행은 오른쪽 특이벡터 라 부르며, A의 열들 간 관계를 설명합니다.

각 구성 요소는 원래 데이터에 대해 서로 다른 정보를 보여 줍니다. U 는 행 수준 패턴(행들 간의 관계), \Sigma 는 중요도 가중치(각 패턴의 기여도), V* 는 열 수준 패턴(열들 간의 관계)을 담습니다.

비유하자면, 누군가에게 레시피를 설명한다고 해 봅시다. 재료(무엇이 들어가는지), 비율(각각 얼마나 쓰는지), 단계(어떻게 조합하는지)로 나눌 수 있습니다. 각각만으로는 음식을 재현할 수 없지만, 함께라면 필요한 정보를 모두 담습니다. SVD도 행렬에 대해 같은 일을 합니다. "무엇", "얼마나", "어떻게"를 각각 독립적으로 다룰 수 있는 구성 요소로 분리하죠.

선형대수에서 SVD가 돋보이는 이유는 어떤 행렬에도 적용된다는 점입니다. 정사각 행렬일 필요도, 특별한 성질이 필요도 없습니다. 임의의 m x n 행렬은 이 방식으로 분해할 수 있어, 데이터 사이언스 전반에서 널리 쓰입니다.

실무에서의 SVD 동작 방식

이제 SVD가 어떻게 작동하는지, 기초부터 살펴보겠습니다.

행렬 분해 설명

3×2 행렬 A 가 있다고 합시다:

Matrix decomposition

행렬 분해

SVD는 이를 U(3×3), \Sigma(3×2), V*(2×2)로 분해합니다. U의 열은 A x A^T의 고유벡터에서, V의 열은 A^T x A의 고유벡터에서 옵니다. \Sigma의 특이값은 두 곱에서 얻은 고유값의 제곱근입니다.

다행히 이를 손으로 계산할 필요는 없습니다. 파이썬에서는 한 줄이면 충분합니다:

import numpy as np

A = np.array([[1, 2], [3, 4], [5, 6]])
U, sigma, Vt = np.linalg.svd(A, full_matrices=True)

Numpy output

Numpy 출력

세 행렬은 곱셈을 통해 상호작용합니다. U 는 행 공간에서 데이터를 회전시키고, \Sigma 는 각 축 방향으로 스케일링하며, V* 는 열 공간에서 회전시킵니다. 그 결과가 원래 행렬 A 입니다.

특이값의 역할

\Sigma 의 대각 원소는 각 구성 요소가 전체 행렬에 얼마나 기여하는지를 알려 줍니다.

첫 번째 특이값이 항상 가장 큽니다. 데이터에서 가장 지배적인 패턴을 포착하죠. 이후 값들은 점차 줄어듭니다. 처음 몇 개의 특이값이 크고 나머지가 0에 가깝다면, 행렬의 정보 대부분이 소수의 구성 요소에 집중되어 있다는 뜻입니다.

이 점이 데이터 압축을 가능하게 합니다.

작은 특이값(그리고 이에 대응하는 U 의 열과 V*의 행)을 제외해도 정보 손실이 미미합니다. 결과는 원래 행렬보다 작고 다루기 쉬운 저랭크 근사입니다.

0이 아닌 특이값의 개수는 행렬의 랭크(선형 독립인 행 또는 열의 수)를 알려 줍니다. 100×50 행렬에 0이 아닌 특이값이 10개뿐이라면, 데이터는 독립 차원이 10개뿐이며 나머지 40개는 중복이라는 의미입니다.

행렬 복원

세 구성 요소를 다시 곱해 원래 행렬을 복원할 수 있습니다:

Matrix reconstruction

행렬 복원

하지만 실제로는 부분 복원이 더 유용합니다. 모든 특이값을 쓰는 대신, 상위 k 개와 그에 대응하는 벡터만 유지합니다. 그러면 A랭크 k 근사를 얻게 됩니다:

Rank-k matrix approximation

랭크 k 행렬 근사

Eckart-Young 정리는 이 랭크 k 근사가 원래 A에 가장 가까운(프로베니우스 노름 기준) 랭크 k 행렬임을 보장합니다. 즉, 행렬을 k 차원으로 압축해야 한다면, SVD가 최선의 결과를 제공합니다.

데이터 사이언스에서의 SVD 활용

한번 관심을 갖고 보면, SVD는 예상보다 훨씬 많은 곳에 등장합니다.

핵심 아이디어는 큰 행렬에서 중요한 부분만 남기고 나머지를 제거하는 것입니다. 달라지는 것은 문제에 따라 무엇이 "중요"한지의 기준입니다.

차원 축소

고차원 데이터셋은 다루기도, 해석하기도 어렵습니다. 특성이 많을수록 학습 시간이 길어지고 과적합 위험이 커집니다. SVD는 차원 수를 줄여 이런 문제를 완화합니다.

대략적인 절차는 이렇습니다. 데이터 행렬을 분해하고, 특이값을 확인한 뒤 상위 k 개의 구성 요소만 유지합니다. 작은 특이값은 잡음과 미세한 변동을 나타내므로 제거해도 데이터 품질에 거의 영향이 없습니다. 이렇게 하면 원래 구조의 대부분을 유지하면서도 간결한 표현을 얻게 됩니다.

이는 바로 주성분 분석(PCA)의 동작 방식과 같습니다. PCA는 데이터를 중심화한 뒤 SVD를 수행합니다. 주성분은 오른쪽 특이벡터이며, 특이값은 각 구성 요소가 설명하는 분산의 크기를 알려 줍니다.

추천 시스템

Netflix나 Amazon 같은 회사에는 대부분의 항목이 비어 있는 거대한 사용자-아이템 행렬이 있습니다. 사용자는 수천 개 중 일부 영화만 평가하므로 행렬이 희소하죠. SVD는 이런 빈칸을 메우는 데 쓰입니다.

평점 행렬을 사용자 선호와 아이템 특성으로 분해하는 것이 아이디어입니다. U 는 각 사용자가 무엇을 중시하는지(장르, 전개 속도, 톤 등)를, V* 는 각 아이템이 무엇을 제공하는지를 나타냅니다. \Sigma의 특이값은 이러한 요인들의 중요도를 스케일링합니다. 다시 곱하면 사용자가 아직 보지 않은 영화의 예측 평점을 얻을 수 있습니다.

실무에서는 표준 SVD가 결측값을 0으로 간주하기 때문에 희소 행렬에 바로 적용하기 어렵습니다. 그래서 절단 SVD나 관측된 항목에만 작동하는 행렬 분해 변형 기법을 사용합니다.

이미지 압축

그레이스케일 이미지는 픽셀 값의 행렬일 뿐입니다. SVD는 가장 중요한 특이값만 유지해 이미지를 압축할 수 있습니다.

1000×1000 이미지가 있다고 합시다. 전체 SVD는 특이값 1000개를 제공합니다. 하지만 상위 50개만 유지하면 1000 대신 50개의 구성 요소로 이미지를 재구성합니다. 이미지는 약간 흐릿해지지만 식별 가능하며, 저장 용량은 1,000,000에서 약 100,500으로 줄어듭니다(U의 50개 열 + 특이값 50개 + V*의 50개 행).

특이값을 더 많이 쓰면 화질은 좋아지지만 압축률은 낮아집니다. 더 적게 쓰면 파일은 작아지지만 손실이 커집니다. 사용 사례에 맞게 균형점을 선택하면 됩니다.

성능 고려 사항과 한계

행렬이 클수록 계산 비용이 커집니다.

계산 비용

m x n 행렬에 대한 전체 SVD의 시간 복잡도는 O(mn²) 입니다(m >= n 가정). 작은 행렬에는 문제가 없지만, 수백만 행과 수천 열의 행렬에는 비용이 큽니다.

메모리도 병목입니다. 전체 SVD는 밀집 행렬 세 개를 만들어 한 번에 모두 저장해야 하므로 사용 가능한 RAM을 초과할 수 있습니다.

해결책은 불필요한 전체 SVD 계산을 피하는 것입니다. 절단 SVD는 상위 k 개의 특이값과 벡터만 계산하므로 훨씬 빠릅니다. 파이썬에서는 scipy.sparse.linalg.svdssklearn.decomposition.TruncatedSVD가 이를 제공합니다. 랜덤화 SVD는 무작위 표본을 사용해 분해를 근사하며, 지배적인 구성 요소만 필요할 때 특히 효과적입니다.

안정성과 정확도

SVD는 대부분의 경우 수치적으로 안정적이지만, 특정 데이터 패턴에서는 어려움을 겪을 수 있습니다.

잡음이 매우 많은 데이터가 한 예입니다. 신호 대 잡음비가 낮으면 상위 특이값이 잡음과 뚜렷이 분리되지 않습니다. 절단 시 잡음을 유지하거나 신호를 줄일 수 있습니다.

조건수가 큰(가장 큰 특이값과 가장 작은 특이값의 비율이 큰) ill-conditioned 행렬도 문제입니다. 계산 중의 작은 수치 오차가 증폭되어 부동소수점 정밀도 한계에서 특히 신뢰할 수 없는 결과를 초래할 수 있습니다.

해결책은 절단 전에 특이값을 점검하는 것입니다. 그래프로 그리고 신호와 잡음 사이의 뚜렷한 급감 지점을 찾으세요. 감쇠가 완만해 뚜렷한 "팔꿈치"가 없다면, 그 데이터셋에는 SVD가 최선의 도구가 아닐 수 있습니다.

SVD의 대안

SVD만 있는 것은 아니며, 모든 작업에 항상 최선의 선택인 것도 아닙니다.

아래 대안들은 각기 특정 문제를 해결합니다. SVD를 대체한다기보다, 서로 다른 가정과 제약에서 동작합니다. 언제나 그렇듯 알맞은 선택은 수행하려는 과업에 달려 있습니다.

고유분해

고유분해는 SVD와 가장 밀접합니다. 정사각 행렬을 고유값과 고유벡터로 분해합니다:

Eigendecomposition formula

고유분해 공식

여기서 Q는 고유벡터를, \Lambda는 고유값의 대각 행렬입니다.

단, 정사각 행렬에만 적용됩니다. 데이터 행렬이 m x n 이고 m != n 이면 고유분해로 직접 다룰 수 없습니다. SVD는 어떤 형태의 행렬에도 적용되므로 더 일반적인 도구입니다.

정사각이고 대칭인 행렬(예: 공분산 행렬)에서는 고유분해와 SVD가 매우 유사한 결과를 냅니다. 대칭 양의 준정부호 행렬의 특이값은 그 고유값과 같습니다. 따라서 PCA에서 공분산 행렬을 다룰 때 두 방법은 동일한 결과를 제공합니다. SVD는 비정사각의 경우로 일반화된 버전일 뿐입니다.

QR 분해

QR 분해는 행렬을 직교 행렬 Q와 상삼각 행렬 R로 나눕니다:

QR decomposition formula

QR 분해 공식

특히 연립 선형방정식과 최소제곱 문제를 푸는 작업에서 SVD보다 빠릅니다.

대신 정보는 적습니다. QR은 특이값을 제공하지 않으므로, 행렬의 랭크나 어떤 구성 요소가 더 큰 비중을 갖는지 알려주지 못합니다. 만약 Ax = b를 풀기만 하면 되고 내부 구조에 관심이 없다면 QR이 좋은 선택입니다. 반대로 데이터를 이해하거나 압축해야 한다면 SVD가 더 적합합니다.

비음수 행렬 분해(NMF)

NMF는 모든 값이 음수가 아닌 두 행렬로 원 행렬을 분해합니다:

NMF formula

NMF 공식

이 제약 덕분에 NMF는 본질적으로 음수가 아닌 데이터(픽셀 강도, 단어 수 등)에 잘 맞습니다. 반면 SVD는 이런 제약이 없습니다. 분해된 행렬에 음수가 포함될 수 있어, 때로는 해석이 어려운 구성 요소가 나옵니다.

NMF는 텍스트 마이닝과 토픽 모델링에서 특히 인기 있습니다. W의 각 열은 토픽을, H의 각 행은 각 문서에 그 토픽이 얼마나 나타나는지를 의미할 수 있습니다. 비음수 제약 덕분에 토픽은 단어의 가산적 조합으로 구성되어, SVD의 양·음 혼재 구성 요소보다 읽기 쉽습니다.

단점은 해가 유일하지 않고 초기값에 따라 결과가 달라질 수 있다는 점입니다. SVD는 같은 입력에 대해 항상 같은 출력을 냅니다.

랜덤화 SVD

행렬이 너무 커서 전체 SVD가 어렵지만 그래도 특이값이 필요하다면, 랜덤화 SVD를 고려해 보세요. 전체 분해를 계산하지 않고 상위 k 개의 특이값과 벡터를 무작위 사영으로 근사합니다. scikit-learn(TruncatedSVD)와 Facebook의 fbpca 같은 라이브러리가 이 접근을 구현하며, 수백만 행의 행렬에도 잘 확장됩니다.

아래 표는 각 방법을 언제 선택할지 요약합니다.

Alternatives to SVD

SVD의 대안

SVD를 사용할 때의 기타 고려 사항

초보 데이터 사이언티스트가 흔히 혼동하는 부분이 몇 가지 있습니다.

첫째는 특이값을 오독하는 것입니다. 큰 특이값은 해당 구성 요소가 데이터의 분산을 많이 설명한다는 뜻이지, 도메인 관점에서 그 구성 요소가 "중요"하다는 의미는 아닙니다. 예를 들어 사용자 평점 행렬에서 지배적인 특이값은 많은 사람이 인기 영화를 평가한다는 사실을 포착할 뿐, 의미 있는 선호 패턴을 담지 않을 수 있습니다. 특이값의 크기만 보지 말고, 항상 데이터 맥락에서 해석하세요.

둘째는 불필요할 때 SVD를 쓰는 것입니다. 소규모 데이터셋(수백 행, 소수의 열)에서는 SVD가 불필요한 복잡성을 더할 뿐입니다. 상관분석이나 기본적인 특성 선택 같은 단순한 방법이 더 빠르고 코드도 적습니다. SVD는 중복 구조가 많은 고차원 데이터에 유용합니다. 데이터셋이 이 설명에 맞지 않으면 더 단순한 방법을 쓰세요.

결론

SVD는 어떤 행렬이든 그 구조를 보여 주는 세 구성 요소로 분해합니다. 특이값은 데이터에서 어떤 부분이 가장 중요한지를 알려 주며, 왼쪽·오른쪽 특이벡터는 그 배후의 행과 열 패턴을 보여 줍니다.

이 분해는 우리가 매일 쓰는 실용 도구들의 기반입니다. 추천 시스템은 결측 평점을 예측하는 데, 이미지 압축은 시각적 품질을 유지하면서 파일 크기를 줄이는 데 이를 활용합니다. 도메인이 달라도 근간이 되는 수학은 거의 동일합니다.

하지만 SVD가 항상 정답은 아닙니다. 큰 행렬에서는 비용이 크고, 특이값이 잘 분리되지 않으면 신호와 잡음을 섞어 버릴 수 있습니다. 또한 소규모 데이터셋에는 과하죠. QR 분해, 고유분해, NMF 같은 대안이 특정 경우에 더 적합합니다.

핵심은 언제 SVD를 쓰고, 언제 더 단순한 방법이 나은지 아는 것입니다. 그 지식을 쌓기 위해 Machine Learning Scientist in Python 트랙에 등록하고 2026년에 실무 역량을 갖추세요.

SVD 자주 묻는 질문

특이값 분해(SVD)란 무엇인가요?

SVD는 임의의 행렬을 세 구성 요소로 분해하는 행렬 분해 방법입니다. 왼쪽 특이벡터(U), 특이값(Σ), 오른쪽 특이벡터(V*)로 나눕니다. 모양이나 크기에 관계없이 모든 행렬에 작동하며, 데이터를 패턴과 그 상대적 중요도로 분리해 기저 구조를 드러냅니다.

데이터 사이언스와 머신 러닝에서 SVD를 사용하는 이유는 무엇인가요?

SVD는 고차원 데이터셋에서 가장 중요한 패턴을 유지하면서 차원 수를 줄이는 데 도움을 줍니다. PCA와 추천 시스템의 수학적 기반입니다. 이 응용들은 모두 지배적인 구성 요소만 남기고 나머지를 제거한다는 같은 아이디어를 활용합니다.

SVD와 고유분해의 차이는 무엇인가요?

고유분해는 정사각 행렬에만 작동하지만, SVD는 어떤 형태의 행렬에도 작동합니다. 공분산 행렬처럼 정사각 대칭 행렬에서는 두 방법이 매우 유사한 결과를 냅니다. 양의 준정부호 행렬의 특이값은 그 고유값과 같습니다. SVD가 더 일반적인 도구이므로 데이터 사이언스 워크플로에서 기본값으로 쓰이는 경우가 많습니다.

특이값은 데이터 압축과 어떤 관련이 있나요?

특이값은 큰 것부터 작은 것 순서로 정렬되며, 각 값은 특정 구성 요소가 설명하는 분산의 크기를 나타냅니다. 작은 특이값(및 해당 벡터)을 제거하면 지배적인 구조를 유지한 채 미세한 패턴과 잡음을 제거하게 됩니다. 약간의 정확도 손실로 큰 크기 감소를 얻는 셈입니다.

언제 SVD 사용을 피해야 하나요?

SVD는 큰 행렬에서 비용이 큽니다. 전체 분해의 시간 복잡도는 O(mn^2)입니다. 소수의 특성만 가진 작은 데이터셋이라면 상관분석이나 기본 특성 선택 같은 단순한 방법이 더 빠릅니다. 행렬이 매우 크고 상위 구성 요소만 필요하다면, 전체 SVD 대신 절단 SVD나 랜덤화 SVD가 더 적합합니다.

주제

DataCamp로 학습하세요

courses

Python으로 배우는 선형 분류기

4
66.6K
이 과정에서는 로지스틱 회귀와 SVM 등 선형 분류기의 원리를 자세히 학습합니다.
자세히 보기Right Arrow
강좌 시작
더 보기Right Arrow