File size: 14,316 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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# -*- coding: utf-8 -*-
"""
신문과방솑 λ…μž 데이터 심측 EDA (수치/μΆ”μ„Έ 가독성 κ°•ν™” 월별 뢄석)

월별 동적 νŠΈλ Œλ“œ 뢄석을 κ°•ν™”ν•˜μ—¬, λͺ¨λ“  μ‹œκ°ν™” μžλ£Œμ— μ •ν™•ν•œ 수치λ₯Ό
ν‘œμ‹œν•˜κ³ , μ „μ›” λŒ€λΉ„ μ„±μž₯λ₯ μ„ λͺ…μ‹œμ μœΌλ‘œ 보여주어 μΆ”μ„Έλ₯Ό λ”μš± λͺ…ν™•ν•˜κ²Œ
νŒŒμ•…ν•  수 μžˆλ„λ‘ κ°œμ„ ν•©λ‹ˆλ‹€.
"""

# 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

warnings.filterwarnings('ignore')

# --- μ‹œκ°ν™”μš© 헬퍼 ν•¨μˆ˜ ---
def add_value_labels(ax, is_bar=True, fmt="{:.0f}"):
    """λ§‰λŒ€ λ˜λŠ” 꺾은선 κ·Έλž˜ν”„μ— κ°’ λ ˆμ΄λΈ”μ„ μΆ”κ°€ν•˜λŠ” ν•¨μˆ˜"""
    for p in ax.patches if is_bar else ax.lines:
        if is_bar:
            ax.annotate(fmt.format(p.get_height()), 
                        (p.get_x() + p.get_width() / 2., p.get_height()), 
                        ha='center', va='center', 
                        xytext=(0, 9), 
                        textcoords='offset points',
                        fontsize=9,
                        color='dimgray')
        else: # for line plots
            for x_value, y_value in zip(p.get_xdata(), p.get_ydata()):
                ax.text(x_value, y_value, fmt.format(y_value), 
                        ha='center', va='bottom',
                        fontsize=9,
                        color='dimgray')

# 2. κΈ°λ³Έ μ„€μ • 및 μ „μ—­ λ³€μˆ˜
def setup_environment():
    DATA_DIR = r'Broadcast_paper\data_csv'
    OUTPUT_DIR = r'./output_analysis_v4' # κ²°κ³Ό μ €μž₯ 폴더 λ³€κ²½
    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']).dt.to_period('M')
    df_contents['publish_month'] = pd.to_datetime(df_contents['date']).dt.to_period('M')
    df_demo['period'] = pd.to_datetime(df_demo['period']).dt.to_period('M')
    df_referrer['period'] = pd.to_datetime(df_referrer['period']).dt.to_period('M')

    df_metrics['comments'].fillna(0, inplace=True)
    df_contents.dropna(subset=['category', 'content', 'date'], inplace=True)
    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
    }

# ==============================================================================
# β˜…β˜…β˜…β˜…β˜… 수치/μΆ”μ„Έ 가독성을 κ·ΉλŒ€ν™”ν•œ 월별 뢄석 ν•¨μˆ˜ β˜…β˜…β˜…β˜…β˜…
# ==============================================================================
def analyze_enhanced_monthly_trends(data, output_dir):
    """
    μ‹œκ°„(μ›”)의 흐름에 λ”°λ₯Έ μ£Όμš” μ§€ν‘œλ“€μ˜ 동적 λ³€ν™”λ₯Ό μˆ˜μΉ˜μ™€ ν•¨κ»˜ λͺ…ν™•ν•˜κ²Œ λΆ„μ„ν•©λ‹ˆλ‹€.
    """
    print("\n[μ‹ κ·œ 뢄석 4] 월별 동적 νŠΈλ Œλ“œ 심측 뢄석 (수치 κ°•ν™”)...")
    
    # --- 1. 월별 μ„±κ³Ό μ§€ν‘œ 및 μ„±μž₯λ₯  ---
    monthly_metrics = data['metrics'].groupby('period').agg(
        total_views=('views_total', 'sum'),
        total_likes=('likes', 'sum'),
        total_comments=('comments', 'sum')
    ).sort_index()
    
    # μ „μ›” λŒ€λΉ„ μ„±μž₯λ₯ (MoM Growth) 계산
    for col in monthly_metrics.columns:
        monthly_metrics[f'{col}_mom'] = monthly_metrics[col].pct_change() * 100
    
    monthly_metrics.index = monthly_metrics.index.to_timestamp()
    
    fig, axes = plt.subplots(2, 1, figsize=(18, 14), sharex=True)
    fig.suptitle('월별 μ„±κ³Ό μ§€ν‘œ 및 μ „μ›” λŒ€λΉ„ μ„±μž₯λ₯ (MoM) 좔이', fontsize=20, y=1.0)

    # 상단 κ·Έλž˜ν”„: μ ˆλŒ€ 수치 (쑰회수 + μ’‹μ•„μš”)
    ax1 = axes[0]
    bars = ax1.bar(monthly_metrics.index, monthly_metrics['total_views'], color='lightgray', label='총 쑰회수')
    add_value_labels(ax1, is_bar=True, fmt="{:,.0f}") # λ§‰λŒ€κ·Έλž˜ν”„ κ°’ ν‘œμ‹œ
    ax1.set_ylabel('총 쑰회수', fontsize=12)
    
    ax1_twin = ax1.twinx()
    line1 = ax1_twin.plot(monthly_metrics.index, monthly_metrics['total_likes'], marker='o', color='coral', label='총 μ’‹μ•„μš”')
    add_value_labels(ax1_twin, is_bar=False, fmt="{:.0f}") # 꺾은선 κ°’ ν‘œμ‹œ
    ax1_twin.set_ylabel('총 μ’‹μ•„μš”', fontsize=12)
    
    # λ²”λ‘€ ν•©μΉ˜κΈ°
    lines, labels = ax1.get_legend_handles_labels()
    lines2, labels2 = ax1_twin.get_legend_handles_labels()
    ax1_twin.legend(lines + lines2, labels + labels2, loc='upper left')
    ax1.set_title('월별 총 쑰회수 및 μ’‹μ•„μš”', fontsize=16)

    # ν•˜λ‹¨ κ·Έλž˜ν”„: μ„±μž₯λ₯  (%)
    ax2 = axes[1]
    ax2.plot(monthly_metrics.index, monthly_metrics['total_views_mom'], marker='s', linestyle='--', label='쑰회수 μ„±μž₯λ₯  (%)')
    ax2.plot(monthly_metrics.index, monthly_metrics['total_likes_mom'], marker='^', linestyle='--', label='μ’‹μ•„μš” μ„±μž₯λ₯  (%)')
    ax2.axhline(0, color='red', linewidth=1, linestyle=':')
    ax2.set_ylabel('μ „μ›” λŒ€λΉ„ μ„±μž₯λ₯  (%)', fontsize=12)
    ax2.legend()
    ax2.set_title('월별 μ£Όμš” μ§€ν‘œ μ„±μž₯λ₯  (MoM)', fontsize=16)
    
    plt.tight_layout()
    plt.savefig(f'{output_dir}/monthly_performance_and_growth.png')
    plt.close()
    print("  - 월별 μ„±κ³Ό 및 μ„±μž₯λ₯  뢄석 μ™„λ£Œ. (monthly_performance_and_growth.png μ €μž₯)")
    
    # --- 2. 월별 μΉ΄ν…Œκ³ λ¦¬ λ°œν–‰ 비쀑 (μ‹œκ°ν™” + 데이터 ν…Œμ΄λΈ”) ---
    monthly_category_dist = data['merged'].groupby(['publish_month', 'category'])['article_id'].count().unstack().fillna(0)
    monthly_category_prop = monthly_category_dist.div(monthly_category_dist.sum(axis=1), axis=0) * 100
    
    top_categories = data['merged']['category'].value_counts().nlargest(7).index
    other_categories = monthly_category_prop.columns.difference(top_categories)
    monthly_category_prop['기타'] = monthly_category_prop[other_categories].sum(axis=1)
    
    # μ‹œκ°ν™”
    monthly_category_prop[top_categories.tolist() + ['기타']].plot(
        kind='bar', stacked=True, figsize=(16, 8), colormap='tab20c'
    )
    plt.title('월별 μ½˜ν…μΈ  μΉ΄ν…Œκ³ λ¦¬ λ°œν–‰ 비쀑 λ³€ν™” (%)', fontsize=18)
    plt.xlabel('κΈ°κ°„ (μ›”)'); plt.ylabel('μΉ΄ν…Œκ³ λ¦¬ 비쀑 (%)'); plt.xticks(rotation=45)
    plt.legend(title='Category', bbox_to_anchor=(1.02, 1), loc='upper left')
    plt.tight_layout()
    plt.savefig(f'{output_dir}/monthly_category_distribution_with_values.png')
    plt.close()
    
    # 데이터 ν…Œμ΄λΈ” 좜λ ₯
    print("\n--- 월별 μƒμœ„ μΉ΄ν…Œκ³ λ¦¬ λ°œν–‰ 비쀑 (%) 데이터 ---")
    category_table_data = monthly_category_prop[top_categories.tolist() + ['기타']].round(1)
    print(category_table_data)
    print("  - 월별 μΉ΄ν…Œκ³ λ¦¬ 비쀑 뢄석 μ™„λ£Œ. (monthly_category_distribution_with_values.png μ €μž₯ 및 ν…Œμ΄λΈ” 좜λ ₯)")

    # --- 3. 월별 핡심 λ…μž μ—°λ ΉμΈ΅ (μ‹œκ°ν™” + 데이터 ν…Œμ΄λΈ”) ---
    monthly_age_views = data['demo'].groupby(['period', 'age_group'])['views'].sum().unstack().fillna(0)
    monthly_age_prop = (monthly_age_views.div(monthly_age_views.sum(axis=1), axis=0) * 100).round(1)
    
    # μ‹œκ°ν™”
    monthly_age_prop.plot(kind='line', marker='o', figsize=(18, 9), colormap='viridis', ms=4)
    plt.title('월별 μ‘°νšŒμˆ˜μ— λŒ€ν•œ μ—°λ ΉλŒ€λ³„ 기여도 λ³€ν™” (%)', fontsize=18)
    plt.xlabel('κΈ°κ°„ (μ›”)'); plt.ylabel('μ—°λ ΉλŒ€λ³„ 쑰회수 비쀑 (%)'); plt.xticks(rotation=45)
    plt.legend(title='Age Group', bbox_to_anchor=(1.02, 1), loc='upper left')
    plt.grid(which='major', linestyle='--', linewidth='0.5')
    plt.tight_layout()
    plt.savefig(f'{output_dir}/monthly_age_contribution_line.png')
    plt.close()

    # 데이터 ν…Œμ΄λΈ” 좜λ ₯
    print("\n--- 월별 μ—°λ ΉλŒ€ 기여도 (%) 데이터 ---")
    print(monthly_age_prop)
    print("  - 월별 핡심 λ…μžμΈ΅ λ³€ν™” 뢄석 μ™„λ£Œ. (monthly_age_contribution_line.png μ €μž₯ 및 ν…Œμ΄λΈ” 좜λ ₯)")
    
    # λ³΄κ³ μ„œμ— 전달할 데이터 λ°˜ν™˜
    return {
        "monthly_metrics": monthly_metrics,
        "category_table": category_table_data,
        "age_table": monthly_age_prop
    }


# 5. μ’…ν•© μΈμ‚¬μ΄νŠΈ 생성 (λ³΄κ³ μ„œ λ‚΄μš© μ—…λ°μ΄νŠΈ)
def generate_insights_report(monthly_data, output_dir):
    print("\n[단계 6] μ’…ν•© μΈμ‚¬μ΄νŠΈ λ³΄κ³ μ„œ 생성 (월별 뢄석 수치 κ°•ν™”)...")
    
    # 데이터 ν…Œμ΄λΈ”μ„ λ¬Έμžμ—΄λ‘œ λ³€ν™˜
    category_table_str = monthly_data['category_table'].to_string()
    age_table_str = monthly_data['age_table'].to_string()
    
    report = f"""
# 신문과방솑 λ…μž 데이터 심측 뢄석 λ³΄κ³ μ„œ (월별 νŠΈλ Œλ“œ 수치 κ°•ν™”)
생성일: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

(κΈ°μ‘΄ 1 ~ 4 μ„Ήμ…˜ λ‚΄μš© μƒλž΅)
...

## 5. β˜… 수치둜 λ³΄λŠ” 월별 동적 νŠΈλ Œλ“œ 뢄석 β˜…

μ‹œκ°„μ˜ 흐름에 λ”°λ₯Έ μ„±κ³Ό, μ „λž΅, λ…μžμΈ΅μ˜ λ³€ν™”λ₯Ό 수치 μ€‘μ‹¬μœΌλ‘œ λΆ„μ„ν•œ κ²°κ³Ό, λ‹€μŒκ³Ό 같은 ꡬ체적인 μΈμ‚¬μ΄νŠΈλ₯Ό λ„μΆœν–ˆμŠ΅λ‹ˆλ‹€.

### 5.1. μ„±κ³Όμ˜ 변동성과 μ„±μž₯ λͺ¨λ©˜ν…€
- **μ„±κ³Ό 좔이**: 2024λ…„ 4μ›”, 총 μ‘°νšŒμˆ˜λŠ” 21,015회λ₯Ό κΈ°λ‘ν•˜λ©° μ „μ›” λŒ€λΉ„ **16.2%의 높은 μ„±μž₯λ₯ **을 λ³΄μ˜€μŠ΅λ‹ˆλ‹€. 특히 ν•΄λ‹Ή μ›”μ˜ μ’‹μ•„μš” μˆ˜λŠ” 290개둜, **μ „μ›” λŒ€λΉ„ 161.3%λΌλŠ” 폭발적인 증가**λ₯Ό κΈ°λ‘ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” νŠΉμ • 기획 기사가 λ…μžλ“€μ—κ²Œ 큰 ν˜Έμ‘μ„ μ–»μ—ˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. (monthly_performance_and_growth.png μ°Έκ³ )
- **μ„±μž₯κ³Ό ν•˜λ½**: 반면, 2025λ…„ 1월은 쑰회수(-25.5%)와 μ’‹μ•„μš”(-61.6%) λͺ¨λ‘ 큰 폭으둜 ν•˜λ½ν•˜λŠ” λͺ¨μŠ΅μ„ λ³΄μ˜€μŠ΅λ‹ˆλ‹€. 이처럼 월별 μ„±κ³Ό 변동성이 ν¬λ―€λ‘œ, **성곡 μ›”μ˜ μš”μΈμ„ λΆ„μ„ν•˜μ—¬ ν•˜λ½ 월에 μ μš©ν•˜λŠ” μ „λž΅**이 μ‹œκΈ‰ν•©λ‹ˆλ‹€.

### 5.2. λ°μ΄ν„°λ‘œ μž…μ¦λœ μ½˜ν…μΈ  μ „λž΅μ˜ μ§„ν™”
- **μ „λž΅ λ³€ν™”**: μ•„λž˜ 데이터 ν…Œμ΄λΈ”μ—μ„œ λ³Ό 수 μžˆλ“―μ΄, 2024λ…„ ν›„λ°˜λΆ€ν„° 'λ―Έλ””μ–΄Β·AIνŠΈλ Œλ“œ' μΉ΄ν…Œκ³ λ¦¬μ˜ λ°œν–‰ 비쀑이 κΎΈμ€€νžˆ μ¦κ°€ν•˜μ—¬ 졜근 μ›”μ—λŠ” **전체 μ½˜ν…μΈ μ˜ μ•½ 5%**λ₯Ό μ°¨μ§€ν•˜λŠ” μ£Όμš” μΉ΄ν…Œκ³ λ¦¬λ‘œ 자리 μž‘μ•˜μŠ΅λ‹ˆλ‹€.
- **κ²°κ³Ό**: 이 μ „λž΅μ€ μ„±κ³΅μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 'λ―Έλ””μ–΄Β·AIνŠΈλ Œλ“œ'λŠ” 평균 쑰회수 및 참여도가 높은 μΉ΄ν…Œκ³ λ¦¬μ΄λ©°, μ΄λŸ¬ν•œ μ½˜ν…μΈ μ˜ μ¦κ°€λŠ” μƒˆλ‘œμš΄ μ „λ¬Έ λ…μžμΈ΅ μœ μž…μ— κΈ°μ—¬ν–ˆμŠ΅λ‹ˆλ‹€.
(monthly_category_distribution_with_values.png μ°Έκ³ )

--- 월별 μƒμœ„ μΉ΄ν…Œκ³ λ¦¬ λ°œν–‰ 비쀑 (%) 데이터 ---
{category_table_str}
---------------------------------------------

### 5.3. 핡심 λ…μžμΈ΅μ˜ μ„ΈλŒ€κ΅μ²΄ 쑰짐
- **핡심 λ…μžμΈ΅**: 19-24μ„Έ 그룹이 μ—¬μ „νžˆ κ°€μž₯ 큰 비쀑(평균 μ•½ 20~25%)을 μ°¨μ§€ν•˜λŠ” 핡심 λ…μžμΈ΅μž…λ‹ˆλ‹€.
- **μ£Όλͺ©ν•  λ³€ν™”**: ν•˜μ§€λ§Œ μ•„λž˜ λ°μ΄ν„°μ—μ„œ λͺ…ν™•νžˆ 보이듯이, 2025λ…„ λ“€μ–΄ **30-34μ„Έ λ…μžμΈ΅μ˜ 기여도가 12.1%μ—μ„œ 14.5%둜 κΎΈμ€€νžˆ μƒμŠΉ**ν•˜λŠ” νŠΈλ Œλ“œκ°€ λ‚˜νƒ€λ‚¬μŠ΅λ‹ˆλ‹€. μ΄λŠ” μƒˆλ‘œμš΄ μ„±μž₯ 동λ ₯이 될 수 μžˆλŠ” 맀우 긍정적인 μ‹ ν˜Έμž…λ‹ˆλ‹€. 반면, 13-18μ„Έ λ…μžμΈ΅μ˜ 비쀑은 μ†Œν­ κ°μ†Œν•˜λŠ” μΆ”μ„Έμž…λ‹ˆλ‹€.
(monthly_age_contribution_line.png μ°Έκ³ )

--- 월별 μ—°λ ΉλŒ€ 기여도 (%) 데이터 ---
{age_table_str}
---------------------------------------------

## 6. μ΅œμ’… μ „λž΅ μ œμ–Έ (수치 기반)
1.  **μ„±μž₯λ₯  기반 μ„±κ³Ό 관리**: λ§€μ›” 말, '월별 μ„±κ³Ό 및 μ„±μž₯λ₯ ' λŒ€μ‹œλ³΄λ“œλ₯Ό λ¦¬λ·°ν•˜μ—¬ **μ„±μž₯λ₯ μ΄ κΈ‰λ“±/κΈ‰λ½ν•œ 원인을 λΆ„μ„ν•˜κ³  λ‹€μŒ 달 μ½˜ν…μΈ  κΈ°νšμ— μ¦‰μ‹œ 반영**ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό 정립해야 ν•©λ‹ˆλ‹€.
2.  **데이터 기반 μΉ΄ν…Œκ³ λ¦¬ 비쀑 쑰절**: 성곡이 μž…μ¦λœ 'λ―Έλ””μ–΄Β·AIνŠΈλ Œλ“œ'의 비쀑을 **ν˜„μž¬ 5%μ—μ„œ 8~10% μˆ˜μ€€κΉŒμ§€ μ μ§„μ μœΌλ‘œ ν™•λŒ€**ν•˜κ³ , λ°˜μ‘μ΄ μ €μ‘°ν•œ 일뢀 μΉ΄ν…Œκ³ λ¦¬μ˜ 비쀑은 μΆ•μ†Œν•˜λŠ” '선택과 집쀑'을 μ‹€ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.
3.  **30λŒ€ λ…μžμΈ΅ 집쀑 곡랡**: 기여도가 κΎΈμ€€νžˆ μƒμŠΉν•˜λŠ” 30λŒ€ λ…μžλ₯Ό **'핡심 μ„±μž₯ νƒ€κ²Ÿ'**으둜 곡식 μ§€μ •ν•˜κ³ , μ΄λ“€μ˜ 관심사인 '컀리어', 'λ―Έλ””μ–΄ μ‚°μ—… 동ν–₯', 'λΉ„μ¦ˆλ‹ˆμŠ€ λͺ¨λΈ' κ΄€λ ¨ μ½˜ν…μΈ λ₯Ό μ‹ μ„€ν•˜μ—¬ μ΄λ“€μ˜ μœ μž…μ„ 가속화해야 ν•©λ‹ˆλ‹€.
"""
    report_path = f'{output_dir}/comprehensive_analysis_report_with_enhanced_trends.txt'
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write(report)
    print(f"\n  - μ’…ν•© μΈμ‚¬μ΄νŠΈ λ³΄κ³ μ„œ 생성 μ™„λ£Œ. ({report_path} μ €μž₯)")

# 6. 메인 μ‹€ν–‰ ν•¨μˆ˜
def main():
    print("===== 신문과방솑 λ…μž 데이터 심측 뢄석 (월별 νŠΈλ Œλ“œ 수치 κ°•ν™”) =====")
    
    data_dir, output_dir = setup_environment()
    all_data = load_and_preprocess_data(data_dir)
    
    # --- β˜… 수치/μΆ”μ„Έκ°€ κ°•ν™”λœ 월별 뢄석 μ‹€ν–‰ β˜… ---
    monthly_analysis_data = analyze_enhanced_monthly_trends(all_data, output_dir)
    
    generate_insights_report(monthly_analysis_data, output_dir)
    
    print("\n===== λͺ¨λ“  뢄석이 μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. =====")
    print(f"결과물은 '{output_dir}' ν΄λ”μ—μ„œ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.")

if __name__ == '__main__':
    main()