Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import pandas as pd
|
3 |
+
import gradio as gr
|
4 |
+
import openai
|
5 |
+
from datetime import datetime
|
6 |
+
|
7 |
+
# OpenAI API ํด๋ผ์ด์ธํธ ์ค์
|
8 |
+
openai.api_key = os.getenv("OPENAI_API_KEY")
|
9 |
+
|
10 |
+
# LLM ํธ์ถ ํจ์
|
11 |
+
def call_api(content, system_message="๋ฆฌ๋ทฐ๋ฅผ ๋ถ์ํ์ฌ ์์ฝํด ์ฃผ์ธ์.", max_tokens=200, temperature=0.7, top_p=0.9):
|
12 |
+
response = openai.ChatCompletion.create(
|
13 |
+
model="gpt-4o-mini",
|
14 |
+
messages=[
|
15 |
+
{"role": "system", "content": system_message},
|
16 |
+
{"role": "user", "content": content},
|
17 |
+
],
|
18 |
+
max_tokens=max_tokens,
|
19 |
+
temperature=temperature,
|
20 |
+
top_p=top_p,
|
21 |
+
)
|
22 |
+
return response.choices[0].message['content']
|
23 |
+
|
24 |
+
# ์์
๋ฐ์ดํฐ ์ฝ๊ธฐ ํจ์
|
25 |
+
def read_excel_data(file):
|
26 |
+
df = pd.read_excel(file, usecols="A, B, C, D, E", skiprows=1,
|
27 |
+
names=["ID", "Review Date", "Option", "Review", "ReviewScore"], engine='openpyxl')
|
28 |
+
df['Review Date'] = pd.to_datetime(df['Review Date']).dt.tz_localize(None).dt.date
|
29 |
+
df['Year'] = df['Review Date'].astype(str).str.slice(0, 4)
|
30 |
+
df['Option1'] = df['Option'].astype(str).str.split(" / ").str[0]
|
31 |
+
df['Review Length'] = df['Review'].str.len()
|
32 |
+
return df
|
33 |
+
|
34 |
+
# ๊ธ์ ์ ์ธ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐํํ๋ ํจ์
|
35 |
+
def get_positive_reviews(df):
|
36 |
+
positive_reviews = df[df['ReviewScore'] >= 4].sort_values(by='Review Length', ascending=False)
|
37 |
+
positive_reviews = positive_reviews.head(20)
|
38 |
+
positive_reviews.reset_index(drop=True, inplace=True)
|
39 |
+
positive_reviews.index += 1
|
40 |
+
positive_reviews['์๋ฒ'] = positive_reviews.index
|
41 |
+
positive_output = "\n\n".join(positive_reviews.apply(
|
42 |
+
lambda x: f"{x['์๋ฒ']}. **{x['Review Date']} / {x['ID']} / {x['Option']}**\n\n{x['Review']}", axis=1))
|
43 |
+
analysis = call_api(positive_output)
|
44 |
+
return positive_output, analysis
|
45 |
+
|
46 |
+
# ๋ถ์ ์ ์ธ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐํํ๋ ํจ์
|
47 |
+
def get_negative_reviews(df):
|
48 |
+
negative_reviews = df[df['ReviewScore'] <= 2].sort_values(by='Review Length', ascending=False)
|
49 |
+
negative_reviews = negative_reviews.head(30)
|
50 |
+
negative_reviews.reset_index(drop=True, inplace=True)
|
51 |
+
negative_reviews.index += 1
|
52 |
+
negative_reviews['์๋ฒ'] = negative_reviews.index
|
53 |
+
negative_output = "\n\n".join(negative_reviews.apply(
|
54 |
+
lambda x: f"{x['์๋ฒ']}. **{x['Review Date']} / {x['ID']} / {x['Option']}**\n\n{x['Review']}", axis=1))
|
55 |
+
analysis = call_api(negative_output)
|
56 |
+
return negative_output, analysis
|
57 |
+
|
58 |
+
# ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ์ฌ ๊ธ์ ๋ฐ ๋ถ์ ๋ฆฌ๋ทฐ๋ฅผ ์ถ์ถํ๋ ํจ์
|
59 |
+
def process_reviews(file):
|
60 |
+
df = read_excel_data(file)
|
61 |
+
positive_reviews, positive_analysis = get_positive_reviews(df)
|
62 |
+
negative_reviews, negative_analysis = get_negative_reviews(df)
|
63 |
+
return positive_reviews, positive_analysis, negative_reviews, negative_analysis
|
64 |
+
|
65 |
+
# Gradio ์ธํฐํ์ด์ค ๊ตฌ์ฑ
|
66 |
+
def create_interface():
|
67 |
+
with gr.Blocks() as demo:
|
68 |
+
gr.Markdown("### ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ ์
๋ก๋ ๋ฐ ๋ถ์")
|
69 |
+
file_input = gr.File(label="์์
ํ์ผ ์
๋ก๋", file_types=[".xlsx"])
|
70 |
+
analyze_button = gr.Button("๋ฆฌ๋ทฐ๋ถ์")
|
71 |
+
|
72 |
+
with gr.Column():
|
73 |
+
gr.Markdown("### ๊ธ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ (์ต๋ 20๊ฐ)")
|
74 |
+
positive_reviews_output = gr.Textbox(label="๊ธ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ", interactive=False, lines=20)
|
75 |
+
positive_analysis_output = gr.Textbox(label="๊ธ์ ๋ฆฌ๋ทฐ ๋ถ์ ๊ฒฐ๊ณผ", interactive=False, lines=5)
|
76 |
+
|
77 |
+
gr.Markdown("### ๋ถ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ (์ต๋ 30๊ฐ)")
|
78 |
+
negative_reviews_output = gr.Textbox(label="๋ถ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ", interactive=False, lines=30)
|
79 |
+
negative_analysis_output = gr.Textbox(label="๋ถ์ ๋ฆฌ๋ทฐ ๋ถ์ ๊ฒฐ๊ณผ", interactive=False, lines=5)
|
80 |
+
|
81 |
+
analyze_button.click(
|
82 |
+
fn=process_reviews,
|
83 |
+
inputs=[file_input],
|
84 |
+
outputs=[positive_reviews_output, positive_analysis_output, negative_reviews_output, negative_analysis_output]
|
85 |
+
)
|
86 |
+
|
87 |
+
return demo
|
88 |
+
|
89 |
+
if __name__ == "__main__":
|
90 |
+
interface = create_interface()
|
91 |
+
interface.launch()
|