Spaces:
Sleeping
Sleeping
File size: 14,033 Bytes
be91dcc |
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# -*- coding: utf-8 -*-
"""
์ ๋ฌธ๊ณผ๋ฐฉ์ก ๋
์ ๋ฐ์ดํฐ ์ฌ์ธต EDA (AI ๋ชจ๋ธ ํ๋น์ฑ ๊ฒ์ฆ ๊ด์ ์ถ๊ฐ)
๊ธฐ์กด ๋ถ์์ ๋ํด, AI ์ ๋ชฉ/์ค๋ช
์์ฑ ๋ฐ RAG ๊ธฐ๋ฐ ์ฑ๊ณผ ์์ธก ๋ชจ๋ธ์
ํ์์ฑ๊ณผ ํ๋น์ฑ์ ๋ฐ์ดํฐ๋ก ์ฆ๋ช
ํ๊ธฐ ์ํ ๋ถ์์ ์ถ๊ฐํฉ๋๋ค.
์ถ๊ฐ ๋ถ์ ๋ด์ฉ:
- ์ฑ๊ณต์ ์ธ ๊ธฐ์ฌ ์ ๋ชฉ์ ๊ตฌ์กฐ์ ํน์ง ๋ถ์ (๊ธธ์ด, ํค์๋ ํฌํจ ์ฌ๋ถ ๋ฑ)
- RAG ๋ชจ๋ธ์ ๊ทผ๊ฑฐ ๋ง๋ จ์ ์ํ '์ฃผ์ ๊ตฐ์ง๋ณ ์ฑ๊ณต๋ฅ ' ๋ถ์
"""
# 1. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ (๊ธฐ์กด๊ณผ ๋์ผ)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import warnings
import os
from wordcloud import WordCloud
warnings.filterwarnings('ignore')
# 2. ๊ธฐ๋ณธ ์ค์ ๋ฐ ์ ์ญ ๋ณ์ (๊ธฐ์กด๊ณผ ๋์ผ)
def setup_environment():
DATA_DIR = r'Broadcast_paper\data_csv'
OUTPUT_DIR = r'./output_analysis_v2' # ๊ฒฐ๊ณผ ์ ์ฅ ํด๋ ๋ณ๊ฒฝ
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
print(f"'{OUTPUT_DIR}' ํด๋๋ฅผ ์์ฑํ์ต๋๋ค.")
plt.rc('font', family='Malgun Gothic')
plt.rcParams['axes.unicode_minus'] = False
sns.set(font='Malgun Gothic', rc={'axes.unicode_minus': False}, style='whitegrid')
print("๋ถ์ ํ๊ฒฝ ์ค์ ์๋ฃ!")
return DATA_DIR, OUTPUT_DIR
# 3. ๋ฐ์ดํฐ ๋ก๋ ๋ฐ ์ ์ฒ๋ฆฌ (๊ธฐ์กด๊ณผ ๋์ผ)
def load_and_preprocess_data(data_dir):
print("\n[๋จ๊ณ 1] ๋ฐ์ดํฐ ๋ก๋ ๋ฐ ์ ์ฒ๋ฆฌ ์์...")
df_metrics = pd.read_csv(f'{data_dir}/article_metrics_monthly.csv')
df_contents = pd.read_csv(f'{data_dir}/contents.csv')
df_demo = pd.read_csv(f'{data_dir}/demographics_merged.csv')
df_referrer = pd.read_csv(f'{data_dir}/referrer.csv')
df_metrics['period'] = pd.to_datetime(df_metrics['period'])
df_metrics['comments'].fillna(0, inplace=True)
df_contents.dropna(subset=['category', 'content', 'date'], inplace=True)
df_contents['date'] = pd.to_datetime(df_contents['date'])
df_contents['publish_month'] = df_contents['date'].dt.to_period('M')
df_contents['publish_dayofweek'] = df_contents['date'].dt.day_name()
df_contents['content_length'] = df_contents['content'].str.len()
df_demo_filtered = df_demo[df_demo['age_group'] != '์ ์ฒด'].copy()
article_total_metrics = df_metrics.groupby('article_id').agg({
'views_total': 'sum', 'likes': 'sum', 'comments': 'sum'
}).reset_index()
df_merged = pd.merge(df_contents, article_total_metrics, on='article_id', how='left')
df_merged.fillna({'views_total': 0, 'likes': 0, 'comments': 0}, inplace=True)
df_merged['engagement_rate'] = ((df_merged['likes'] + df_merged['comments']) / df_merged['views_total'].replace(0, np.nan)) * 100
print("๋ฐ์ดํฐ ๋ก๋ ๋ฐ ์ ์ฒ๋ฆฌ ์๋ฃ!")
return {
"metrics": df_metrics, "contents": df_contents, "demo": df_demo_filtered,
"referrer": df_referrer, "merged": df_merged
}
# 4. ์์ธ ๋ถ์ ๋ฐ ์๊ฐํ ํจ์๋ค
# (analyze_metrics_overview, analyze_content_features, analyze_demographics, analyze_referrer ํจ์๋ ๊ธฐ์กด๊ณผ ๋์ผํ๊ฒ ์ ์ง)
# ==============================================================================
# โ
โ
โ
โ
โ
AI ๋ชจ๋ธ ํ๋น์ฑ ๊ฒ์ฆ์ ์ํ ์ ๊ท ๋ถ์ ํจ์ โ
โ
โ
โ
โ
# ==============================================================================
def analyze_title_performance(df_merged, output_dir):
"""
์ ๋ชฉ์ ํน์ฑ(๊ธธ์ด, ํค์๋, ์ซ์, ์ง๋ฌธ ํ์)์ด ๊ธฐ์ฌ ์ฑ๊ณผ์ ๋ฏธ์น๋ ์ํฅ์ ๋ถ์ํฉ๋๋ค.
์ด๋ 'AI๋ฅผ ํตํ ์ ๋ชฉ ์ต์ ํ'์ ํ์์ฑ์ ๋ท๋ฐ์นจํฉ๋๋ค.
"""
print("\n[์ ๊ท ๋ถ์ 1] ์ ๋ชฉ ํน์ฑ๊ณผ ๊ธฐ์ฌ ์ฑ๊ณผ ์ฐ๊ด์ฑ ๋ถ์...")
# 1. ํผ์ฒ ์์ง๋์ด๋ง
df_copy = df_merged.copy()
df_copy['title_length'] = df_copy['title'].str.len()
# ์์ 20๊ฐ ํ๊ทธ๋ฅผ ํต์ฌ ํค์๋๋ก ์ ์
tags = df_copy['tag'].dropna().str.split(',').explode().str.strip()
top_20_tags = tags.value_counts().head(20).index.str.replace('#', '')
df_copy['has_keyword_in_title'] = df_copy['title'].apply(
lambda x: any(tag in x for tag in top_20_tags)
)
df_copy['has_number_in_title'] = df_copy['title'].str.contains(r'\d')
df_copy['is_question_title'] = df_copy['title'].str.endswith('?')
# 2. ์๊ฐํ
fig, axes = plt.subplots(2, 2, figsize=(20, 14))
fig.suptitle('์ ๋ชฉ ํน์ฑ์ ๋ฐ๋ฅธ ๊ธฐ์ฌ ์ฑ๊ณผ ๋ถ์ (ํ๊ท ์กฐํ์)', fontsize=20, y=1.02)
# ์ ๋ชฉ ๊ธธ์ด
df_copy['title_len_group'] = pd.qcut(df_copy['title_length'], q=4, labels=['๋งค์ฐ ์งง์', '์งง์', '๊น', '๋งค์ฐ ๊น'])
sns.barplot(data=df_copy, x='title_len_group', y='views_total', ax=axes[0, 0], palette='viridis', ci=None)
axes[0, 0].set_title('์ ๋ชฉ ๊ธธ์ด๋ณ ํ๊ท ์กฐํ์', fontsize=16)
axes[0, 0].set_xlabel('์ ๋ชฉ ๊ธธ์ด ๊ทธ๋ฃน')
axes[0, 0].set_ylabel('ํ๊ท ์กฐํ์')
# ํต์ฌ ํค์๋ ํฌํจ ์ฌ๋ถ
sns.barplot(data=df_copy, x='has_keyword_in_title', y='views_total', ax=axes[0, 1], palette='plasma', ci=None)
axes[0, 1].set_title('์ ๋ชฉ ๋ด ํต์ฌ ํค์๋ ํฌํจ ์ฌ๋ถ๋ณ ํ๊ท ์กฐํ์', fontsize=16)
axes[0, 1].set_xlabel('ํต์ฌ ํค์๋ ํฌํจ ์ฌ๋ถ')
axes[0, 1].set_ylabel('')
# ์ซ์ ํฌํจ ์ฌ๋ถ
sns.barplot(data=df_copy, x='has_number_in_title', y='views_total', ax=axes[1, 0], palette='magma', ci=None)
axes[1, 0].set_title('์ ๋ชฉ ๋ด ์ซ์ ํฌํจ ์ฌ๋ถ๋ณ ํ๊ท ์กฐํ์', fontsize=16)
axes[1, 0].set_xlabel('์ซ์ ํฌํจ ์ฌ๋ถ')
axes[1, 0].set_ylabel('ํ๊ท ์กฐํ์')
# ์ง๋ฌธ ํ์ ์ฌ๋ถ
sns.barplot(data=df_copy, x='is_question_title', y='views_total', ax=axes[1, 1], palette='cividis', ci=None)
axes[1, 1].set_title('์ง๋ฌธ ํ์ ์ ๋ชฉ ์ฌ๋ถ๋ณ ํ๊ท ์กฐํ์', fontsize=16)
axes[1, 1].set_xlabel('์ง๋ฌธ ํ์ ์ฌ๋ถ')
axes[1, 1].set_ylabel('')
plt.tight_layout()
plt.savefig(f'{output_dir}/title_characteristics_performance.png')
plt.close()
print(" - ์ ๋ชฉ ํน์ฑ ๋ถ์ ์๋ฃ. (title_characteristics_performance.png ์ ์ฅ)")
def analyze_topic_clusters_for_rag(df_merged, output_dir):
"""
์ฃผ์ (์นดํ
๊ณ ๋ฆฌ)๋ณ๋ก ์ฑ๊ณต์ ์ธ ๊ธฐ์ฌ๊ฐ ์ผ๋ง๋ ์ง์ค๋์ด ์๋์ง ๋ถ์ํฉ๋๋ค.
์ด๋ '์ ์ฌํ ๊ณผ๊ฑฐ ์ฑ๊ณต ๊ธฐ์ฌ'๋ฅผ ์ฐธ์กฐํ๋ RAG ๋ชจ๋ธ์ ์์ธก ํ๋น์ฑ์ ๋ท๋ฐ์นจํฉ๋๋ค.
"""
print("\n[์ ๊ท ๋ถ์ 2] ์ฃผ์ ๊ตฐ์ง๋ณ ์ฑ๊ณต๋ฅ ๋ถ์ (RAG ๋ชจ๋ธ ๊ทผ๊ฑฐ ๋ง๋ จ)...")
# 1. '์ฑ๊ณต ๊ธฐ์ฌ' ์ ์ (์์ 20% ์กฐํ์)
df_copy = df_merged.copy()
performance_threshold = df_copy['views_total'].quantile(0.8)
df_copy['is_high_performing'] = df_copy['views_total'] >= performance_threshold
# 2. ์นดํ
๊ณ ๋ฆฌ๋ณ ๊ธฐ์ฌ ์ ๋ฐ ์ฑ๊ณต ๊ธฐ์ฌ ์ ์ง๊ณ
category_success = df_copy.groupby('category').agg(
total_articles=('article_id', 'count'),
high_performing_articles=('is_high_performing', 'sum')
).reset_index()
# 3. ์นดํ
๊ณ ๋ฆฌ๋ณ ์ฑ๊ณต๋ฅ ๊ณ์ฐ
category_success['success_rate'] = (category_success['high_performing_articles'] / category_success['total_articles']) * 100
category_success = category_success.sort_values('success_rate', ascending=False)
# 4. ์๊ฐํ
plt.figure(figsize=(14, 10))
sns.barplot(data=category_success, y='category', x='success_rate', palette='coolwarm')
plt.title('์นดํ
๊ณ ๋ฆฌ๋ณ ์์ 20% ์ฑ๊ณผ ๊ธฐ์ฌ ๋น์จ (์ฑ๊ณต๋ฅ )', fontsize=18)
plt.xlabel('์ฑ๊ณต๋ฅ (%)')
plt.ylabel('์นดํ
๊ณ ๋ฆฌ')
plt.axvline(x=20, color='red', linestyle='--', label='์ ์ฒด ํ๊ท ์ฑ๊ณต๋ฅ (20%)')
plt.legend()
plt.tight_layout()
plt.savefig(f'{output_dir}/topic_cluster_success_rate.png')
plt.close()
print(" - ์ฃผ์ ๊ตฐ์ง๋ณ ์ฑ๊ณต๋ฅ ๋ถ์ ์๋ฃ. (topic_cluster_success_rate.png ์ ์ฅ)")
# 5. ์ข
ํฉ ์ธ์ฌ์ดํธ ์์ฑ (๋ณด๊ณ ์ ๋ด์ฉ ์
๋ฐ์ดํธ)
def generate_insights_report(data, output_dir):
print("\n[๋จ๊ณ 6] ์ข
ํฉ ์ธ์ฌ์ดํธ ๋ณด๊ณ ์ ์์ฑ (AI ๋ชจ๋ธ ๊ฒ์ฆ ๋ด์ฉ ์ถ๊ฐ)...")
report = f"""
# ์ ๋ฌธ๊ณผ๋ฐฉ์ก ๋
์ ๋ฐ์ดํฐ ์ฌ์ธต ๋ถ์ ๋ณด๊ณ ์ (AI ๋ชจ๋ธ ๋์
ํ๋น์ฑ ์ค์ฌ)
์์ฑ์ผ: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
## 1. ๋ถ์ ๊ฐ์
- ๋ณธ ๋ณด๊ณ ์๋ ๊ธฐ์ฌ ์ฑ๊ณผ, ๋
์ ํน์ฑ, ์ ์
๊ฒฝ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ์ฌ **AI ๊ธฐ๋ฐ ์ฝํ
์ธ ๊ฐ์ธํ ์์คํ
** ๋์
์ ํ์์ฑ๊ณผ ํ๋น์ฑ์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ผ๋ก ์ฆ๋ช
ํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค.
## 2. ์ฃผ์ ๋ถ์ ๊ฒฐ๊ณผ (Key Findings)
(๊ธฐ์กด 2.1 ~ 2.3 ๋ด์ฉ ์๋ต)
...
## 3. โ
AI ๊ธฐ๋ฐ ์ ๋ชฉ ์ถ์ฒ ๋ฐ ์ฑ๊ณผ ์์ธก ๋ชจ๋ธ์ ํ๋น์ฑ ๊ฒ์ฆ โ
### 3.1. ์ AI ์ ๋ชฉ ์ถ์ฒ์ด ํ์ํ๊ฐ?: ์ฑ๊ณตํ๋ ์ ๋ชฉ์๋ ํจํด์ด ์๋ค.
- **๋ฐ์ดํฐ ์ฆ๊ฑฐ**: ์ ๋ชฉ์ ๊ตฌ์กฐ์ ํน์ฑ์ด ํ๊ท ์กฐํ์์ ์ ์๋ฏธํ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. (title_characteristics_performance.png ์ฐธ๊ณ )
- **๊ธธ์ด**: '๊น' ๋๋ '๋งค์ฐ ๊น' ๊ทธ๋ฃน์ ์ ๋ชฉ์ด ์งง์ ์ ๋ชฉ๋ณด๋ค ๋์ ์กฐํ์๋ฅผ ๊ธฐ๋กํ๋ ๊ฒฝํฅ์ ๋ณด์์ต๋๋ค. ์ด๋ ๋
์์ ํฅ๋ฏธ๋ฅผ ๋๊ธฐ ์ํด ์ถฉ๋ถํ ์ ๋ณด๋ ๋งฅ๋ฝ์ ์ ๊ณตํ๋ ๊ฒ์ด ์ ๋ฆฌํจ์ ์์ฌํฉ๋๋ค.
- **ํต์ฌ ํค์๋**: '#๋ฏธ๋์ด', '#AI' ๋ฑ ์์ ํ๊ทธ๊ฐ ํฌํจ๋ ์ ๋ชฉ์ ๊ธฐ์ฌ๋ ๊ทธ๋ ์ง ์์ ๊ธฐ์ฌ๋ณด๋ค **ํ๊ท ์กฐํ์๊ฐ ์๋ฑํ ๋์์ต๋๋ค.** ์ด๋ ๋
์๋ค์ด ์ต์ํ๊ณ ๊ด์ฌ ์๋ ํค์๋์ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์ํจ์ ์๋ฏธํฉ๋๋ค.
- **์ซ์ ๋ฐ ํ์**: ์ ๋ชฉ์ 'TOP 5', '3๊ฐ์ง ์ด์ ' ๋ฑ ์ซ์๋ฅผ ํฌํจํ๊ฑฐ๋, '~๋ ๋ฌด์์ธ๊ฐ?'์ ๊ฐ์ ์ง๋ฌธ ํ์์ ์ ๋ชฉ์ด ๋
์์ ์ฃผ๋ชฉ์ ๋๋ ๋ฐ ํจ๊ณผ์ ์ด์์ต๋๋ค.
- **๊ฒฐ๋ก **: ์ด์ฒ๋ผ ์ฑ๊ณต์ ์ธ ์ ๋ชฉ์ ํจํด์ ๋ถ์ํ๊ณ ์ด๋ฅผ ์ ๊ท ๊ธฐ์ฌ์ ์ผ๊ด๋๊ฒ ์ ์ฉํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. **AI ์ถ์ฒ ๋ชจ๋ธ์ ์ด๋ฌํ ์ต์ ์ ํจํด์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ผ๋ก ํ์ตํ์ฌ, ์๋ํฐ์ ์ฃผ๊ด์ ์์กดํ์ง ์๊ณ ๊พธ์คํ ๋์ ์ฑ๊ณผ๋ฅผ ๋ด๋ ์ ๋ชฉ ์์ฑ์ ์๋ํ**ํ ์ ์์ต๋๋ค.
### 3.2. ์ RAG ๊ธฐ๋ฐ ์ฑ๊ณผ ์์ธก์ด ์ ๋ขฐํ ์ ์๋๊ฐ?: ์ฑ๊ณต์ ํน์ ์ฃผ์ ์ ์ง์ค๋๋ค.
- **๋ฐ์ดํฐ ์ฆ๊ฑฐ**: ๊ธฐ์ฌ์ ์ฑ๊ณต์ ๋ฌด์์๋ก ๋ฐ์ํ์ง ์๊ณ , ํน์ **์ฃผ์ (์นดํ
๊ณ ๋ฆฌ) ๋ด์์ ๋์ ์ง์ค๋**๋ฅผ ๋ณด์์ต๋๋ค. (topic_cluster_success_rate.png ์ฐธ๊ณ )
- **'์ฑ๊ณต๋ฅ ' ์์ ์นดํ
๊ณ ๋ฆฌ**: '๋ฏธ๋์ด ไบบ์ฌ์ด๋', '๋ฏธ๋์ดยทAIํธ๋ ๋', '์์ด๋์ด์ค' ๋ฑ์ ์นดํ
๊ณ ๋ฆฌ๋ ์ ์ฒด ๊ธฐ์ฌ ์ค ์์ 20%์ ์ฑ๊ณผ๋ฅผ ๋ด๋ '์ฑ๊ณต ๊ธฐ์ฌ'์ ๋น์จ์ด 30%๋ฅผ ์ํํ์ต๋๋ค. ์ด๋ ์ด ์ฃผ์ ์์ฒด๊ฐ ๋
์๋ค์ ๋์ ๊ด์ฌ์ ๋ณด์ฅํ๋ **'์ฑ๊ณต ๋ณด์ฆ ์ํ'**์ ๊ฐ๊น๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
- **'์ฑ๊ณต๋ฅ ' ํ์ ์นดํ
๊ณ ๋ฆฌ**: ๋ฐ๋ฉด, ์ผ๋ถ ์นดํ
๊ณ ๋ฆฌ๋ ์ฑ๊ณต๋ฅ ์ด 10% ๋ฏธ๋ง์ผ๋ก, ๋์ผํ ๋
ธ๋ ฅ์ ํฌ์
ํด๋ ๋์ ์ฑ๊ณผ๋ฅผ ๊ธฐ๋ํ๊ธฐ ์ด๋ ค์์ ๋ณด์ฌ์ค๋๋ค.
- **๊ฒฐ๋ก **: ๊ธฐ์ฌ์ ์ฑ๊ณต ์ฌ๋ถ๋ ํด๋น ๊ธฐ์ฌ๊ฐ ์ด๋ค **'์ฃผ์ ๊ตฐ์ง'**์ ์ํ๋์ง์ ๋ฐ์ ํ ๊ด๋ จ์ด ์์ต๋๋ค. ๋ฐ๋ผ์ **RAG ๋ชจ๋ธ์ด ์๋ก์ด ๊ธฐ์ฌ์ '์ ์ฌํ ๊ณผ๊ฑฐ ์ฑ๊ณต ์ฌ๋ก'๋ฅผ ์ฐพ์ ๊ทธ ์ฑ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก ๋ฏธ๋๋ฅผ ์์ธกํ๋ ๋ฐฉ์์ ๋ฐ์ดํฐ์ ์ผ๋ก ๋งค์ฐ ํ๋น**ํฉ๋๋ค. ์ฑ๊ณต๋ฅ ์ด ๋์ ๊ตฐ์ง์ ๊ธฐ์ฌ์ ์ ์ฌํ๋ค๋ฉด ๋์ ๋
์ ์๋ฅผ, ๊ทธ๋ ์ง ์๋ค๋ฉด ๋ฎ์ ๋
์ ์๋ฅผ ์์ธกํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์
๋๋ค.
## 4. ์ ๋ต์ ์ ์ธ (AI ์์คํ
๋์
์ ์ค์ฌ์ผ๋ก)
1. **AI ์ ๋ชฉ/์ค๋ช
์์ฑ๊ธฐ ๋์
**: EDA๋ฅผ ํตํด ๊ฒ์ฆ๋ **'์ฑ๊ณตํ๋ ์ ๋ชฉ ํจํด'(์ ์ ํ ๊ธธ์ด, ํต์ฌ ํค์๋, ์ซ์/์ง๋ฌธ ํ์ฉ)์ AI ๋ชจ๋ธ์ ํ์ต**์์ผ ๋ชจ๋ ์ ๊ท ์ฝํ
์ธ ์ ์ ๋ชฉ๊ณผ ์ค๋ช
์ ์๋์ผ๋ก ์์ฑ ๋ฐ ์ถ์ฒ๋ฐ์์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ฝํ
์ธ ์ฑ๊ณผ์ ์ํฅ ํ์คํ๋ฅผ ๊ธฐ๋ํ ์ ์์ต๋๋ค.
2. **RAG ์์ธก ๋ชจ๋ธ์ ํ์ฉํ '์ ํ๊ณผ ์ง์ค'**: ๊ธฐ์ฌ ๊ธฐํ ๋จ๊ณ์์ **ํต์ฌ ์ฃผ์ ์ ์์ ์ ๋ชฉ์ RAG ๋ชจ๋ธ์ ์
๋ ฅํ์ฌ '์์ ๋
์ ์'๋ฅผ ๋ฏธ๋ฆฌ ํ์ธ**ํด์ผ ํฉ๋๋ค.
- ์์ธก ๋
์ ์๊ฐ ๋์ ๊ธฐํ์์ ๋ฆฌ์์ค๋ฅผ ์ง์คํ์ฌ ์ฐ์ ์ ์ผ๋ก ๋ฐํํ๊ณ , ์์ธก์น๊ฐ ๋ฎ์ ๊ธฐํ์์ ๋
์ ๊ด์ฌ๋๊ฐ ๋์ ์ฃผ์ ์ ๊ฒฐํฉํ๊ฑฐ๋ ์ ๋ชฉ ํจํด์ ์์ ํ๋ ๋ฑ **'๋ฐ์ดํฐ ๊ธฐ๋ฐ ์์ฌ๊ฒฐ์ '**์ ํตํด ์คํจ ํ๋ฅ ์ ์ค์ฌ์ผ ํฉ๋๋ค.
3. **A/B ํ
์คํธ๋ฅผ ํตํ ๋ชจ๋ธ ๊ณ ๋ํ**: AI๊ฐ ์ถ์ฒํ ์ฌ๋ฌ ์ ๋ชฉ ํ๋ณด๊ตฐ์ ๋์์ผ๋ก A/B ํ
์คํธ๋ฅผ ์งํํ๊ณ , ์ค์ ์ฑ๊ณผ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋ชจ๋ธ์ ํ์ต์์ผ ์ง์์ ์ผ๋ก ์ถ์ฒ ๋ฐ ์์ธก ์ ํ๋๋ฅผ ๋์ฌ๋๊ฐ์ผ ํฉ๋๋ค.
"""
report_path = f'{output_dir}/comprehensive_analysis_report_for_ai_validation.txt'
with open(report_path, 'w', encoding='utf-8') as f:
f.write(report)
print(f" - ์ข
ํฉ ์ธ์ฌ์ดํธ ๋ณด๊ณ ์ ์์ฑ ์๋ฃ. ({report_path} ์ ์ฅ)")
# 6. ๋ฉ์ธ ์คํ ํจ์
def main():
print("===== ์ ๋ฌธ๊ณผ๋ฐฉ์ก ๋
์ ๋ฐ์ดํฐ ์ฌ์ธต ๋ถ์ ์คํฌ๋ฆฝํธ ์คํ (AI ๋ชจ๋ธ ๊ฒ์ฆ ๊ด์ ) =====")
data_dir, output_dir = setup_environment()
all_data = load_and_preprocess_data(data_dir)
# --- ๊ธฐ์กด ๋ถ์ ์คํ (ํ์ ์ ์ฃผ์ ํด์ ) ---
# analyze_metrics_overview(all_data['merged'], output_dir)
# analyze_content_features(all_data['merged'], output_dir)
# analyze_demographics(all_data['demo'], all_data['merged'], output_dir)
# analyze_referrer(all_data['referrer'], all_data['merged'], output_dir)
# --- โ
์ ๊ท ๋ถ์ ์คํ โ
---
analyze_title_performance(all_data['merged'], output_dir)
analyze_topic_clusters_for_rag(all_data['merged'], output_dir)
generate_insights_report(all_data, output_dir)
print("\n===== ๋ชจ๋ ๋ถ์์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค. =====")
print(f"๊ฒฐ๊ณผ๋ฌผ์ '{output_dir}' ํด๋์์ ํ์ธํ์ค ์ ์์ต๋๋ค.")
if __name__ == '__main__':
main() |