File size: 4,333 Bytes
384f5e4
bfd4ab7
ebf358a
384f5e4
ebf358a
384f5e4
717fe8c
ebf358a
 
717fe8c
ebf358a
 
 
 
bfd4ab7
ebf358a
 
717fe8c
ebf358a
717fe8c
ebf358a
 
 
 
 
 
d10e98d
ebf358a
 
 
 
 
 
 
d10e98d
ebf358a
 
 
 
 
 
 
 
 
 
 
 
bfd4ab7
 
 
717fe8c
ebf358a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384f5e4
ebf358a
 
 
 
384f5e4
bfd4ab7
ebf358a
bfd4ab7
ebf358a
 
 
 
 
 
 
 
 
95eccad
ebf358a
 
 
384f5e4
 
 
ebf358a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import streamlit as st
import requests
import openai
from transformers import pipeline
import matplotlib.pyplot as plt
import pandas as pd

# OpenAI API ํ‚ค ์„ค์ •
openai.api_key = "YOUR_OPENAI_API_KEY"

# Step 1: ๋„ค์ด๋ฒ„ ๋‰ด์Šค ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
def fetch_news(query, display=5):
    client_id = "YOUR_NAVER_CLIENT_ID"
    client_secret = "YOUR_NAVER_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)
    return response.json()["items"] if response.status_code == 200 else []

# Step 2: ์ •์น˜ ์„ฑํ–ฅ ๋ถ„์„ ๋ชจ๋ธ ๋กœ๋“œ
def load_sentiment_model():
    return pipeline("text-classification", model="bucketresearch/politicalBiasBERT")

# Step 3: GPT-4๋ฅผ ์‚ฌ์šฉํ•ด ๋Œ€์กฐ ๊ด€์  ๊ธฐ์‚ฌ ์ƒ์„ฑ
def generate_article_gpt4(prompt):
    try:
        response = openai.ChatCompletion.create(
            model="gpt-4",
            messages=[{"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}"

# Step 4: ๋‰ด์Šค ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ฐ ๊ฒฐ๊ณผ ์ƒ์„ฑ
def analyze_news_political_viewpoint(query, sentiment_model):
    news_data = fetch_news(query)
    if not news_data:
        return "๋‰ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.", None, None

    results = []
    sentiment_counts = {"์ง„๋ณด": 0, "๋ณด์ˆ˜": 0}

    for item in news_data:
        title = item["title"]
        description = item["description"]
        combined_text = f"{title}. {description}"

        # ์„ฑํ–ฅ ๋ถ„์„
        sentiment = sentiment_model(combined_text[:512])[0]
        sentiment_label = sentiment["label"]
        sentiment_score = sentiment["score"]

        # ์ง„๋ณด์ /๋ณด์ˆ˜์  ๊ด€์  ๋ฐ˜๋Œ€๋กœ ๊ธฐ์‚ฌ ์ƒ์„ฑ
        if sentiment_label == "์ง„๋ณด":
            prompt = f"๋‹ค์Œ ๊ธฐ์‚ฌ๋ฅผ ๋ณด์ˆ˜์  ๊ด€์ ์—์„œ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”:\n{combined_text}"
        elif sentiment_label == "๋ณด์ˆ˜":
            prompt = f"๋‹ค์Œ ๊ธฐ์‚ฌ๋ฅผ ์ง„๋ณด์  ๊ด€์ ์—์„œ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”:\n{combined_text}"
        else:
            continue  # ์ค‘๋ฆฝ ๊ธฐ์‚ฌ๋Š” ์ œ์™ธ

        generated_article = generate_article_gpt4(prompt)
        sentiment_counts[sentiment_label] += 1

        # ๊ฒฐ๊ณผ ์ €์žฅ
        results.append({
            "์ œ๋ชฉ": title,
            "์›๋ณธ ๊ธฐ์‚ฌ": description,
            "์„ฑํ–ฅ": sentiment_label,
            "์„ฑํ–ฅ ์ ์ˆ˜": sentiment_score,
            "๋Œ€์กฐ ๊ด€์  ๊ธฐ์‚ฌ": generated_article,
        })

    return "๋‰ด์Šค ๋ถ„์„์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", results, sentiment_counts

# Step 5: ์‹œ๊ฐํ™” ํ•จ์ˆ˜
def visualize_sentiment_distribution(sentiment_counts):
    labels = list(sentiment_counts.keys())
    values = list(sentiment_counts.values())
    fig, ax = plt.subplots()
    ax.bar(labels, values, color=['blue', 'red'])
    ax.set_title("์ง„๋ณด vs ๋ณด์ˆ˜ ๊ธฐ์‚ฌ ์ˆ˜")
    ax.set_ylabel("๊ธฐ์‚ฌ ์ˆ˜")
    st.pyplot(fig)

# Step 6: Streamlit UI
st.title("์ •์น˜์  ๊ด€์  ๋น„๊ต ๋ถ„์„ ๋„๊ตฌ")
st.markdown("### ๋‰ด์Šค ๊ธฐ์‚ฌ์˜ ์ •์น˜ ์„ฑํ–ฅ ๋ถ„์„๊ณผ ๋ฐ˜๋Œ€ ๊ด€์  ๊ธฐ์‚ฌ ์ƒ์„ฑ")

query = st.text_input("๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”", value="์ •์น˜")
if st.button("๋ถ„์„ ์‹œ์ž‘"):
    with st.spinner("๋ถ„์„ ์ค‘์ž…๋‹ˆ๋‹ค..."):
        sentiment_model = load_sentiment_model()
        status_message, analysis_results, sentiment_counts = analyze_news_political_viewpoint(query, sentiment_model)

        # ๊ฒฐ๊ณผ ์ถœ๋ ฅ
        st.subheader(status_message)
        if analysis_results:
            st.write("### ์„ฑํ–ฅ ๋ถ„ํฌ ์‹œ๊ฐํ™”")
            visualize_sentiment_distribution(sentiment_counts)

            st.write("### ๋ถ„์„ ๊ฒฐ๊ณผ")
            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("---")