Python 주제 분석


수강중

6. LSA 실습

전처리된 데이터 불러오기

import joblib
data = joblib.load('plot.pkl')
locals().update(data)

SVD

x_train은 27,908개의 문서를 2,000개의 단어로 나타낸 행렬이다. 따라서 2,000차원이라고 볼 수 있다.

x_train.shape
(27908, 2000)

scikit-learn 라이브러리를 이용해서 SVD를 한다.

from sklearn.decomposition import TruncatedSVD

n_components는 축소할 차원의 개수를 나타낸다. 일단 10차원으로 줄여본다.

svd = TruncatedSVD(n_components=10, random_state=1234)
svd.fit(x_train)
TruncatedSVD(algorithm='randomized', n_components=10, n_iter=5,
             random_state=1234, tol=0.0)

LSA에서 적절한 주제를 찾는 방법으로 스크리 플롯(scree plot)이 있다. 정확하지는 않으나 흔히 사용하는 방법이다. 이 방법은 차원의 크기에 따라 설명하는 분산의 양이 달라지는 것을 그래프로 그리고, 그래프가 꺾이는 점에서 LSA의 차원을 결정한다.

import matplotlib.pyplot as plt
plt.plot(svd.explained_variance_, 'o')
[<matplotlib.lines.Line2D at 0x1b923865438>]

다섯 번째 차원까지 설명되는 분산이 줄어들다가 이후로 결과값의 변화가 적다. 따라서 5차원으로 줄이기로 한다. SVD 결과에서 5차원을 더 잘라내도 되지만, 여기서는 편의상 다시 SVD를 돌린다.

svd = TruncatedSVD(n_components=5, random_state=1234)
svd.fit(x_train)
TruncatedSVD(algorithm='randomized', n_components=5, n_iter=5,
             random_state=1234, tol=0.0)

결과를 저장해둔다.

joblib.dump(svd, 'svd.pkl')
['svd.pkl']

차원 축소

테스트 데이터 x_testx_train과 동일하게 2,000차원이다.

x_test.shape
(6978, 2000)

테스트 데이터 x_text를 차원 축소한다.

doc_emb = svd.transform(x_test)

5차원으로 축소되었다.

doc_emb.shape
(6978, 5)

주제보기

어떤 단어들이 같은 주제로 표현되는지 확인해본다. svd.components_가 주제와 단어의 관계를 나타낸다. 이 행렬의 크기는 (5, 2000)이다. 즉 5개의 주제와 2,000개의 단어의 관계를 나타낸다.

svd.components_.shape
(5, 2000)

편리하게 다루기 위해 판다스 데이터 프레임으로 변환한다.

import pandas as pd
loading = pd.DataFrame(svd.components_.T)
loading['word'] = cv.get_feature_names()

0번 주제과 관련이 높은 단어를 확인합니다. tells, father, house, home, man 등의 단어가 나온다. 0번 주제의 값이 높을 수록 단어 문서 행렬에서 해당 단어의 빈도가 높아진다.

i = 0
loading.sort_values(i, ascending=False).loc[:, [i, 'word']].head()
0 word
1797 0.190082 tells
636 0.184727 father
850 0.143918 house
838 0.143609 home
1110 0.135895 man

저장

svd 결과를 저장한다.

joblib.dump(svd, 'svd.pkl')
['svd.pkl']