일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 최소자승법
- 텍스트 분류
- 밑바닥부터 시작하는 딥러닝2
- 자연어 처리
- rnn
- 군집화
- 회귀분석
- 코사인 유사도
- 다층 퍼셉트론
- 파이썬 pandas
- 밑바닥부터 시작하는 딥러닝
- Django
- 기술통계학
- word2vec
- 머신러닝
- Pandas
- F분포
- 결정계수
- 모두의 딥러닝
- 기초통계
- numpy
- 차원축소
- 은준아 화이팅
- 구글 BERT의 정석
- 가설검정
- 오래간만에 글쓰네
- 텐서플로2와 머신러닝으로 시작하는 자연어처리
- student t분포
- 감성분석
- 히스토그램
- Today
- Total
데이터 한 그릇
텍스트 분류(1) - 텍스트 데이터 EDA 및 전처리 본문
텍스트 데이터에서 다양한 방법으로 텍스트 분류 모델을 만들기 전에,
EDA 작업과 전처리 작업을 진행할 예정.
데이터는 kaggle 에 있는 wrod2vec -nlp-tutorial 데이터를 사용할 것.
이때 캐글의 데이터는 직접 홈페이지 다운 방식이 아니라 api 를 사용.
데이터 EDA
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
!kaggle competitions download -c word2vec-nlp-tutorial
캐글 api 이용해서 wrod2vec -nlp-tutorial 데이터 다운.
DATA_IN_PATH = './data_in/'
TRAIN_INPUT_DATA = 'train_input.npy'
TRAIN_LABEL_DATA = 'train_label.npy'
TRAIN_CLEAN_DATA = 'train_clean.csv'
DATA_CONFIGS = 'data_configs.json'
train_data = pd.read_csv(DATA_IN_PATH + "labeledTrainData.tsv", header = 0, delimiter = "\t",
quoting = 3)
데이터 압축파일을 풀어주면 그 안에 데이터 폴더 경로대로 train 데이터 불러오기.
(이 데이터는 감정값이 label 되어 있음)
train_length = train_data['review'].apply(len)
train_length
plt.figure(figsize = (12,5))
plt.hist(train_length, bins = 200, alpha = 0.5, color = 'r', label='word')
plt.yscale('log', nonposy='clip')
plt.title('Log-Histogram of length of review')
plt.xlabel('Length of review')
plt.ylabel('Number of review')
리뷰의 길이를 히스토그램으로 시각화 하기 (각 리뷰마다의 길이)
print('리뷰 중 최대 길이 : ', np.max(train_length))
print('리뷰 길이 최솟값 : ', np.min(train_length))
print('리뷰 길이 평균값 : ', np.mean(train_length))
print('리뷰 길이 표준편차 : ', np.std(train_length))
print('리뷰 길이 중간값 : ', np.median(train_length))
plt.figure(figsize = (12,5))
plt.boxplot(train_length,
labels = ['counts'],
showmeans = True)
리뷰 기초 통계 값을 수치로 나타내기.
리뷰 기초 통계 값을 박스 플롯으로 나타내기.
from wordcloud import WordCloud
cloud = WordCloud(width = 800, height = 600).generate(" ".join(train_data['review']))
plt.figure(figsize = (20,15))
plt.imshow(cloud)
plt.axis('off')
워크클라우드 시각화하기.
#라벨 개수 세기
sns.countplot(train_data['sentiment'])
우리가 분류해보려고 하는 감성 값들(정답값)의 value_count 해보기
데이터 전처리
import re
import pandas as pd
import numpy as np
import json
from bs4 import BeautifulSoup
from nltk.corpus import stopwords
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.preprocessing.text import Tokenizer
전처리에 사용할 패키지 및 모듈 불러오기
데이터 특수문자 제거
review = train_data['review'][0]
review_text = BeautifulSoup(review, 'html5lib').get_text() #HTML 태그 제거
review_text
review_text = re.sub("[^a-zA-Z]"," ", review_text) #특수문자 제거
리뷰 한 개에 대해서 먼저 전처리 해보기. (train_data['review'][0] 이 리뷰 한 개를 의미한다.
리뷰 안에 HTML 태그들이 달려 있는데, HTML 태그를 제거하기 위해서 크롤링 객체 사용하기.
BeautifulSoup(review, 'html5lib').get_text() 로 문서 내 텍스트만 가져오기.
그 다음 정규식 모델 re 를 사용해서 특수문자 제거하기.
이때 리뷰는 영어로만 이루어져 있으므로 영어를 제외한 특수문자는 제외히기로 한다.
[^a-zA-Z] 를 사용
불용어 제거
stop_words = set(stopwords.words('english'))
#소문자로 바꾸기
review_text = review_text.lower()
#단어별로 tokenize
words = review_text.split(' ')
#불용어 제거
words = [w for w in words if w not in stop_words]
#다시 문장으로 합치기
clean_review = " ".join(words)
clean_review
자연어 처리 패키지 NLTK 를 사용해서 불용어처리 하기
nltk 패키지 stopwords 에는 각 국가별 stopwords 들이 포함되어 있음.
stopwords.words('english') 를 사용해서 영어 스톱워드들은 "stop_words" 변수에 저장.
전처리 작업을 위해서 모든 reivew 들을 소문자로 전환.
리뷰들을 단어 단위로 나누고 그 단어들을 stop_words 변수 안에 저장되어 있는 스톱워드들과 비교해서 스톱워드 아닌 것들만 따로 words 에 저장.
스톱워드 제거된 클린된 단어들을 이용해서 다시 문장으로 변환.
전체 review 에 대해서 전처리
#전처리 과정 함수로 만들기
def preprocessing(review, remove_stopwords = False):
#불용어 제거는 옵션으로 선택
#HTML 태그 제거
review_text = BeautifulSoup(review,'html5lib').get_text()
#소문자로 전환, 단어별로 보기
review_text = review_text.lower()
words = review_text.split(' ')
#불용어 제거
if remove_stopwords == True:
stops = set(stopwords.words('english'))
words = [w for w in words if w not in stops]
clean_review = ' '.join(words)
else:
clean_review = ' '.join(words)
clean_train_review = []
for review in train_data['review']:
clean_train_review.append(preprocessing(review, remove_stopwords = True))
return clean_review
앞서 진행한 리뷰 한 개에 대한 특수문자 제거, 소문자 전환, 단어 tokenize, 불용어 제거 과정을 함수로 만들고 이를 리뷰 전체에 적용하기.
for 문을 사용해서 각각의 review 를 꺼내고 각 review 들에 대해서 전처리 작업을 진행한 이후에 전처리 된 리뷰를 clean_train_review 리스트에 담아서 마지막에 return.
데이터 프레임 생성
clean_train_df = pd.DataFrame({'review':clean_train_review, 'sentiment' : train_data['sentiment']})
clean_train_df
review 칼럼에는 전처리된 리뷰 전체 데이터인 "clean_train_review" 를 넣어주고, 감정 값으로는 이미 공개되어 있는 train_data 의 "sentiment" 칼럼을 사용한다.
입력값 길이 조절
#입력값의 길이가 같아야 한다.
tokenizer = Tokenizer()
tokenizer.fit_on_texts(clean_train_review)
text_sequences = tokenizer.texts_to_sequences(clean_train_review)
자연어 입력값들의 특징 중 하나는 각각 입력 길이가 다르다는 점이다. 각각의 입력 데이터 길이가 다른 이유는, 리뷰마다 글의 길이가 다르기 때문이다.
모델을 만들기 위해서는 입력값의 길이가 동일한게 좋기 때문에 입력값의 길이를 동일하게 만든다.
tensorflow의 keras 에는 텍스트 전처리 모듈인 Tokenizer 가 들어있다. Tokenizer 를 이용해서 문장을 단어들의 집합으로 만든다.
Tokenizer 는 fit_on_texts 함수를 제공한다. fit_on_texts 함수를 적용하면 문서의 단어들에 대해서 id를 부여해준다.
"I like banana" 가 있으면 각각의 단어 i, like, banana 에 대해서 id 를 부여해준다.
tokenizer 는 이를 기억해두고 있다고 texts_to_sequences 를 이용해서 문장을 단어id 의 시퀀스로 변환해준다.
"I like banana" 가 있고, {I : 1, like : 2, banana : 3"} 이면 [1,2,3] 을 반환한다.
word_vocab = tokenizer.word_index
# word_vocab[word_vocab.values == 354]
word_vocab["<PAD>"] = 0
print(word_vocab)
data_configs = {}
data_configs['vocab'] = word_vocab
data_configs['vocab_size'] = len(word_vocab)
tokenizer의 word_index 함수를 사용하면, 단어와 그 단어에 대한 id 값의 딕셔너리가 도출된다.
이 값을 word_vocab 변수에 저장해둔다.
만일 이 vocab_size 에 len 내장함수를 사용하면 단어들이 몇 개가 있는지 나타낼 수 있다.
data_configs 라는 딕셔너리를 새로 만들어서, word_vocab 딕셔너리 값과, 단어가 몇 개 있는지 나타내는 len(word_vocab) 을 넣어준다. (나중을 위해서)
#패딩의 최대 길이는 단어나온 횟수의 중간 길이를 사용 (평균도 좋지만 이상치 때문에)
MAX_SEQUENCE_LENGTH = 174
train_inputs = pad_sequences(text_sequences, maxlen = MAX_SEQUENCE_LENGTH, padding = 'post')
print(train_inputs.shape)
train_labels = np.array(train_data['sentiment'])
train_labels.shape
앞서 fit_on_texts 와 texts_to_sequence 함수를 통해서 문장에 대해 단어id 시퀀스로 바꾸었다.
이 값들의 길이는 각각 문장의 길이에 따라서 다르기 때문에 tensorflow keras preprocessing 내에 있는 pad_sequences 로 길이를 통일해준다. 그리고 그 결과 값을 train_inputs 변수에 저장한다.
최대 길이를 maxlen 파라미터로 조절할 수 있는데 이를 174 로 지정해준다.
padding 함수는 길이를 맞추기 위한 작업을 문장 앞에서 진행할지 뒤에서 진행할지 결정하는 파라미터다.
X데이터 뿐만 아니라 label 데이터도 따로 지정해야만 한다.
train_label 변수에 train_data 의 label 값을 저장해준다.
정리
지금까지 영어 자연어에 대한 전처리 과정을 정리해보면,
먼저 문장에 대한 특수문자를 제거한 이후, 전처리 작업을 위해서 모두 소문자로 바꿔주고, 단어로 token 화 시킨 후,
불용어 사전을 꺼내어 token 화 된 단어들 중에서 불용어가 아닌 것들만 추려내고 이를 다시 문장화 시킨다.
그리고 Tokenizer 함수를 이용해서 모든 단어들에 대해서 ID 를 부여한 이후, 문장을 단어 ID의 시퀀스로 변환한다.
그리고 입력 데이터의 길이를 통일시킨다.
'NLP > 텐서플로2와 머신러닝으로 시작하는 자연어처리' 카테고리의 다른 글
텍스트 유사도 (0) | 2022.01.28 |
---|---|
텍스트 분류(2) - 다양한 모델링 기법 (0) | 2022.01.27 |
자연어 처리 개요_자연어 생성과 기계 이해 (0) | 2022.01.09 |
자연어 처리 개요_텍스트 분류 (0) | 2022.01.09 |
자연어 처리 개요_텍스트 유사도 (0) | 2022.01.09 |