새소식

반응형
AI/tutorials

키워드 추출하기 (1)

  • -
728x90
반응형

키워드 추출 (Keyword Extraction)이란?

  • Keyword extraction is about automatically finding what’s relevant in a large set of data.
  • 문서를 가장 잘 나타내는 N개의 키워드를 찾는 작업

 

1. Model  < KeyBERT >

  • 문서를 가장 잘 나타내는 키워드 또는 키구문을 찾아주는, 쉽게 사용 가능한 BERT-based 모델
 

KeyBERT

KeyBERT 란? KeyBERT is a minimal and easy-to-use keyword extraction technique that leverages BERT embeddings to create keywords and keyphrases that are most similar to a document. 문서를 가장 잘 나타내는 키워드 또는 키구문을 찾아주

pinopino.tistory.com

 

 

2. Data  < 근로자 자소서 >

  • 실제 회사 근로자의 자소서 데이터
    • 근로자 자소서 : 근로자 id 와 자기소개 텍스트

 

텍스트 데이터 읽어오기

import pandas as pd
df = pd.read_csv('근로자_자기소개.csv')
array_text = pd.DataFrame(df['introduction']).to_numpy()

 

한국어 텍스트 데이터 전처리

  • 텍스트 클리닝 (html / url / 특수 문자 제거 등)
    • ㄱ-ㅎ/ㅏ-ㅣ 등 자음과 모음으로만 이루어진 글자들 제거
    • @#$%^&*() 등 puctuation(문장부호) 제거
  • 띄어쓰기 및 맞춤법 검사
    • 띄어쓰기 : pykospacing 라이브러리 사용
    • 맞춤법 검사 : py-hanspell 라이브러리 사용
  • [PLUS] 한 단어짜리 자기소개 제거
    • ex) 꼼꼼하게, 안녕하세요, 일, ...
    • 위는 키워드 추출에 의미가 없다고 판단해 제거
  • Pos Tagging + Stemming 
    • 형태소 분석 후, 동사를 명사형으로 변환
    • 명사만 남기기
  • Stop word 제거
 

한국어 텍스트 데이터 전처리

1) 텍스트 클리닝 (html / url / 특수 문자 제거 등) 크롤링 데이터의 경우 html tag 제거 필요하지 않은 특수문자 매핑 또는 제거 ㄱ-ㅎ/ㅏ-ㅣ 등 자음과 모음으로만 이루어진 글자들 제거 @#$%^&*() 등 puc

pinopino.tistory.com

 

 

 

3. 키워드 추출

3-1. 각 사람 별(문장 별) 키워드 추출하기

from keybert import KeyBERT
from transformers import BertModel

def keyword(array_text):
    bow = []
    model = BertModel.from_pretrained('skt/kobert-base-v1')
    kw_extractor = KeyBERT(model)
    
    # 문장 별 키워드 1개씩 추출
    for i in range(len(array_text)):
        keywords = kw_extractor.extract_keywords(array_text[i], top_n=1)
        bow.append(keywords)
    
    # 키워드 전달하기
    keyword = pd.DataFrame(bow, columns=['keyword', 'weight'])
    return keyword
keyword_cv = keyword(array_text)

# 상위 20개의 키워드 출력
print(keyword_cv.groupby('keyword').agg('sum').sort_values('weight', ascending='False').head(20))

 

  • 결과가 애매~ 하다
  • BERT embedding 과정에서 띄어쓰기 구분 없이 구문 통째로 임베딩 되는 듯 하다.

 

 

3-2. 전체 텍스트에서 키워드 추출하기

  • 두 단어로 적용 (keyphrase_ngram_range 변수)
from keybert import KeyBERT
from transformers import BertModel

def keyword_one(text, top_n, use_mmr, diversity):
    model = BertModel.from_pretrained('skt/kobert-base-v1')
    kw_extractor = KeyBERT(model)
    keywords = kw_extractor.extract_keywords(text, keyphrase_ngram_range=(1, 2), top_n=top_n, use_mmr=use_mmr, diversity=diversity)
    keyword = pd.DataFrame(keywords, columns=['keyword', 'weight'])
    return keyword
text = ""		# 전체 텍스트를 하나로 묶기
for t in array_text:
    text += " " + t
    
keyword_cv2 = keyword_one(text2, top_n=20, use_mmr=True, diversity=0.3)

# 상위 20개의 키워드 출력
print(keyword_cv2.groupby('keyword').agg('sum').sort_values('weight', ascending='False').head(20))

 

 

  • 분명 2개 단어로 지정했는데.. 문장이 나왔다.
  • BERT embedding 과정에서 띄어쓰기 구분 없이 구문 통째로 임베딩 되는게 맞는 것 같다.
  • 형태소 분석 후 명사형만 보내보자.

 

3-3. 형태소 분석 후 하나로 묶어서 분석

from kiwipiepy import Kiwi

def noun_extractor(text):
    results = [[] for _ in range(len(text))]
    kiwi = Kiwi()
    
    # 문장 별로 형태소 분석 후, 명사만 하나의 텍스트로 만들기
    for i, t in enumerate(text):
        result = kiwi.analyze(t)
        for token, pos, _, _ in list(result)[0][0][0]:
        	# 명사형만 남기기
            if len(token) != 1 and pos.startswith('N') or pos.startswith('SL'):
                results[i].append(token)
    
    noun_results = ""
    for t in results:
        noun_results += " " + " ".join(t)
        
    return noun_results
text = noun_extractor(array_text)		# 형태소 분석하기
keyword_cv3 = keyword_one(text, top_n=20, use_mmr=True, diversity=0.2)

# 상위 20개의 키워드 출력
print(keyword_cv3.groupby('keyword').agg('sum').sort_values('weight', ascending='False').head(20))

 

  • kiwi 형태소 분석기를 사용해서 진행했는데, 훨씬 결과가 좋다.
  • 현재는 단순히 명사형만 남긴 거라 Stemming 까지 한 뒤에 다시 실험해보자.

 

3-4. Stemming 후 하나로 묶어서 분석

from khaiii import KhaiiiApi
def stemming(sentence):
    morphtags = morphs = [(morph.lex, morph.tag) for word in KhaiiiApi().analyze(sentence) for morph in word.morphs]
	
    words = []
    
    for lex, tag in morphtags :
        if tag in ('NNP', 'NNG', 'SL') :
            words.append(lex)
        elif tag=='VA' or tag == 'VV':
            words.append(lex+'다')
    return words
array_text_new_5 = []

for text in array_text_new_4:
    array_text_new_5.append( stemming(text) )

 

 

text_6 = ""
for t in array_text_new_6:
    text += " " + " ".join(t) 
keyword_cv5 = keyword_one(text_6)
print(keyword_cv5.groupby('keyword').agg('sum').sort_values('weight', ascending='False').head(20))

 

  • 내 오래된 노트북에서 결과가 나오질 않는다..

 

 

 

References

반응형

'AI > tutorials' 카테고리의 다른 글

LINER PDF Chat Tutorial (2)  (0) 2024.03.06
LINER PDF Chat Tutorial  (0) 2024.03.06
한국어 텍스트 데이터 전처리  (0) 2023.04.22
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.