143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
import gradio as gr
|
|
from transformers import pipeline
|
|
import re
|
|
import pandas as pd
|
|
import matplotlib.pyplot as plt
|
|
import koreanize_matplotlib
|
|
|
|
# 문장 여러개 ( 파일 )
|
|
# 리뷰 데이터 -> 분석
|
|
|
|
english_classifier = pipeline("sentiment-analysis", top_k = None)
|
|
korean_classifier = pipeline("sentiment-analysis", model="WhitePeak/bert-base-cased-Korean-sentiment", top_k = None)
|
|
|
|
def is_korean(text):
|
|
korean = re.search(r"[가-힣]", text)
|
|
return korean is not None
|
|
|
|
|
|
def predict_sentiment(file):
|
|
|
|
# 1. file => pandas
|
|
df = pd.read_csv(file)
|
|
reviews = df['review'].to_list()
|
|
|
|
results_text = []
|
|
# [수정] 변수 초기화 추가
|
|
positive_count, negative_count = 0, 0
|
|
positive_scores, negative_scores = 0.0, 0.0
|
|
best_positive_score, best_negative_score = 0.0, 0.0
|
|
best_positive_review, best_negative_review = "", ""
|
|
positive_length, negative_length = [], []
|
|
|
|
label_map = {"LABEL_0" : "부정 😡", "LABEL_1" : "긍정 😄", "NEGATIVE" : "부정 😡", "POSITIVE" : "긍정 😄"}
|
|
|
|
for sentence in reviews:
|
|
# 한국말인지 확인하기
|
|
if is_korean(sentence):
|
|
result = korean_classifier(sentence)[0]
|
|
else:
|
|
result = english_classifier(sentence)[0]
|
|
|
|
best = max(result, key=lambda x:x['score'])
|
|
label = best["label"]
|
|
label = label_map.get(label, label)
|
|
score = best['score']
|
|
|
|
# 가장 긍정적인 리뷰 (best_positive_review)와 확률(best_positive_score)
|
|
# 가장 부정적인 리뷰 (best_negative_review)와 확률(best_negative_score)
|
|
# 긍정 점수 평균 positive_scores
|
|
# 부정 점수 평균 negative_scores
|
|
|
|
review_length = len(sentence)
|
|
|
|
if label =="긍정 😄":
|
|
positive_count += 1
|
|
positive_scores += score
|
|
positive_length.append(review_length)
|
|
|
|
if best_positive_score < score :
|
|
best_positive_score = score
|
|
best_positive_review = sentence
|
|
else:
|
|
negative_count += 1
|
|
negative_scores += score
|
|
negative_length.append(review_length)
|
|
|
|
if best_negative_score < score :
|
|
best_negative_score = score
|
|
best_negative_review = sentence
|
|
|
|
|
|
results_text.append([sentence, label, score])
|
|
|
|
# 총 리뷰수 : 20개
|
|
total = len(reviews)
|
|
# 긍정 리뷰 : 4개
|
|
# 부정 리뷰 : 16개
|
|
|
|
# 긍정 비율 : 21.05%
|
|
positive_ration = positive_count / total * 100
|
|
# 부정 비율 : 78.95%
|
|
negative_ration = negative_count / total * 100
|
|
|
|
# 부정 긍정 점수 평균
|
|
avg_positive = positive_scores / positive_count if positive_count > 0 else 0
|
|
avg_negative = negative_scores / negative_count if negative_count > 0 else 0
|
|
|
|
# 리뷰 길이 평균
|
|
avg_positive_length = sum(positive_length) / len(positive_length) if positive_length else 0
|
|
avg_negative_length = sum(negative_length) / len(negative_length) if negative_length else 0
|
|
|
|
stats = f"""
|
|
총 리뷰 수 : {total} 개
|
|
|
|
긍정 리뷰 😄 : {positive_count} 개
|
|
부정 리뷰 😡 : {negative_count} 개
|
|
|
|
긍정 비율 😄 : {positive_ration:.2f}%
|
|
부정 비율 😡 : {negative_ration:.2f}%
|
|
|
|
가장 긍정적인 리뷰 😄 : {best_positive_review} = {positive_length}
|
|
= (긍정 확률 {best_positive_score:.4f})
|
|
가장 부정적인 리뷰 😡 : {best_negative_review} = {negative_length}
|
|
= (부정 확률 {best_negative_score:.4f})
|
|
|
|
긍정 점수 평균 😄 : {avg_positive:.2f}
|
|
부정 점수 평균 😡 : {avg_negative:.2f}
|
|
|
|
평균 긍정 리뷰 길이 😄 = {avg_positive_length:.2f}
|
|
평균 부정 리뷰 길이 😡 = {avg_negative_length:.2f}
|
|
"""
|
|
|
|
|
|
#차트
|
|
fig, ax = plt.subplots()
|
|
|
|
ax.pie(
|
|
[positive_count, negative_count],
|
|
labels=["긍정", "부정"],
|
|
autopct="%.1f%%",
|
|
startangle=90,
|
|
counterclock=False
|
|
)
|
|
|
|
return (
|
|
gr.update(value=results_text, visible=True),
|
|
gr.update(value=stats, visible=True),
|
|
gr.update(value=fig, visible=True),
|
|
)
|
|
|
|
with gr.Blocks() as demo :
|
|
gr.Markdown("HuggingFace Transformer 기반 감정 분석 프로그램")
|
|
|
|
inp = gr.File()
|
|
btn = gr.Button("감정분석")
|
|
|
|
df = gr.Dataframe(headers=["문장", "감정", "확률"], visible=False)
|
|
stats = gr.Textbox(label="분석 결과", visible=False)
|
|
chart_box = gr.Plot(label="감정 비율", visible=False)
|
|
btn.click(fn=predict_sentiment, inputs = inp, outputs = [df, stats, chart_box])
|
|
|
|
|
|
demo.launch() |