일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 클래스 분류
- 문맥을 반영한 토픽모델링
- 자연어 모델
- 트위치
- SBERT
- BERTopic
- 블루 아카이브
- geocoding
- 코사인 유사도
- CTM
- 구글 스토어 리뷰
- 피파온라인 API
- LDA
- Tableu
- Roberta
- NLP
- 데이터리안
- 블루아카이브 토픽모델링
- 데벨챌
- 포아송분포
- 원신
- KeyBert
- 붕괴 스타레일
- 개체명 인식
- 다항분포
- 토픽 모델링
- 옵티마이저
- 데이터넥스트레벨챌린지
- 조축회
- Optimizer
- Today
- Total
분석하고싶은코코
텍스트 마이닝 - Bag of words / TF-IDF 본문
개인 프로젝트를 진행하면서 텍스트 마이닝 할 일이 생겨서 공부하게 되었다.
단어의 등장 순서에 상관없이 빈도수에 집중한 표현 방식이다.
1. Bag of Words ? TF-IDF ?
1. Bag of Words란 단어들의 순서는 전혀 고려하지 않고, 단어들의 출현 빈도(frequency)에만 집중하는 텍스트 데이터의 수치화 표현 방법이다. Bag of Words를 직역하면 단어들의 가방이라는 의미이다. (여유 있는 가방에 물건을 넣고 다녔을때 넣었을 때 모양 그대로 유지되기 어렵다. 그런 의미에서 가방이라는 표현을 쓴 듯..?)
2. TF-IDF(Term Frequency - Inverse Document Frequency)란 정보 검색과 텍스트 마이닝에서 사용하는 가중치를 이야기한다. 문서군에서 특정 단어가 그 안에서 얼마나 중요한지를 나태내는지를 보여주는 통계적 수치이다.
두 가지를 파이썬에서 구현해보기 앞서 파이썬에서 한글을 다루는 패키지에 대해서 먼저 알아봐야했다.
2.KoNLPy(코앤엘파이) - 한국어 정보처리 패키지
1) KoNLPy - 한국어 정보처리 패키지
KoNLPy에서는 대한민국 헌법 말뭉치인 kolaw와 국회법안 말뭉치인 kobill을 제공한다. 각 말뭉치가 포함하는 파일의 이름은 fields 메서드로 알 수 있고 open 메서드로 해당 파일의 텍스트를 읽어들인다.
from konlpy.corpus import kolaw
kolaw.fileids()
c = kolaw.open('constitution.txt').read()
print(c[:40])
대한민국헌법
유구한 역사와 전통에 빛나는 우리 대한국민은 3·1운동으로
from konlpy.corpus import kobill
kobill.fileids()
d = kobill.open('1809890.txt').read()
print(d[:40])
지방공무원법 일부개정법률안
(정의화의원 대표발의 )
의 안
번 호
2) 형태소 패키지
KoNLPy는 다음과 같은 다양한 형태소 분석, 태깅 라이브러리를 파이썬에서 쉽게 사용할 수 있도록 모아놓았다.
- Hannanum: 한나눔. KAIST Semantic Web Research Center 개발.
- Kkma: 꼬꼬마. 서울대학교 IDS(Intelligent Data Systems) 연구실 개발.
- Komoran: 코모란. Shineware에서 개발.
- Mecab: 메카브. 일본어용 형태소 분석기를 한국어를 사용할 수 있도록 수정.
- Open Korean Text: 오픈 소스 한국어 분석기. 과거 트위터 형태소 분석기.
이 클래스들은 다음과 같은 메서드를 공통적으로 제공한다.
- nouns : 명사 추출
- morphs : 형태소 추출
- pos : 품사 부착
예시는 Okt(Open Korean Text)로 진행
from konlpy.tag import *
okt = Okt()
print(okt.nouns(c[:40]))
print(okt.morphs(c[:40]))
print(okt.pos(c[:40]))
#okt.tagset
['대한민국', '헌법', '유구', '역사', '전통', '우리', '국민', '운동']
['대한민국', '헌법', '\n\n', '유구', '한', '역사', '와', '전통', '에', '빛나는', '우리', '대', '한', '국민', '은', '3', '·', '1', '운동', '으로']
[('대한민국', 'Noun'), ('헌법', 'Noun'),
('\n\n', 'Foreign'), ('유구', 'Noun'),
('한', 'Josa'), ('역사', 'Noun'),
('와', 'Josa'), ('전통', 'Noun'),
('에', 'Josa'), ('빛나는', 'Verb'),
('우리', 'Noun'), ('대', 'Modifier'),
('한', 'Modifier'), ('국민', 'Noun'),
('은', 'Josa'), ('3', 'Number'),
('·', 'Punctuation'), ('1', 'Number'),
('운동', 'Noun'), ('으로', 'Josa')]
+ okt.tagset을 통해서 품사 목록 확인 가능.
4. 단어 분리 예제
Tripadvisor 여행사이트에서 "제주 호텔"로 검색해서 나온 리뷰들을 활용
(https://www.tripadvisor.co.kr)
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
df = pd.read_csv("https://raw.githubusercontent.com/yoonkt200/FastCampusDataset/master/tripadviser_review.csv")
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1001 entries, 0 to 1000
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 rating 1001 non-null int64
1 text 1001 non-null object
dtypes: int64(1), object(1)
memory usage: 15.8+ KB
텍스트 확인
df['text'][0]
여행에 집중할수 있게 편안한 휴식을 제공하는 호텔이었습니다. 위치선정 또한 적당한 편이었고 청소나 청결상태도 좋았습니다.
텍스트에서 한글만 가져오기
import re
def apply_regular_expression(text):
hangul = re.compile('[^ ㄱ-ㅣ 가-힣]') # 한글 추출 규칙: 띄어 쓰기(1 개)를 포함한 한글
result = hangul.sub('', text) # 위에 설정한 "hangul"규칙을 "text"에 적용(.sub)시킴
return result
print(apply_regular_expression(df['text'][0]))
여행에 집중할수 있게 편안한 휴식을 제공하는 호텔이었습니다 위치선정 또한 적당한 편이었고 청소나 청결상태도 좋았습니다
형태소 추출 - KoNLPy -> Okt 사용
from konlpy.tag import Okt
from collections import Counter
# 형태소 추출
okt = Okt() # 명사 형태소 추출 함수
nouns = okt.nouns(apply_regular_expression(df['text'][0]))
nouns
['여행', '집중', '휴식', '제공', '호텔', '위치', '선정', '또한', '청소', '청결', '상태']
모든 리뷰를 하나의 텍스트로 합쳐 형태소 추출 후 상위 10개 항목 출력.
corpus = "".join(df['text'].tolist())
nouns = okt.nouns(apply_regular_expression(corpus))
counter = Counter(nouns)
counter.most_common(10)
[('호텔', 803),
('수', 498),
('것', 436),
('방', 330),
('위치', 328),
('우리', 327),
('곳', 320),
('공항', 307),
('직원', 267),
('매우', 264)]
'수', '것', '방', '곳'과 같은 한 글자 단어는 분석에 방해되는 요소들 같아 삭제 진행
available_counter = Counter({x: counter[x] for x in counter if len(x) > 1})
available_counter.most_common(10)
[('호텔', 803),
('위치', 328),
('우리', 327),
('공항', 307),
('직원', 267),
('매우', 264),
('가격', 245),
('객실', 244),
('시설', 215),
('제주', 192)]
단어 목록중 의미가 없는 단어들(불용어)를 제거 작업을 진행. 지금까지으 과정을 모두 합쳐 하나의 함수에서 작업을 진행.
# 불용어 사전 불러오기
stopwords = pd.read_csv("https://raw.githubusercontent.com/yoonkt200/FastCampusDataset/master/korean_stopwords.txt").values.tolist()
def text_cleaning(text):
hangul = re.compile('[^ ㄱ-ㅣ 가-힣]') # 정규 표현식 처리
result = hangul.sub('', text)
okt = Okt() # 형태소 추출
nouns = okt.nouns(result)
nouns = [x for x in nouns if len(x) > 1] # 한글자 키워드 제거
nouns = [x for x in nouns if x not in stopwords] # 불용어 제거
return nouns
BoW만들기
CountVectorizer는 단어 집합에서 단어를 집계하여 BoW인코딩 백터를 생성해준다.
from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer(tokenizer = lambda x: text_cleaning(x))
bow_vect = vect.fit_transform(df['text'].tolist())
word_list = vect.get_feature_names()
count_list = bow_vect.toarray().sum(axis=0)
1. vect 변수는 (text_cleaning)을 모두 걸친 텍스트 모음을 CountVectorizer해주는 lambda 설정
2. vect에 모든 리뷰가 담긴 텍스트를 리스트 형태로 넘겨주면 lambda 실행됨
3. 토근 형태로 들어가 있기 때문에 딕셔너리 형태로 넣어주기 위해 word 키워드를 가져오고
4. 각 리뷰마다 단어가 카운트 되어 있는 것을 배열 형태로 나열한 후 열 기준으로 합쳐 빈도수를 구한다.
word_count_dict = dict(zip(word_list, count_list))
word_count_dict
zip을 통해 (단어 키워드 : 빈도수)로 정리된 단어 딕셔너리를 만들어준다.
'가가': 4,
'가게': 8,
'가격': 245,
'가격표': 1,
'가구': 8,
'가급': 1,
'가기': 20,
'가까이': 20,
'가끔': 5,
'가능': 10,
'가도': 7,
.
.
.
TF-IDF 중요도 나타내기
from sklearn.feature_extraction.text import TfidfTransformer
tfidf_vectorizer = TfidfTransformer()
tf_idf_vect = tfidf_vectorizer.fit_transform(bow_vect)
# 첫 번째 리뷰에서의 단어 중요도(TF-IDF 값) -- 0이 아닌 것만 출력
print(tf_idf_vect[0])
첫번째 리뷰 단어의 중요도
(0, 3588) 0.35673213299026796
(0, 2927) 0.2582351368959594
(0, 2925) 0.320251680858207
(0, 2866) 0.48843555212083145
(0, 2696) 0.23004450213863206
(0, 2311) 0.15421663035331626
(0, 1584) 0.48843555212083145
(0, 1527) 0.2928089229786031
(0, 790) 0.2528176728459411
텍스트 마이닝을 위한 기본적인 데이터 전처리 방법에 대해서 알아보았다. 이를 활용해서 별점이나 방문횟수 등 여러가지 요인들을 복학접으로 활용한다면 리뷰에 대한 긍/부정에 대한 판단하는 모델을 만들 수 있을 것 같다는 생각이든다. 다음에는 리뷰를 긍/부정에 대해서 평가하는 모델에 대해서 포스팅 할 계획이다.
'데이터분석' 카테고리의 다른 글
따릉이 수요량 예측 (0) | 2023.01.03 |
---|---|
스타벅스 매장은 정말 매장마다 차이가 없을까?? - (1) (0) | 2022.12.12 |
이디야는 스타벅스 근처에 입점한다? (0) | 2022.11.25 |
제주도 교통량 예측(1)_EDA (0) | 2022.10.11 |
데이터분석(4) - 타이타닉 생존자 구하기 (0) | 2022.06.27 |