본문 바로가기

Project/TakePicture_GetResult

[NLP]자연어처리_키워드추출

반응형

아래 자연어처리는 네이버 플레이스에서 크롤링한

네이버 블로그리뷰 데이터를 사용하여 진행

 

 

 

KR-WordRank

키워드 추출 라이브러리

- 비지도학습 방법으로 한국어 텍스트에서 단어/키워드를 자동으로 추출하는 라이브러리.

 

< Reference >

https://github.com/lovit/KR-WordRank

 

lovit/KR-WordRank

비지도학습 방법으로 한국어 텍스트에서 단어/키워드를 자동으로 추출하는 라이브러리입니다. Contribute to lovit/KR-WordRank development by creating an account on GitHub.

github.com

 

Keyword extraction process

# substring graph를 만들기 위한 변수의 값 설정

- min_count : 단어의 최소 출현 빈도 수 (그래프 생성 시)

- max_length : 단어의 최대 길이

 

<CODE>

from krwordrank.word import KRWordRank

min_count = 5   # 단어의 최소 출현 빈도수 (그래프 생성 시)
max_length = 10 # 단어의 최대 길이
wordrank_extractor = KRWordRank(min_count, max_length)

 

 

# graph ranking알고리즘을 사용하여 단어추출 (HITS algorithm)

- Substring graph에서 node(substring)의 랭킹을 계산하기 위해 graph ranking알고리즘의 parameters가 필요

- beta : PageRank의 decaying factor beta

- max_iters

- verbose 

- text : 인풋으로 들어가는 문장. 타입은 문자열의 리스트여야한다.

 

<CODE>

beta = 0.85    # PageRank의 decaying factor beta
max_iter = 10
verbose = True
texts = ['예시 문장 입니다', '여러 문장의 list of str 입니다', ... ]
keywords, rank, graph = wordrank_extractor.extract(texts, beta, max_iter, verbose)

 

 

# Graph ranking이 높은 노드(substring)이 출력

- 후처리 과정을 거쳐 단어로 출력 된다.

 

<CODE>

for word, r in sorted(keywords.items(), key=lambda x:x[1], reverse=True)[:30]:
        print('%8s:\t%.4f' % (word, r))

 

 

# summarize_with_keywords 

- 위의 과정을 간단하게 수행하는 함수

- stop_words : Figure에 나타내지 않을 일반적인 단어

 

<CODE>

from krwordrank.word import summarize_with_keywords

keywords = summarize_with_keywords(texts, min_count=5, max_length=10,
    beta=0.85, max_iter=10, stopwords=stopwords, verbose=True)
keywords = summarize_with_keywords(texts) # with default arguments

 

 

Keyword extraction process

- KR-WordRank >= 1.0.0 부터 사용가능

- keywords가 많이 포함한 문장을 핵심 문장으로 선택

- 문장추출원리 : 추출 된 키워드의 랭크 값으로 키워드 벡터 생성

                         코싸인 유사도 기준으로 입력된 문장 벡터가 키워드 벡터와 유사한 문장 선택

 

<< summarize_with_sentences >>

# 라이브러리 로딩

from krwordrank.sentence import summarize_with_sentences

 

# summarize_with_sentences

texts = []

penalty = lambda x:0 if (25 <= len(x) <= 80) else 1
stopwords = {'영화', '관람객', '너무', '정말', '진짜'}

keywords, sents = summarize_with_sentences(
    texts,
    penalty=penalty,
    stopwords = stopwords,
    diversity=0.5,
    num_keywords=100,
    num_keysents=10,
    verbose=False
)

 

<< INPUT >>

- texts : 문자열의 리스트 형태로

 

<< PARAMETERS >>

- penalty : 패널티 설정 가능

- stopwords : 키워드에서 제거될 단어, 키워드 벡터를 만들때도 사용하지 않는다.

- diversity : 코싸인 유사도 기준 핵심문장간의 최소 거리, 값이 클수록 다양한 문장 선택

- num_keywords : 키워드로 추출 될 키워스 갯수를 설정.

- num_keysents : 핵심문장으로 추출 될 문장의 갯수 설정.

 

<< OUTPUT >>

- keywords : KR-WordRank로 학습된 키워드와 랭크 값이 dict형태로

- sents : 핵심 문장이 list of str 형식

 

 

 

NLP : Korean Text (요약 자료)

- 실제 프로젝트에 사용한 자연어처리 흐름

 

# 발표자료

- 키워드 추출에 사용된 발표자료

 

 

NLP : 사용한 코드

# 사용할 json 파일 로딩

import json
with open('blog_review.json', 'r', encoding='utf-8-sig') as f:
    blog = json.load(f)

- 자연어처리를 진행 할 블로그 데이터를 load한다

 

 

# 블로그리뷰가 있는 레스토랑만 가져오기

blog_list = []

for k in blog.keys():
    if len(blog[k]) == 0:
        continue
    blog_list.append(k)

- 블로그 리뷰 중 데이터가 있는 레스토랑 리스트 추출하기

 

 

# 전처리 함수 생성

from konlpy.tag import Kkma
from konlpy.tag import Okt

kkma = Kkma()
okt = Okt()

import sys
import os
import re
sys.path.append(os.path.dirname('PyKoSpacing/'))
from pykospacing import spacing

def preprocessing(review, name):
    total_review = ''
    #인풋리뷰
    for idx in range(len(review)):
        r = review[idx]
        #하나의 리뷰에서 문장 단위로 자르기
        sentence = re.sub(name.split(' ')[0],'',r)
        sentence = re.sub(name.split(' ')[1],'',sentence)
        sentence = re.sub('\n','',sentence)
        sentence = re.sub('\u200b','',sentence)
        sentence = re.sub('\xa0','',sentence)
        sentence = re.sub('([a-zA-Z])','',sentence)
        sentence = re.sub('[ㄱ-ㅎㅏ-ㅣ]+','',sentence)
        sentence = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]','',sentence)
        if len(sentence) == 0:
            continue
        sentence = okt.pos(sentence, stem = True)
        word = []
        for i in sentence:
            if not i[1] == 'Noun':
                continue
            if len(i[0]) == 1:
                continue
            word.append(i[0])
        word = ' '.join(word)
        word += '. '
        total_review += word
    return total_review

- 자연어처리에 기본이 되는 전처리 함수 생성

 

 

# 키워드 추출 함수 생성

from krwordrank.sentence import summarize_with_sentences

stop = 0

for b_idx in blog_list[5:]:
    print(b_idx)
    stop += 1
    test = blog[b_idx]
    st = ''
    for r in range(len(test)):
        texts = test[r]
        texts = preprocessing(texts, b_idx)
        st += texts
    texts = st.split('. ')
    try:
        stopwords = {b_idx.split(' ')[0], b_idx.split(' ')[1]}
        keywords, sents = summarize_with_sentences(
                                               texts, 
                                               stopwords = stopwords,
                                               num_keywords=100, 
                                               num_keysents=10
                                               )
    except ValueError:
        print('key가 없습니다.')
        print()
        continue
        
    for word, r in sorted(keywords.items(), key=lambda x:x[1], reverse=True)[:7]:
        #print('%8s:\t%.4f' % (word, r))
        print('#%s' % word)
    print()
    if stop == 50:
        break

- 아래의 그림과 같이 키워드중 랭크값이 높은 상위 5개만 해당 레스토랑의 태그로 출력되도록 설정

- 키워드 추출은 gensim의 summarize_with_sentences 함수를 사용한다.

- 위 함수는 WordRank알고리즘을 기반으로 만들어졌다.

 

결과 이미지

 

반응형