LSA Latent Semantic Analysis

2021. 8. 16. 10:27AI/Machine learning

    목차
반응형

토픽 모델링(Topic Modeling)

문서 집합의 추상적인 주제를 발견하기 위한 통계적 모델 

텍스트 본문의 숨겨진 의미 구조를 발견하기 위해 사용되는 텍스트 마이닝 기법

 

잠재 의미 분석(Latent Semantic Analysis, LSA)

토픽 모델링이라는 분야에 아이디어를 제공한 알고리즘

 

BoW에 기반한 DTM이나 TF-IDF는 기본적으로 단어의 빈도 수를 이용한 수치화 방법이기 때문에 "단어의 의미"를 고려하지 못한다

 

LSA = DTM의 잠재된(Latent) 의미를 이끌어내는 방법

선형대수학의 특이값 분해(Singular Value Decomposition, SVD)를 사용

 

 

특이값 분해(Singular Value Decomposition, SVD)

A가 m × n 행렬

3개의 행렬의 곱으로 분해(decomposition)

 

A = UΣV^T

        U: m x m 직교행렬 (AA^T = U(ΣΣ^T)U^T)
        V: n x n 직교행렬 (A^TA = V(Σ^TΣ)V^T)
        Σ: m x n 직사각 대각행렬

 

위 수식에서 사용된 행렬에 대한 용어는 다음과 같다.

    orthogonal matrix
        자신과 자신의 전치 행렬(transpose matrix)의 곱 (혹은 반대가) identity matrix(단위행렬)이 되는 행렬

        A x A^T = I
        A^T x A = I
        둘을 만족하는 행렬 A를 직교 행렬
        이 때 직교행렬인 A는
            A^-1 = A^T 임

    diagonal matrix(대각 행렬)
        주대각선을 제외한 곳의 원소가 모두 0인 행렬

 

        Σ =  a 0 0
             0 a 0
             0 0 a

        Σ =  a 0 0
             0 a 0
             0 0 a
             0 0 0

        Σ = a 0 0 0
            0 a 0 0
            0 0 a 0

 

    Identity Matrix (단위 행렬)
        I = 1 0    
            0 1

    Inverse Matrix (역행렬)
        A matrix와 B matrix의 곱이 I matrix

            B를 A의 역행렬이라고 표현
            A^-1

        A x A^-1 = I
    SVD로 나온 대각 행렬의 대각 원소의 값을 행렬 A의 특이값(singular value)

 

SVD를 통해 나온 대각 행렬 Σ

    Σ의 주대각원소를 행렬 A의 특이값(singular value)

    내림차순 정렬 특징

 

    ex.
    Σ = 12.4  0    0
        0     9.5  0
        0     0    1.3

 

    이 SVD의 차원의 수가 줄이고자 하는 차원의 수이다.

 

 

절단된 SVD(Truncated SVD)

위에서 설명한 SVD를 풀 SVD(full SVD)

LSA의 경우 풀 SVD에서 나온 3개의 행렬에서 일부 벡터들을 삭제시킨 절단된 SVD(truncated SVD)를 사용

 

A = UΣV^T

        U: m x m 직교행렬 (AA^T = U(ΣΣ^T)U^T)
        V: n x n 직교행렬 (A^TA = V(Σ^TΣ)V^T)
        Σ: m x n 직사각 대각행렬

    Full SVD

        A         U       Σ    V^T
        +----+    +----+  +--+ +----+
        |    | =  |    |  |  | |    |
        |    |    |    |  |  | +----+
        |    |    |    |  |  |
        +----+    +----+  +--+

    Truncated SVD

        A'        Ut      Σt  V^Tt
        +----+    +--+    +-+ +----+
        |    | =  |  |    | | +----+
        |    |    |  |    +-+ 
        |    |    |  |    
        +----+    +--+

절단된 SVD (데이터의 차원을 줄임)

대각 행렬 Σ의 대각 원소의 값 중에서 상위값 t개만 남음

절단된 SVD를 수행하면 값의 손실로 행렬 A를 복구할 수 없음

 

t = 찾고자하는 토픽의 수를 반영한 하이퍼파라미터값

t를 선택하는 것은 쉽지 않은 일

 

  • t를 크게 잡으면
    기존의 행렬 A로부터 다양한 의미를 가져갈 수 있음

  • t를 작게 잡으면
    노이즈를 제거할 수 있음
    설명력이 낮은 정보를 삭제하고 설명력이 높은 정보를 남긴다는 의미
    -> 심층적인 의미를 확인
    계산 비용이 낮아짐

 

잠재 의미 분석(Latent Semantic Analysis, LSA)

DTM이나 TF-IDF 행렬에 절단된 SVD(truncated SVD)를 사용하여 차원을 축소하여 단어들의 잠재적인 의미를 끌어냄

 

DTM

           word1  word2   ... wordn
    doc1   0      1       ... 1
    doc2   1      0       ... 0
    ...
    docn   0      1       ... 1

DTM가 SVD의 'A' matrix

 

full SVD

import numpy as np

U, sigma, VT = np.linalg.svd(A, full_matrices=True)

 

특이값을 sigma에 저장

 

DTM의 차원이 5 by 10일 때,

np.shape(U) # (5, 5) 즉, 5x5의 직교행렬

 

대각행렬 sigma의 경우 (5,)

 

이를 original 차원의 space에서 확인하려면, 다음과 같은 변형이 필요

 

ori_s = np.zeros((5, 10))

ori_s[:5, :5] = np.diag(sigma)

 

print(ori_s.round(2))

[[ val1   0.   0.  0.  0.  0.  0.  0.  0.  0.   ]

 [0.   val2 ....

  ...

 

 

U × ori_s × VT를 하면 기존의 행렬 A가 나와야 함

 

 

Truncated SVD 수행

대각 행렬 S 내의 특이값 중에서 상위 2개만 남기고 제거

ori_s=ori_s[:2,:2]

 

직교 행렬 U에 대해서도 2개의 열만 남기고 제거

U=U[:,:2]

 

행렬 V의 전치 행렬인 VT에 대해서 2개의 행만 남기고 제거

VT=VT[:2,:]

 

축소된 행렬 U, ori_s, VT에 대해서 다시 U × ori_s × VT연산을 하면 기존의 A와는 다른 결과

 

차원 축소를 통해

축소된 '문서 벡터', 축소된 '단어 벡터'를 구할 수 이 있고,

각각 축소된 벡터로 '유사도'를 구하게 됨 

 

U: 문서 벡터

ori_s

VT: 단어 벡터

 

  • 축소된 U는 5 × 2의 크기
    • 문서의 개수 × 토픽의 수 t의 크기
    • 단어의 개수인 10는 유지하지 않고, 
    • 문서의 개수인 5의 크기가 유지
    • 5개의 문서 각각을 2개의 값으로 표현
    • 즉, U의 각 행은 잠재 의미를 표현하기 위한 수치화 된 각각의 문서 벡터
  • 축소된 VT는 2 × 10의 크기
    • 토픽의 수 t × 단어의 개수
    • VT의 각 열은 잠재 의미를 표현하기 위해 수치화된 각각의 단어 벡터
  • 이 문서 벡터들과 단어 벡터들을 통해 다른 문서의 유사도
  • 다른 단어의 유사도, 단어(쿼리)로부터 문서의 유사도를 구하는 것들이 가능

 

SVD implementation

  • alphabet이 아닌 것 제거
  • 짧은 단어 제거
  • 소문자로 변환
  • 불용어 제거
    • nltk.corpus의 stopwords 사용
    • nltk.download('stopwords')하여 
    • stop_words = stopwords.words('english')를 사용하여
    • 각 단어가 stop_words에 있으면 제거
  • TF-IDF matrix 생성
    • TfidfVectorizer로 생성
    • tfidf_vectorizer = TfidfVectorizer(stop_words='english', max_features=100 <- space의 크기 결정
          max_df=0.5, smooth_idf=True)
    • tfidf_data = tfidf_vectorizer.fit_transform(clean_data)
  • LSA - topic modeling
    • 사이킷런의 절단된 SVD(Truncated SVD)를 사용
    • from sklearn.decomposition import TruncatedSVD
    • skl_svd = TruncatedSVD(n_components=10, algorithm='randomized', n_iter=100, random_state=122)
    • skl_svd.fit(tfidf_data )
  • 가장 중요한 term 3개를 출력
    • terms = vectorizer.get_feature_names()
    • for idx, topic in enumerate(skl_svd.components_):  # 10
          print("Topic %d:" % (idx + 1), [(terms[i], topic[i].round(2)) for i in topic.argsort()[-1:-1 - 3:-1])

 

LSA pros./cons.

  • 장점
    • 쉽고 빠르게 구현이 가능
    • 유사도 계산에서 좋은 성능
  • 단점
    • 늘 항상 처음부터 다시 학습(계산) 해야 함
    • online learning이 안 됨
    • 즉, 현실적으로 사용하기 어렵기에 LSA 대신 word2vec, BERT 등 단어의 의미를 embedding vector로 만드는 방법을 사용함

 

 

반응형

'AI > Machine learning' 카테고리의 다른 글

kNN  (0) 2021.08.16
LDA Latent Dirichlet Allocation  (0) 2021.08.16
특징 생성  (0) 2021.08.14
모델 평가 지표  (0) 2021.08.14
Data Science: 자연어 처리 (Natural Language Processing)  (0) 2021.08.14