
๐ก ๊ต๋ณด๋ฌธ๊ณ ์ ๋์๋ฅผ ์ถ์ฒํ๋ ์์คํ
์ ๋ง๋ค ๋ ์ค ์ฑ
์๊ฐ๋ฅผ ์ด์ฉํ์ฌ ์ ์๋ฏธํ ํค์๋๋ฅผ ์ถ์ถํ๊ณ ์ถ๋ค๋ ์๊ฐ์ด ๋ค์๊ณ ์๊ฒ ๋ ๊ฒ์ด ๋ฐ๋ก WordRank์๋ค. ์ง๊ธ๋ถํฐ ํ๊ธ๋ก ๊ตฌ์ฑ๋ ํ
์คํธ์์ ์ ์๋ฏธํ ํค์๋๋ฅผ ์ถ์ถํ๊ธฐ ์ํด ์ฐพ์๋ดค๋ ๋ฐฉ๋ฒ๋ค์ ์์ฝ ํด๋ณผ๊น ํ๋ค!
ํ
์คํธ ์์ฝ์๋ ํฌ๊ฒ ์ถ์ถ์ ์์ฝ(Extractive Summarization)๊ณผ ์ถ์์ ์์ฝ(Abstractive Summarization)์ผ๋ก ๋๋ ์ง๋ค.
์ถ์ถ์ ์์ฝ์ ๊ธฐ์กด์ ๊ธ์์ ์ค์๋๊ฐ ๋๊ฑฐ๋ ํต์ฌ์ด ๋๋ ๋ฌธ์ฅ์ ๊ทธ๋๋ก ์ถ์ถํด์ ์์ฝ๋ฌธ์ ๋ง๋๋ ๊ฒ์ด๋ค.
์ถ์์ ์์ฝ์ด๋ ์๋ก์ด ๋จ์ด์ ์๋ก์ด ๋ฌธ์ฅ์ ์์ฑํด์ ์์ฝ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ถ์ถ์ ์์ฝ๋ฒ์ ๊ฐ์ฅ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๐ ๊ด๋ จ ๋
ผ๋ฌธ : http://infolab.stanford.edu/~backrub/google.html
๐ TextRank : https://sungmooncho.com/2012/08/26/pagerank/
ํ์ดํผ๋งํฌ๋ฅผ ๊ฐ์ง๋ ์น ํ์ด์ง์ ๋ํด์ ์ผ๋ง๋ ์ฐธ์กฐ๊ฐ ๋์๋์ง, ์ผ๋ง๋ ์ ์
๋์๋์ง ๋ฑ์ผ๋ก ํ์ด์ง์ ์์๋ฅผ ๋งค๊ธฐ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.

๋ค๋ฅธ ํ์ด์ง์์ ์ค๋ ๋งํฌ๋ฅผ ๊ฐ์ ๋น์ค์ผ๋ก ์ธ๋ ๋์ ์, ๊ทธ ํ์ด์ง์ ๊ฑธ๋ฆฐ ๋งํฌ ์ซ์๋ฅผ โ์ ๊ทํ(normalize)โํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
์๋ฅผ ๋ค์ด A์ ํ์ด์ง ๋ญํฌ๋ A๋ผ๋ ํ์ด์ง๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๋ค๋ฅธ ํ์ด์ง์ ํ์ด์ง ๋ญํฌ๊ฐ์ด ๋์์๋ก (์ฆ, ๋ ์ค์ํ ์๋ก) ๋ ๋์์ง๋ค.
๐ก ์ ์ ๊ทํ๋ฅผ ํ ๊น?
โถ๏ธ
ํ์ด์ง ๋ญํฌ์ ๋จ์ ํฉ์ฐ์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค. ์๋ฅผ ๋ค์ด, T1์ ํ์ด์ง ๋ญํฌ๊ฐ ๋๋ค๊ณ ํ๋๋ผ๋, ๊ทธ ํ์ด์ง์์ ๋งํฌ๋ฅผ ์์ฒ ๊ฐ ๋ฌ์๋์๋ค๋ฉด(์ฆ, C(T1)๊ฐ์ด ๋๋ค๋ฉด) ๊ทธ ํ์ด์ง๊ฐ ๊ธฐ์ฌํ๋ ๋น์ค์ ๋ฎ์์ง๋ค.
TextRank ๋ชจ๋ธ์ PageRank์ ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ ๊ฒ์ผ๋ก, ํ์ด์ง์ ๊ฐ๋
์ ๋จ์ด์ ๊ฐ๋
์ผ๋ก ๋ฐ๊พผ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ์ฆ, ํ
์คํธ๋ก ์ด๋ฃจ์ด์ง ๊ธ์์ ํน์ ๋จ์ด๊ฐ ๋ค๋ฅธ ๋ฌธ์ฅ๊ณผ ์ผ๋ง๋งํผ์ ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋์ง๋ฅผ ๊ณ์ฐํ๋ ๊ฒ์ด๋ค.
TextRank๋ ๊ทธ๋ํ ๊ธฐ๋ฐ์ ๋ญํน๋ชจ๋ธ๋ก ์์๋ฅผ ๋งค๊ธฐ๋ ๋ฐฉ๋ฒ์ด ๋ฌธ๋จ์ ์ถ์ถ์ ์์ฝ์ ๋งค์ฐ ํจ๊ณผ์ ์ด๋ผ ์๊ฐ์ผ๋ก ๊ฐ๋ฐ๋์๋ค.
๐ ๋
ผ๋ฌธ : https://web.eecs.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf
๐ ์ฐธ๊ณ ์ฌ์ดํธ : https://www.dinolabs.ai/288
๐ ์ด๋ป๊ฒ ์์๋ฅผ ๋งค๊ธธ๊น?
โถ๏ธ ๋ ผ๋ฌธ์ ์ํ๋ฉด 'voting'๊ณผ 'recommendation'๊ณผ ๊ฐ์ ์์ด๋์ด๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํ๋ค. ํ ๋จ์ด(vertex)๊ฐ ๋ค๋ฅธ ๋จ์ด(vertex)์ ์ฐ๊ฒฐ๋๋ค๋ฉด ์ด๋ฅผ ์ฐ๊ฒฐํ vertex์ ํฌํ๋ฅผ ํ๋ค๊ณ ํ๋ค. ์ฆ, ํฌํ๋ฅผ ๋ง์ด ๋ฐ์ vertex์ ์ค์๋๊ฐ ์ปค์ง๊ฒ ๋๋ค๊ณ ๋ณผ ์ ์๊ณ ํฌํ์๋ ์์๋ฅผ ๊ฒฐ์ ํ๋ ๊ฐ์ด ๋๋ค.
WordRank๋ ์ผ๋ณธ์ด์ ์ค๊ตญ์ด์ Unsupervised word segmentation์ ์ํด ์ ์๋ ๋ฐฉ๋ฒ์ผ๋ก ํ๊ตญ์ด์ ์ ์ฉํ ์ ์ข์ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์๋ค.
WordRank๋ ๋์ด์ฐ๊ธฐ๊ฐ ์๋ ์ค๊ตญ์ด์ ์ผ๋ณธ์ด์์ ๊ทธ๋ํ ๋ญํน ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด ๋จ์ด๋ฅผ ์ถ์ถํ๊ธฐ ์ํด ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค. WordRank๋ substring graph๋ฅผ ๋ง๋ ๋ค, ๊ทธ๋ํ ๋ญํน ์๊ณ ๋ฆฌ์ฆ์ ํ์ตํ๋ค.
Substring graph ๋ ์๋ ๊ทธ๋ฆผ์ (a), (b) ์ฒ๋ผ ๊ตฌ์ฑ๋๋ค.
WordRank ์๊ณ ๋ฆฌ์ฆ์ ํ๊ตญ์ด์ ์ ์ฉํ๊ฒ ๋๋ฉด ํ ๊ธ์๋ค์ด ๋์ ranking ์ ์ง๋๊ฒ ๋๋ค. ํ๊ตญ์ด์ ํ๊ธ์๋ ๊ทธ ์์ฒด๋ก ๋จ์ด์ด๊ธฐ๋ ํ๋ฉฐ, ๊ดํ์ฌ๋ ์กฐ์ฌ๋ก ์ด์ฉ๋๋ ๊ธ์๋ค์ด ๋ง์ ๋จ์ด๋ก ๋ฑ์ฅํ๊ธฐ ๋๋ฌธ์ ํ๊ตญ์ด์ ํน์ฑ์ ๋ฐ์ํ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด์ผํ๋ค.
ํ๊ตญ์ด๋ ๋์ด์ฐ๊ธฐ ์ ๋ณด๋ฅผ ์ด์ฉํด์ผํ๋ค. ๋์ด์ฐ๊ธฐ ์ ๋ณด๋ฅผ ์ด์ฉํ์ง ์์ผ๋ฉด ๋ ์ด์ ์ ์๋์ ๊ฑธ์น substring ์ญ์ ๋จ์ด ํ๋ณด์ ํฌํจ๋๋ค.
<
substring('์ด๋ฒ๋ด์๋') = [์ด๋ฒ, ๋ฒ๋ด, ๋ด์, ์๋, ์ด๋ฒ๋ด, ๋ฒ๋ด์, ...]
subsrting('์ด๋ฒ ๋ด์๋') = [์ด๋ฒ, ๋ด์, ์๋, ๋ด์๋]
ํ๊ตญ์ด์ ํน์ง์ ์ด์ ์ ์ผ์ชฝ์ ์์นํ ๊ธ์๋ค์ด ์๋ฏธ๋ฅผ ์ง๋๋ ๋จ์ด๋ค์ด๋ฉฐ, ์ค๋ฅธ์ชฝ์ ์์นํ ๊ธ์๋ค์ ๋ฌธ๋ฒ๊ธฐ๋ฅ์ ํ๋ ์กฐ์ฌ์ ์ด๋ฏธ๋ผ๋ ์ ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์ด์ ์ ์ผ์ชฝ๋ถ๋ถ์ ์ด์ฉํด ๋จ์ด์ฌ์ ์ผ๋ก ๋ง๋ค ๊ฒ์ด๋ค.
WordRank ์๊ณ ๋ฆฌ์ฆ์ keyword extraction ๋ฅ๋ ฅ์ด ์๋ค. ranking ์ด ๋์ ๋ง๋๋ ๋จ์ด์ผ ๋ฟ ์๋๋ผ, ๊ทธ ๋ฐ์ดํฐ์
์์ ์์ฃผ ๋ฑ์ฅํ๋ ๋จ์ด์ด๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฝํ๋ keywords ๋ก ์ด์ฉ๋ ์ ์๋ค.
keyword extraction : ์๋ณธ ๋ฌธ์๋ฅผ ๊ฐ์ฅ ์ ํ๋๋ด๋ ์ค์ํ ์ฉ์ด ๋๋ ๊ตฌ๋ฌธ์ ์ฐพ์๋ด๋ ์์

<for text in df['์ฑ
์๊ฐ']:
text.split('\n')
text_list.append(text.split('\n'))
text_list[:2]
from krwordrank.hangle import normalize
texts = [[normalize(text, english=True, number=True) for text in texts] for texts in text_list]
texts[:2]
KRWordRank ํจํค์ง๋ฅผ ์ด์ฉํ์ฌ โ์ฑ
์๊ฐ ์ ์ฒ๋ฆฌโ ์ด์์ ์ค์ํ ํค์๋๋ฅผ ์ถ์ถํ๊ณ , ์ด๋ฅผ ๊ธฐ์กด Dataframe์์ '์ฑ
์๊ฐ ํค์๋ ์์ ๋ณธ' ์ด๋ก ์ถ๊ฐํ๋ค.from krwordrank.word import KRWordRank
from konlpy.tag import Okt
def KeyWord(x):
sentence = []
wordrank_extractor = KRWordRank(
min_count = 1, # ๋จ์ด์ ์ต์ ์ถํ ๋น๋์ (๊ทธ๋ํ ์์ฑ ์)
max_length = 10, # ๋จ์ด์ ์ต๋ ๊ธธ์ด
verbose = True
)
beta = 0.85 # PageRank์ decaying factor beta
max_iter = 20
keywords, rank, graph = wordrank_extractor.extract(x, beta, max_iter)
word_list = list()
for word, r in sorted(keywords.items(), key=lambda x:x[1], reverse=True)[:30]:
if r >=1:
word_list.append(word)
# ํ ๋ฌธ์ฅ์ผ๋ก ํฉ์น๋ค.
sent = ' '.join(word_list)
sentence.append(sent)
# ํํ์ ์ถ์ถ
okt = Okt()
OKT = okt.pos(sent)
keyword_list = []
# ์กฐ์ฌ์ ์ ๋ฏธ์ฌ๋ฅผ ์ ์ธํ ๋๋จธ์ง๋ง์ ํค์๋๋ก ์ฑํ
for word, tag in OKT:
if (tag not in ['Josa']) and (tag not in ['Suffix']):
keyword_list.append(word)
return keyword_list
df['์ฑ
์๊ฐ ํค์๋ ์์ ๋ณธ'] = df['์ฑ
์๊ฐ ํค์๋'].apply(KeyWord)
๐ ์ฐธ๊ณ ์๋ฃ : https://lovit.github.io/nlp/2018/04/16/krwordrank/