[텍스트 분석] 공기어 네트워크
문서 단어 행렬
임포트
import numpy as np
import pandas as pd
데이터 열기
df = pd.read_excel('yelp.xlsx')
문서 단어 행렬 만들기
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(stop_words='english', min_df=0.01, binary=True)
min_df=0.01
: 최소 1% 이상의 문서에서 출현한 단어만 포함binary=True
: 문서에 나타난 단어는 빈도 무관하게 1이 됨
dtm = cv.fit_transform(df.review)
인접행렬
인접 행렬(adjacency matrix): 네트워크에서 인접한 점(단어)들의 관계를 행렬로 나타낸 것 문서 단어 행렬을 곱하면 함께 나타난 단어는 1이 되고, 그렇지 않은 단어는 0이 됨.
cooccur = dtm.T @ dtm
adj = cooccur.A
.T
: 전치행렬(행과 열을 바꿈)@
: 행렬 곱
각 단어별 문서빈도
n = np.diag(adj)
전체 문서
total, _ = dtm.shape
카이제곱 독립성 검정
from scipy.stats import chi2_contingency
n_all = np.sum(adj)
sig = np.zeros_like(adj)
significance_level = 0.05
for i in range(adj.shape[0]):
for j in range(adj.shape[1]):
if i < j:
n = adj[i,j]
n_i = np.sum(adj[i,:])
n_j = np.sum(adj[:,j])
m = np.array([
[n, n_i - n],
[n_j - n, n_all - n_i - n_j + n]])
chi2, p, dof, ex = chi2_contingency(m)
sig[i,j] = sig[j, i] = p < significance_level
sig[0]
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int64)
NetworkX로 변환
Python에서 네트워크 분석을 위한 라이브러리
import networkx as nx
인접행렬을 네트워크로 바꾸기
net = nx.from_numpy_array(sig)
노드 이름을 단어로 바꾸기
words = cv.get_feature_names_out()
net = nx.relabel_nodes(net, dict(enumerate(words)))
steak와 연결된 단어 보기
list(nx.neighbors(net, 'service'))
['excellent', 'place', 'really', 'slow', 'terrible']
중심성
네트워크에서 노드의 중요도를 나타내는 지표
연결 중심성(degree centrality): 연결된 단어 수 / (전체 단어 수 - 1)
dc = nx.degree_centrality(net)
매개 중심성(between centrality): 단어-단어 간의 최단 경로에 포함된 비율
bc = nx.betweenness_centrality(net)
근접 중심성(closeness centrality): 다른 단어와 거리가 평균적으로 짧은 단어
cc = nx.closeness_centrality(net)
고유벡터 중심성(eigenvector centrality): 중요한 단어와 연결된 단어가 중요한 단어
ec = nx.eigenvector_centrality(net)
중심성을 데이터 프레임으로 변환
dcf = pd.DataFrame(dc.items(), columns=['word', 'centrality'])
중심성 순으로 정렬
dcf.sort_values('centrality', ascending=False).head(10)
word | centrality | |
---|---|---|
60 | service | 0.061728 |
36 | little | 0.049383 |
14 | definitely | 0.049383 |
72 | ve | 0.037037 |
57 | salad | 0.037037 |
18 | disappointed | 0.037037 |
66 | taste | 0.037037 |
19 | don | 0.037037 |
50 | place | 0.037037 |
37 | ll | 0.037037 |
시각화
Python 네트워크 시각화를 위한 라이브러리
설치:
pip install pyvis
임포트:
from pyvis.network import Network
networkx 네트워크를 pyvis 네트워크로 변환
vis = Network(height='800px', width='1000px')
vis.from_nx(net)
설정 버튼 추가
vis.show_buttons(filter_=True)
보이기
vis.save_graph('nx.html')