2022년 10월 14일 금요일

KoBERT를 이용한 감성분석

1. 준비 사항

 - 고객센터로 걸려오는 전화<음성>이 STT를 통해 텍스트로 저장되어야 한다.
 - 카카오 톡이나 게시판을 통해서 들어온 텍스트가 필요


2. 감성 분석 Flow

  - 한글을 음절 단위로 자르기 위한 말뭉치
  - 한글 말뭉치를 어휘 단위로 잘라서 vocab 파일 생성

  - 라벨링<문장이 긍정, 부정, 중립>된 정답 데이터
     ==>  이게 제일 구하기 어려움. 각 산업에 맞는 데이터로 해야함.

   - 학습한 후 모델은 .h5 형태로 저장하고 예측 실행시 .h5를 불러온다.
     (학습 -> 모델 생성 과  모델 로딩 -> 예측 이렇게 분리해야 됨)




kobert pretrained model을 이용한 감성분석

  • 평가 데이터 수: train(53건), test(23건)
  • 모델 평가:





* 예측 



3. 어려운 점

   * STT로 들어온 텍스트가 잘 맞지 않음. 주소에서 숫자를 부르면 2 인지 "이"인지 잘 구분이 안됨

   * 음성의 품질이 좋지 않음. 



4. 테스트 코드 <일부>  # ============================================================================= # 모델 평가 # =============================================================================

# 훈련 모델의 예측 성능을 F1 SCORE로 체크하기 위한 작업
def predict_convert_data(data_df):
global tokenizer
tokens, masks, segments = [], [], []
for i in tqdm(range(len(data_df))):

token = tokenizer.encode(data_df[DATA_COLUMN][i], max_length=SEQ_LEN, pad_to_max_length=True)
num_zeros = token.count(0)
mask = [1]*(SEQ_LEN-num_zeros) + [0]*num_zeros
segment = [0]*SEQ_LEN

tokens.append(token)
segments.append(segment)
masks.append(mask)

tokens = np.array(tokens)
masks = np.array(masks)
segments = np.array(segments)
return [tokens, masks, segments]

# 위에 정의한 convert_data 함수를 불러오는 함수를 정의
def predict_load_data(pandas_dataframe):
data_df = pandas_dataframe
data_df[DATA_COLUMN] = data_df[DATA_COLUMN].astype(str)
data_x = predict_convert_data(data_df)
return data_x

# test 데이터 예측하기
test_set = predict_load_data(test)
test_set

preds = sentiment_model.predict(test_set)
preds


# F1 SCORE를 바탕으로 성능 측정
from sklearn.metrics import classification_report
y_true = test['label']
# F1 Score 확인
print(classification_report(y_true, np.round(preds,0)))

import logging
tf.get_logger().setLevel(logging.ERROR)


def sentence_convert_data(data):
global tokenizer
tokens, masks, segments = [], [], []
token = tokenizer.encode(data, max_length=SEQ_LEN, pad_to_max_length=True)
num_zeros = token.count(0)
mask = [1]*(SEQ_LEN-num_zeros) + [0]*num_zeros
segment = [0]*SEQ_LEN

tokens.append(token)
segments.append(segment)
masks.append(mask)

tokens = np.array(tokens)
masks = np.array(masks)
segments = np.array(segments)
return [tokens, masks, segments]

def text_evaluation_predict(sentence):
data_x = sentence_convert_data(sentence)
predict = sentiment_model.predict(data_x)
predict_value = np.ravel(predict)
predict_answer = np.round(predict_value,0).item()
if predict_answer == 0:
print("(부정 확률 : %.3f) 부정적인 텍스트입니다." % (1-predict_value))
elif predict_answer == 1:
print("(긍정 확률 : %.3f) 긍정적인 텍스트입니다." % predict_value)


text_evaluation_predict("그 발급 받을 수 있을까요")
#(긍정 확률 : 0.540) 긍정적인 텍스트입니다.

text_evaluation_predict("감사합니다")
#(긍정 확률 : 0.539) 긍정적인 텍스트입니다.

라벨: ,