## 1. 라이브러리 임포트
# import numpy as np
# import pandas as pd
import numpy as np
import pandas as pd
## 2. 파일 읽어오기
# AI-HUB 감성 대화 말뭉치 활용하여 만든 데이터 읽어오기
# final_data = pd. [칸 채우기] ('https://github.com/ohgzone/file1/raw/main/aihub_coupus.csv' )
final_data = pd.read_csv('https://github.com/ohgzone/file1/raw/main/aihub_coupus.csv' )
# 데이터 확인하기
final_data.head()
# 총 51,630건
final_data.info()
## 3. 영문, 숫자, 특수문자 제거
# '문장' 컬럼의 내용중에 영문, 특수문자 있는지 확인 : 영문과 특수문자 존재 확인
# final_data[final_data['문장'].str.contains('[^가-힣 ]')].values[:10]
final_data[final_data['문장'].str.contains('[^가-힣 ]')].values[:10]
# '문장' 컬럼의 내용에서 숫자, 영문자, 특수문자등의 글자는 삭제처리
# final_data['문장'].replace('[^가-힣 ]','', regex=True) : 이렇게도 가능
# final_data['문장'] = final_data['문장'].str.replace('[^가-힣 ]','', regex=True)
final_data['문장'] = final_data['문장'].str.replace('[^가-힣 ]', '', regex= True)
# '문장' 컬럼의 내용에서 영문, 특수문자 없음 확인
# final_data['문장'][final_data['문장'].str.contains('[^가-힣 ]')].sum()
final_data['문장'][final_data['문장'].str.contains('[^가-힣 ]')].sum()
# 숫자, 영문자, 특수문자 등 제거후 데이터 확인하기.
final_data.head()
## 4. 전처리 : Null, 중복 제거
# final_data 어떤 컬럼과 내용으로 되어 있는지 다시 확인
final_data.tail()
# '문장' 컬럼의 내용을 양끝의 빈공간 삭제
# final_data['문장'] = final_data['문장'].str.strip()
final_data['문장'] =final_data['문장'].str.strip()
# 데이터 다시 확인
final_data.tail()
# Null 있는지 확인 : 없음
final_data.isnull().sum()
# 중복 데이터 있는지 확인 : 56건 중복 존재 확인
final_data['문장'].duplicated().sum()
# 중복 데이터 제거
final_data.drop_duplicates(subset=['문장'], inplace =True)
# 기존 51,630건 --> 이후 51,574건 : 56건 중복 삭제 확인
final_data.info()
## 5. Label 분포 확인
# label '감정' 분포 확인 : 총 6개이며, 고루게 분포 확인. 단 기쁨이 약간 부족해 보임
# final_data['감정']. [칸 채우기] ()
final_data['감정'].value_counts()
# plot Bar차트 그리기
final_data['감정'].value_counts().plot(kind='bar')
## 6. label 숫자로 인코딩
# 라벨와 클래스을 매핑 작업
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
final_data['감정'] = encoder.fit_transform(final_data['감정'])
encoder.classes_
final_data.tail()
## 7. X, Y 분리
# X, Y 분리
features = final_data['문장'].values
labels = final_data['감정'].values
features.shape, labels.shape
# features 내용 3개 출력
features[:3]
# print('이벤트 문자열 최대 길이 :{}'.format(max(len(l) for l in features)))
# print('이벤트 문자열 평균 길이 :{}'.format(sum(map(len, features))/len(features)))
print('even word max :{}'.format(max(len(l) for l in features)))
print ('event word avg :{}'.format(sum(map(len, features))/len(features)))
# 히스토그램을 보면 30~40 부근에 많이 몰려 있음 알수 있다.
plt.hist([len(l) for l in features], bins=50)
plt.xlabel('length of samples')
plt.ylabel('number of samples')
plt.show()
## 8. train set와 test set 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size =0.2, stratify=labels , random_state= 41)
x_train.shape, x_test.shape, y_train.shape, y_test.shape
# 샘플확인 , 라벨 확인
# {0: '불안', 1: '분노', 2: '상처', 3: '슬픔', 4: '당황', 5: '기쁨'}
x_train[:2], y_train[:2]
# 말뭉치를 TF-IDF로 변환하기
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()
x_train_v = tfidf.fit_transform(x_train)
x_test_v = tfidf.transform(x_test)
# 각 라인의 각 단어에 대한 TF-IDF 값 표현
print(x_train_v)
# 학습데이터셋의 TF-IDF 매트릭스 확인하기 : 41259 라인, 47366 단어
x_train_v.shape
## 9. 머신러닝 모델링
# 학습하는데 Colab에서 4분 소요
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
rfc.fit(x_train_v, y_train)
rfc.score(x_test_v, y_test)
### 10. 예측해 보기
# 출력 결과 해석 : (0, 44327) 0.241660101642553
# 0 : 첫라인, 44327 : 단어에 맵핑된 번호, 0.241660101642553 : tf-idf 계산 값
print('검증 데이터 셋의 첫번째 TF-IDF: {}'.format(x_test_v[0]))
print(f'검증데이터셋의 첫번째 TF-IDF 역변환 : {tfidf.inverse_transform(x_test_v[:1])}')
# RandomForest 모델로 예측하기
predict = rfc.predict(x_test_v[:1])
predict, encoder.inverse_transform(predict)
<br>
<br>
<br>
<br>
# 배운 내용 정리
1. AI-HUB 감정말뭉치 데이터 읽어오고
2. 데이터 전처리 : 한글, 공백외의 영어, 숫자, 특수문자등 제거
3. TF-IDF 토큰나이져 활용하여 토큰화하고 문장을 숫자로 나열
4. 머신러닝 RandomForest 모델을 활용하여 감성분류 수행
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
# B. LTSM 모델 이용하여 Classification하기
+ AI-HUB 감정말뭉치 데이터를 가지고
+ LSTM 모델학습하여 감정 뷴류 보겠습니다.
<br>
<br>
## 1. 라이브러리 임포트
import numpy as np
import pandas as pd
## 2. 파일 읽어오기
# AI-HUB 감성 대화 말뭉치 활용하여 만든 데이터 읽어오기
final_data = pd.read_csv('https://github.com/ohgzone/file1/raw/main/aihub_coupus.csv' )
# 데이터 확인하기
final_data.head()
# 총 51,630건
final_data.info()
## 3. 영문, 숫자 특수문자 제거
# '문장' 컬럼의 내용중에 영문, 특수문자 있는지 확인 : 영문과 특수문자 존재 확인
final_data[final_data['문장'].str.contains('[^가-힣 ]')].values[:10]
# '문장' 컬럼의 내용에서 숫자, 영문자, 특수문자등의 글자는 삭제처리
final_data['문장'] = final_data['문장'].str.replace('[^가-힣 ]','', regex=True)
# '문장' 컬럼의 내용에서 영문, 특수문자 없음 확인
final_data['문장'][final_data['문장'].str.contains('[^가-힣 ]')].sum()
# 숫자, 영문자, 특수문자 등 제거후 데이터 확인하기.
final_data.head()
## 4. 전처리 : Null, 중복 제거
# final_data 어떤 컬럼과 내용으로 되어 있는지 다시 확인
final_data.tail()
# '문장' 컬럼의 내용을 양끝의 빈공간 삭제
final_data['문장'] = final_data['문장'].str.strip()
# 데이터 다시 확인
final_data.tail()
# Null 있는지 확인 : 없음
final_data.isnull().sum()
# 중복 데이터 있는지 확인 : 56건 중복 존재 확인
final_data['문장'].duplicated().sum()
# 중복 데이터 제거
final_data.drop_duplicates(subset=['문장'], inplace=True)
# 기존 51,630건 --> 이후 51,574건 : 56건 중복 삭제 확인
final_data.info()
## 5. Label 분포 확인
# label '감정' 분포 확인 : 총 6개이며, 고루게 분포 확인. 단 기쁨이 약간 부족해 보임
final_data['감정'].value_counts()
# plot Bar차트 그리기
final_data['감정'].value_counts().plot(kind='bar')
## 6. label 숫자로 인코딩
# 감정 리스트 만듬
list1 = final_data['감정'].value_counts().index.values
list1
# 라벨와 클래스을 매핑 작업
label2class = {}
class2label = {}
for cl, la in enumerate(list1):
# print(i, j)
label2class[la] = cl
class2label[cl] = la
print(label2class)
print(class2label)
# '감정' 라벨링 수행
final_data['label'] = final_data['감정'].map(label2class)
final_data.tail()
## 7. X, Y 분리
# X, Y 분리
features = final_data['문장'].values
labels = final_data['label'].values
features.shape, labels.shape
# features 내용 3개 출력
features[:3]
print('이벤트 문자열 최대 길이 :{}'.format(max(len(l) for l in features)))
print('이벤트 문자열 평균 길이 :{}'.format(sum(map(len, features))/len(features)))
# 히스토그램을 보면 30~40 부근에 많이 몰려 있음 알수 있다.
plt.hist([len(s) for s in features], bins=50)
plt.xlabel('length of samples')
plt.ylabel('number of samples')
plt.show()
## 8. train set와 test set 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(features, labels , test_size=0.2, stratify=labels, random_state=41)
x_train.shape, x_test.shape, y_train.shape, y_test.shape
# 샘플확인 , 라벨 확인
# {0: '불안', 1: '분노', 2: '상처', 3: '슬픔', 4: '당황', 5: '기쁨'}
x_train[:2], y_train[:2]
## 9. 전체 문장에 대해 Tokenizing
+ 컴퓨터가 이해하기 위해 모든 단어를 숫자로 변환해야 함.
+ 단어 빈도수 따지지 않고 무조건 모든 단어 수용해서 진행
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# Tokenizer 구현 : 단어 사전 만들기(fit_on_texts)
tokenizer = Tokenizer()
tokenizer.fit_on_texts(x_train)
# 단어에 대한 숫자 매핑
print(tokenizer.word_index)
# 반대로 숫자로 단어 매핑
print(tokenizer.index_word)
# 단어별 빈도수 확인
print(tokenizer.word_counts)
# 총 단어 갯수 : 47,646
max_words = len(tokenizer.index_word)
print(max_words)
## 10. texts_to_sequences : 문장을 숫자로 나열
- 빈도수 적은 단어 제외하는것 없이 모든 단어 포함해서 진행
- 그리고, 예를 들어 1번 등장하는 단어는 삭제하는 작업은 필요시 수행!!
# 문장을 숫자로 나열
x_train_seq= tokenizer.texts_to_sequences(x_train)
x_test_seq = tokenizer.texts_to_sequences(x_test)
# 문장을 숫자로 변경후 갯수 확인
# x_train.shape, x_test.shape, y_train.shape, y_test.shape : ((41259,), (10315,), (41259,), (10315,))
print(len(x_train_seq), len(x_test_seq))
print(x_train[1:3])
print(x_train_seq[1:3])
## 11. Padding Sequence
# 문장의 최대 길이 파악 : 제일 긴 문장 seq 길이는 38개로 구성됨.
max(len(l) for l in x_train_seq)
# 모든 문장을 최대 문장 Seq 길이 38에 맞춘다.
x_train_pad = pad_sequences(x_train_seq, maxlen=38)
x_test_pad = pad_sequences(x_test_seq, maxlen=38)
# 문장 Seq 내용을 보니 잘 패딩되어 있음 확인
x_train_pad[:1]
# 문장 Seq 패딩의 shape 확인
x_train_pad.shape, x_test_pad.shape
## 12. LSTM 모델링
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D
from tensorflow.keras.layers import Embedding, Bidirectional, LSTM, SimpleRNN, GRU
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
# 하이퍼 파라미터
max_words = 47646 + 1 # 총 단어 갯수 + padding 0 번호
max_len = 38 # 최대 문장 길이
embedding_dim = 32 # embedding 차원
# 모델 선언
model = Sequential()
# 단어를 의미있는 32 차원으로 Vector 변경(Embedding)
model.add(Embedding(max_words, embedding_dim, input_length=max_len))
# LSTM 모델
model.add(LSTM(16, return_sequences=True))
model.add(LSTM(16, return_sequences=True))
model.add(Flatten())
model.add(Dense(128, activation='swish'))
model.add(Dense(32, activation='swish'))
model.add(Dense(6, activation='softmax'))
# 모델 compile
model.compile(loss = 'sparse_categorical_crossentropy',
optimizer = 'adam',
metrics = ['accuracy'])
model.summary()
# 조기종료 콜백함수 정의(EarlyStopping)
es = EarlyStopping(monitor='val_loss', patience=10, verbose=1)
# 체크포인트 저장(ModelCheckpoint)
checkpoint_path = 'tmp_checkpoint.keras'
cp = ModelCheckpoint(checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True)
# 모델 학습(fit)
history = model.fit(x_train_pad, y_train, epochs=50, batch_size=512,
validation_split=0.2, verbose =1, callbacks=[es, cp])
epochs = range(1, len(history.history['accuracy']) + 1)
plt.plot(epochs, history.history['accuracy'])
plt.plot(epochs, history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'valid'], )
plt.show()
model.evaluate(x_test_pad, y_test)
### 13. 예측해 보기
print(f'문자열 : {x_test[0]}')
print(f'Sequence : {x_test_pad[0]}')
# 모델 예측하기(predict)
predict = model.predict (x_test_pad[:1])
print(f'True : {class2label[y_test[0]]}')
print(f'Predict : {class2label[np.argmax(predict)]}')
'Google > Photo' 카테고리의 다른 글
이미지 (0) | 2024.09.04 |
---|---|
구글 포토(Google Photo) 사진 다운로드하기 (부분 or 일괄) (1) | 2020.12.27 |