Test / app.py
820nam's picture
Update app.py
c42b00b verified
raw
history blame
5.62 kB
import streamlit as st
import requests
import matplotlib.pyplot as plt
from transformers import pipeline
import openai
import pandas as pd
import os
OPENAI_API_KEY="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"
# OpenAI API ํ‚ค ์„ค์ •
openai.api_key = os.getenv("OPENAI_API_KEY", "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") # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋˜๋Š” ์ง์ ‘ ํ‚ค ์ž…๋ ฅ
# ๋„ค์ด๋ฒ„ ๋‰ด์Šค API๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๋‰ด์Šค ๊ธฐ์‚ฌ ๊ฐ€์ ธ์˜ค๊ธฐ
def fetch_naver_news(query, display=5):
client_id = "I_8koTJh3R5l4wLurQbG" # ๋„ค์ด๋ฒ„ ๊ฐœ๋ฐœ์ž ์„ผํ„ฐ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ Client ID
client_secret = "W5oWYlAgur" # ๋„ค์ด๋ฒ„ ๊ฐœ๋ฐœ์ž ์„ผํ„ฐ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ Client Secret
url = "https://openapi.naver.com/v1/search/news.json"
headers = {
"X-Naver-Client-Id": client_id,
"X-Naver-Client-Secret": client_secret,
}
params = {
"query": query,
"display": display,
"start": 1,
"sort": "date", # ์ตœ์‹ ์ˆœ์œผ๋กœ ์ •๋ ฌ
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
news_data = response.json()
return news_data['items'] # ๋‰ด์Šค ๊ธฐ์‚ฌ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
else:
st.error("๋‰ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.")
return []
# ์ •์น˜ ์„ฑํ–ฅ ๋ถ„์„ ๋ชจ๋ธ ๋กœ๋“œ
def load_sentiment_model():
classifier = pipeline("text-classification", model="bucketresearch/politicalBiasBERT")
return classifier
# GPT-4๋ฅผ ์ด์šฉํ•ด ๋ฐ˜๋Œ€ ๊ด€์  ๊ธฐ์‚ฌ ์ƒ์„ฑ
def generate_article_gpt4(prompt):
try:
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a helpful assistant that generates articles."},
{"role": "user", "content": prompt}
],
max_tokens=512,
temperature=0.7
)
return response.choices[0].message.content
except Exception as e:
return f"Error generating text: {e}"
# ์ •์น˜ ์„ฑํ–ฅ ๋ถ„์„
def analyze_article_sentiment(text, classifier):
result = classifier(text[:512]) # ๋„ˆ๋ฌด ๊ธด ํ…์ŠคํŠธ๋Š” ์ž˜๋ผ์„œ ๋ถ„์„
label = result[0]["label"]
score = result[0]["score"]
# ๋ชจ๋ธ์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ผ๋ฒจ์„ "์ง„๋ณด", "๋ณด์ˆ˜", "์ค‘๋ฆฝ"์œผ๋กœ ๋งคํ•‘
if label == "LEFT":
return "์ง„๋ณด", score
elif label == "RIGHT":
return "๋ณด์ˆ˜", score
else:
return "์ค‘๋ฆฝ", score
# ์ •์น˜์  ๊ด€์  ๋น„๊ต ๋ฐ ๋ฐ˜๋Œ€ ๊ด€์  ์ƒ์„ฑ
def analyze_news_political_viewpoint(query):
# ๋‰ด์Šค ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
news_items = fetch_naver_news(query)
if not news_items:
return [], {}
classifier = load_sentiment_model()
results = []
sentiment_counts = {"์ง„๋ณด": 0, "๋ณด์ˆ˜": 0, "์ค‘๋ฆฝ": 0} # ๋งคํ•‘๋œ ๋ผ๋ฒจ์— ๋งž๊ฒŒ ์ดˆ๊ธฐํ™”
for item in news_items:
title = item["title"]
description = item["description"]
combined_text = f"{title}. {description}"
# ๊ธฐ์‚ฌ ์„ฑํ–ฅ ๋ถ„์„
sentiment, score = analyze_article_sentiment(combined_text, classifier)
sentiment_counts[sentiment] += 1 # ๋งคํ•‘๋œ ํ‚ค๋กœ ์นด์šดํŠธ ์ฆ๊ฐ€
# ๋ฐ˜๋Œ€ ๊ด€์  ๊ธฐ์‚ฌ ์ƒ์„ฑ
opposite_perspective = "๋ณด์ˆ˜์ " if sentiment == "์ง„๋ณด" else "์ง„๋ณด์ "
prompt = f"{combined_text}๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ {opposite_perspective} ๊ด€์ ์˜ ๊ธฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”."
opposite_article = generate_article_gpt4(prompt)
results.append({
"์ œ๋ชฉ": title,
"์›๋ณธ ๊ธฐ์‚ฌ": description,
"์„ฑํ–ฅ": sentiment,
"์„ฑํ–ฅ ์ ์ˆ˜": score,
"๋Œ€์กฐ ๊ด€์  ๊ธฐ์‚ฌ": opposite_article
})
return results, sentiment_counts
# ์„ฑํ–ฅ ๋ถ„ํฌ ์‹œ๊ฐํ™”
def visualize_sentiment_distribution(sentiment_counts):
fig, ax = plt.subplots()
labels = list(sentiment_counts.keys())
sizes = list(sentiment_counts.values())
ax.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=["blue", "red", "gray"])
ax.axis("equal")
st.pyplot(fig)
# Streamlit ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
st.title("์ •์น˜์  ๊ด€์  ๋น„๊ต ๋ถ„์„ ๋„๊ตฌ")
st.markdown("๋‰ด์Šค ๊ธฐ์‚ฌ์˜ ์ •์น˜ ์„ฑํ–ฅ ๋ถ„์„๊ณผ ๋ฐ˜๋Œ€ ๊ด€์  ๊ธฐ์‚ฌ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.")
query = st.text_input("๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”", value="์ •์น˜")
if st.button("๋ถ„์„ ์‹œ์ž‘"):
with st.spinner("๋ถ„์„ ์ค‘..."):
analysis_results, sentiment_counts = analyze_news_political_viewpoint(query)
if analysis_results:
st.success("๋‰ด์Šค ๋ถ„์„์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
# ์„ฑํ–ฅ ๋ถ„ํฌ ์‹œ๊ฐํ™”
st.subheader("์„ฑํ–ฅ ๋ถ„ํฌ ์‹œ๊ฐํ™”")
visualize_sentiment_distribution(sentiment_counts)
# ์ƒ์„ธ ๋ถ„์„ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
st.subheader("์ƒ์„ธ ๋ถ„์„ ๊ฒฐ๊ณผ")
for result in analysis_results:
st.write(f"#### ์ œ๋ชฉ: {result['์ œ๋ชฉ']}")
st.write(f"- **์›๋ณธ ๊ธฐ์‚ฌ**: {result['์›๋ณธ ๊ธฐ์‚ฌ']}")
st.write(f"- **์„ฑํ–ฅ**: {result['์„ฑํ–ฅ']} (์ ์ˆ˜: {result['์„ฑํ–ฅ ์ ์ˆ˜']:.2f})")
st.write(f"- **๋Œ€์กฐ ๊ด€์  ๊ธฐ์‚ฌ**: {result['๋Œ€์กฐ ๊ด€์  ๊ธฐ์‚ฌ']}")
st.write("---")
else:
st.error("๋ถ„์„๋œ ๋‰ด์Šค ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")