| import os |
| import pandas as pd |
| import gradio as gr |
| from datetime import datetime |
| import openai |
|
|
| |
| openai.api_key = os.getenv("OPENAI_API_KEY") |
|
|
| def call_api(content, system_message, max_tokens=1024, temperature=0.7, top_p=1): |
| response = openai.ChatCompletion.create( |
| model="gpt-4o-mini", |
| messages=[ |
| {"role": "system", "content": system_message}, |
| {"role": "user", "content": content}, |
| ], |
| max_tokens=max_tokens, |
| temperature=temperature, |
| top_p=top_p, |
| ) |
| return response.choices[0].message['content'] |
|
|
| |
| def read_excel_data(file): |
| df = pd.read_excel(file, usecols="A, B, C, D, E", skiprows=1, |
| names=["ID", "Review Date", "Option", "Review", "ReviewScore"], engine='openpyxl') |
| df['Review Date'] = pd.to_datetime(df['Review Date']).dt.tz_localize(None).dt.date |
| df['Year'] = df['Review Date'].astype(str).str.slice(0, 4) |
| df['Option1'] = df['Option'].astype(str).str.split(" / ").str[0] |
| df['Review Length'] = df['Review'].str.len() |
| return df |
|
|
| |
| def get_positive_reviews(df): |
| positive_reviews = df[df['ReviewScore'] >= 4].sort_values(by='Review Length', ascending=False).head(20) |
| positive_reviews.reset_index(drop=True, inplace=True) |
| positive_reviews.index += 1 |
| positive_reviews['์๋ฒ'] = positive_reviews.index |
|
|
| positive_output = "\n\n".join(positive_reviews.apply( |
| lambda x: f"{x['์๋ฒ']}. **{x['Review Date']} / {x['ID']} / {x['Option']}**\n\n{x['Review']}", axis=1)) |
| return positive_output |
|
|
| |
| def get_negative_reviews(df): |
| negative_reviews = df[df['ReviewScore'] <= 2].sort_values(by='Review Length', ascending=False).head(30) |
| negative_reviews.reset_index(drop=True, inplace=True) |
| negative_reviews.index += 1 |
| negative_reviews['์๋ฒ'] = negative_reviews.index |
|
|
| negative_output = "\n\n".join(negative_reviews.apply( |
| lambda x: f"{x['์๋ฒ']}. **{x['Review Date']} / {x['ID']} / {x['Option']}**\n\n{x['Review']}", axis=1)) |
| return negative_output |
|
|
| |
| def analyze_reviews_with_llm(reviews, review_type): |
| if not reviews: |
| return "๋ฆฌ๋ทฐ๊ฐ ์์ต๋๋ค." |
|
|
| system_message = f"๋น์ ์ ๊ฐ์ ๋ถ์ ์ ๋ฌธ๊ฐ์
๋๋ค. ๋ค์์ {review_type} ๋ฆฌ๋ทฐ์
๋๋ค. ๋ฆฌ๋ทฐ ์ ์ฒด๋ฅผ ๋ถ์ํ ๊ฒฐ๊ณผ๋ฅผ ์์ฝํด์ฃผ์ธ์." |
| content = reviews |
|
|
| analysis_result = call_api(content, system_message) |
| return analysis_result |
|
|
| |
| def process_reviews(file): |
| df = read_excel_data(file) |
| positive_reviews = get_positive_reviews(df) |
| negative_reviews = get_negative_reviews(df) |
|
|
| positive_analysis = analyze_reviews_with_llm(positive_reviews, "๊ธ์ ") |
| negative_analysis = analyze_reviews_with_llm(negative_reviews, "๋ถ์ ") |
|
|
| return positive_reviews, positive_analysis, negative_reviews, negative_analysis |
|
|
| |
| def create_interface(): |
| with gr.Blocks() as demo: |
| gr.Markdown("### ๋ฆฌ๋ทฐ ๋ฐ์ดํฐ ์
๋ก๋ ๋ฐ ๋ถ์") |
| file_input = gr.File(label="์์
ํ์ผ ์
๋ก๋", file_types=[".xlsx"]) |
| analyze_button = gr.Button("๋ฆฌ๋ทฐ๋ถ์") |
|
|
| with gr.Column(): |
| gr.Markdown("### ๊ธ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ (์ต๋ 20๊ฐ)") |
| positive_reviews_output = gr.Textbox(label="๊ธ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ", interactive=False, lines=20) |
| positive_analysis_output = gr.Textbox(label="๊ธ์ ๋ฆฌ๋ทฐ ๋ถ์ ๊ฒฐ๊ณผ", interactive=False, lines=10) |
|
|
| gr.Markdown("### ๋ถ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ (์ต๋ 30๊ฐ)") |
| negative_reviews_output = gr.Textbox(label="๋ถ์ ์ ์ธ ์ฃผ์ ๋ฆฌ๋ทฐ", interactive=False, lines=30) |
| negative_analysis_output = gr.Textbox(label="๋ถ์ ๋ฆฌ๋ทฐ ๋ถ์ ๊ฒฐ๊ณผ", interactive=False, lines=10) |
|
|
| analyze_button.click( |
| fn=process_reviews, |
| inputs=[file_input], |
| outputs=[positive_reviews_output, positive_analysis_output, negative_reviews_output, negative_analysis_output] |
| ) |
|
|
| return demo |
|
|
| if __name__ == "__main__": |
| interface = create_interface() |
| interface.launch() |
|
|