+
+
+
+
+
+
+
+
+
+In [23]:
+
+
+
+
+
+# 필요한 라이브러리 임포트
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+import seaborn as sns
+from datetime import datetime
+import warnings
+warnings.filterwarnings('ignore')
+
+sns.set_style('whitegrid') # 먼저 seaborn 스타일 적용
+plt.rc('font', family='Malgun Gothic') # 그 다음 폰트 설정
+plt.rcParams['axes.unicode_minus'] = False
+
+plt.rcParams['figure.figsize'] = (12, 6)
+
+print("라이브러리 로드 완료!")
+
+
+
+
+
+
+
+
+
+
+
+라이브러리 로드 완료! ++
+
+
+
+
+
+
+
+
+1. 데이터 로드¶
+
+
+
+
+
+
+
+
+In [24]:
+
+
+
+
+
+# 데이터 경로 설정
+data_dir = r'c:\Users\korea\Desktop\dacon_broadcast_paper\data_csv'
+
+# 각 데이터셋 로드
+print("데이터 로딩 시작...\n")
+
+# 1. 기사 월별 지표
+df_metrics = pd.read_csv(f'{data_dir}/article_metrics_monthly.csv')
+print(f"✓ article_metrics_monthly: {df_metrics.shape}")
+
+# 2. 콘텐츠 정보
+df_contents = pd.read_csv(f'{data_dir}/contents.csv')
+print(f"✓ contents: {df_contents.shape}")
+
+# 3. 인구통계학적 데이터 (병합된 파일)
+df_demo = pd.read_csv(f'{data_dir}/demographics_merged.csv')
+print(f"✓ demographics_merged: {df_demo.shape}")
+
+# 4. 유입 경로
+df_referrer = pd.read_csv(f'{data_dir}/referrer.csv')
+print(f"✓ referrer: {df_referrer.shape}")
+
+print("\n모든 데이터 로드 완료!")
+
+
+
+
+
+
+
+
+
+
+
+데이터 로딩 시작... + +✓ article_metrics_monthly: (45344, 5) +✓ contents: (1746, 7) +✓ demographics_merged: (1089504, 6) +✓ referrer: (194947, 6) + +모든 데이터 로드 완료! ++
+
+
+
+
+
+
+
+
+2. 기사 지표 분석 (article_metrics_monthly)¶
+
+
+
+
+
+
+
+In [25]:
+
+
+
+
+
+# 기본 정보 확인
+print("=" * 80)
+print("기사 월별 지표 데이터 분석")
+print("=" * 80)
+
+print("\n[데이터 정보]")
+print(df_metrics.info())
+
+print("\n[기본 통계]")
+print(df_metrics.describe())
+
+print("\n[결측치 확인]")
+print(df_metrics.isnull().sum())
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +기사 월별 지표 데이터 분석 +================================================================================ + +[데이터 정보] +<class 'pandas.core.frame.DataFrame'> +RangeIndex: 45344 entries, 0 to 45343 +Data columns (total 5 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 article_id 45344 non-null int64 + 1 period 45344 non-null object + 2 comments 45318 non-null float64 + 3 likes 45344 non-null int64 + 4 views_total 45344 non-null int64 +dtypes: float64(1), int64(3), object(1) +memory usage: 1.7+ MB +None + +[기본 통계] + article_id comments likes views_total +count 4.534400e+04 45318.000000 45344.000000 45344.000000 +mean 2.228009e+11 0.017035 0.097411 9.365186 +std 5.890164e+08 0.230746 0.870059 30.038701 +min 2.217634e+11 0.000000 0.000000 0.000000 +25% 2.222804e+11 0.000000 0.000000 0.000000 +50% 2.228001e+11 0.000000 0.000000 2.000000 +75% 2.232544e+11 0.000000 0.000000 7.000000 +max 2.239501e+11 15.000000 32.000000 1010.000000 + +[결측치 확인] +article_id 0 +period 0 +comments 26 +likes 0 +views_total 0 +dtype: int64 ++
+
+
+
+
+
+
+In [26]:
+
+
+
+
+
+# 기간별 분석
+df_metrics['period'] = pd.to_datetime(df_metrics['period'])
+
+# 월별 집계
+monthly_stats = df_metrics.groupby('period').agg({
+ 'article_id': 'count',
+ 'views_total': 'sum',
+ 'likes': 'sum',
+ 'comments': 'sum'
+}).reset_index()
+
+monthly_stats.columns = ['기간', '기사수', '총_조회수', '총_좋아요', '총_댓글수']
+
+print("\n[월별 집계 통계]")
+print(monthly_stats)
+
+
+
+
+
+
+
+
+
+
+
++[월별 집계 통계] + 기간 기사수 총_조회수 총_좋아요 총_댓글수 +0 2023-07-01 1744 17490 212 28.0 +1 2023-08-01 1744 14942 166 21.0 +2 2023-09-01 1744 14330 164 13.0 +3 2023-10-01 1744 19020 167 19.0 +4 2023-11-01 1744 21058 165 29.0 +5 2023-12-01 1744 15874 142 33.0 +6 2024-01-01 1744 14010 150 29.0 +7 2024-02-01 1744 12287 155 41.0 +8 2024-03-01 1744 18087 111 39.0 +9 2024-04-01 1744 21015 290 67.0 +10 2024-05-01 1744 25323 228 43.0 +11 2024-06-01 1744 20508 188 43.0 +12 2024-07-01 1744 19207 185 42.0 +13 2024-08-01 1744 15927 168 30.0 +14 2024-09-01 1744 15351 146 28.0 +15 2024-10-01 1744 18866 177 18.0 +16 2024-11-01 1744 21171 140 11.0 +17 2024-12-01 1744 15025 237 32.0 +18 2025-01-01 1744 11188 91 23.0 +19 2025-02-01 1744 11730 164 28.0 +20 2025-03-01 1744 15010 254 33.0 +21 2025-04-01 1744 15137 224 29.0 +22 2025-05-01 1744 16262 125 20.0 +23 2025-06-01 1744 13347 161 27.0 +24 2025-07-01 1744 12566 174 36.0 +25 2025-08-01 1744 9924 33 10.0 ++
+
+
+
+
+
+
+In [27]:
+
+
+
+
+
+# 시각화: 월별 조회수 추이
+fig, axes = plt.subplots(2, 2, figsize=(16, 10))
+
+# 월별 총 조회수
+axes[0, 0].plot(monthly_stats['기간'], monthly_stats['총_조회수'], marker='o', linewidth=2)
+axes[0, 0].set_title('월별 총 조회수 추이', fontsize=14, fontweight='bold')
+axes[0, 0].set_xlabel('기간')
+axes[0, 0].set_ylabel('총 조회수')
+axes[0, 0].grid(True, alpha=0.3)
+axes[0, 0].tick_params(axis='x', rotation=45)
+
+# 월별 총 좋아요
+axes[0, 1].plot(monthly_stats['기간'], monthly_stats['총_좋아요'], marker='o', color='red', linewidth=2)
+axes[0, 1].set_title('월별 총 좋아요 추이', fontsize=14, fontweight='bold')
+axes[0, 1].set_xlabel('기간')
+axes[0, 1].set_ylabel('총 좋아요')
+axes[0, 1].grid(True, alpha=0.3)
+axes[0, 1].tick_params(axis='x', rotation=45)
+
+# 월별 총 댓글수
+axes[1, 0].plot(monthly_stats['기간'], monthly_stats['총_댓글수'], marker='o', color='green', linewidth=2)
+axes[1, 0].set_title('월별 총 댓글수 추이', fontsize=14, fontweight='bold')
+axes[1, 0].set_xlabel('기간')
+axes[1, 0].set_ylabel('총 댓글수')
+axes[1, 0].grid(True, alpha=0.3)
+axes[1, 0].tick_params(axis='x', rotation=45)
+
+# 월별 기사수
+axes[1, 1].bar(monthly_stats['기간'], monthly_stats['기사수'], color='purple', alpha=0.7)
+axes[1, 1].set_title('월별 기사 수', fontsize=14, fontweight='bold')
+axes[1, 1].set_xlabel('기간')
+axes[1, 1].set_ylabel('기사 수')
+axes[1, 1].grid(True, alpha=0.3, axis='y')
+axes[1, 1].tick_params(axis='x', rotation=45)
+
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [28]:
+
+
+
+
+
+# 인기 기사 TOP 20 분석
+top_articles = df_metrics.groupby('article_id').agg({
+ 'views_total': 'sum',
+ 'likes': 'sum',
+ 'comments': 'sum'
+}).reset_index()
+
+top_articles = top_articles.sort_values('views_total', ascending=False).head(20)
+
+print("\n[조회수 TOP 20 기사]")
+print(top_articles)
+
+
+
+
+
+
+
+
+
+
+
++[조회수 TOP 20 기사] + article_id views_total likes comments +1373 223338373790 6142 9 4.0 +563 222456508992 4976 6 0.0 +1214 223129734365 4300 12 0.0 +1361 223338149961 3921 17 5.0 +1421 223430762932 3152 40 9.0 +1451 223468670006 2883 18 3.0 +1465 223498445382 2860 10 0.0 +1096 223001499509 2561 0 0.0 +1283 223227874868 2299 9 0.0 +1420 223430759166 2256 38 1.0 +1360 223338139549 2167 9 6.0 +1091 222994889581 2021 1 0.0 +1266 223198843166 2020 10 1.0 +1459 223468753396 1940 15 1.0 +542 222428623830 1914 5 1.0 +1265 223198839690 1761 8 2.0 +886 222804485559 1729 1 0.0 +1408 223410631358 1673 3 1.0 +25 221800431227 1636 1 0.0 +1412 223410658775 1623 8 3.0 ++
+
+
+
+
+
+
+
+
+3. 콘텐츠 분석 (contents)¶
+
+
+
+
+
+
+
+In [29]:
+
+
+
+
+
+print("=" * 80)
+print("콘텐츠 데이터 분석")
+print("=" * 80)
+
+print("\n[데이터 정보]")
+print(df_contents.info())
+
+print("\n[결측치 확인]")
+print(df_contents.isnull().sum())
+
+print("\n[카테고리별 기사 수]")
+category_counts = df_contents['category'].value_counts()
+print(category_counts)
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +콘텐츠 데이터 분석 +================================================================================ + +[데이터 정보] +<class 'pandas.core.frame.DataFrame'> +RangeIndex: 1746 entries, 0 to 1745 +Data columns (total 7 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 article_id 1746 non-null int64 + 1 category 1745 non-null object + 2 title 1746 non-null object + 3 content 1745 non-null object + 4 date 1745 non-null object + 5 tag 1322 non-null object + 6 source_url 1746 non-null object +dtypes: int64(1), object(6) +memory usage: 95.6+ KB +None + +[결측치 확인] +article_id 0 +category 1 +title 0 +content 1 +date 1 +tag 424 +source_url 0 +dtype: int64 + +[카테고리별 기사 수] +category +커버스토리 254 +취재기·제작기 205 +미디어 월드 와이드 203 +집중점검 152 +미디어현장 142 +기획연재 133 +미디어포럼 123 +카드뉴스 117 +미디어·AI트렌드 58 +미디어 리뷰 57 +글로벌 미디어 현장 56 +신문과방송 48 +재단소식 45 +신방에서 알려주는 36 +미디어 人사이드 32 +테크 24 +빅카인즈 15 +미디어비평 13 +아이디어스 11 +지금 언론계에선 8 +산업・정책 6 +독자가 본 언론 5 +한국언론진흥재단 소식 2 +Name: count, dtype: int64 ++
+
+
+
+
+
+
+In [30]:
+
+
+
+
+
+# 카테고리별 기사 수 시각화
+fig, axes = plt.subplots(1, 2, figsize=(16, 6))
+
+# 막대 그래프
+category_counts.plot(kind='barh', ax=axes[0], color='skyblue')
+axes[0].set_title('카테고리별 기사 수', fontsize=14, fontweight='bold')
+axes[0].set_xlabel('기사 수')
+axes[0].set_ylabel('카테고리')
+axes[0].grid(True, alpha=0.3, axis='x')
+
+# 파이 차트
+category_counts.plot(kind='pie', ax=axes[1], autopct='%1.1f%%', startangle=90)
+axes[1].set_title('카테고리별 기사 비율', fontsize=14, fontweight='bold')
+axes[1].set_ylabel('')
+
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [31]:
+
+
+
+
+
+# 태그 분석
+print("\n[태그 분석]")
+print(f"태그가 있는 기사: {df_contents['tag'].notna().sum()}")
+print(f"태그가 없는 기사: {df_contents['tag'].isna().sum()}")
+
+# 태그를 쉼표로 분리하여 개별 태그 추출
+all_tags = []
+for tags in df_contents['tag'].dropna():
+ if isinstance(tags, str):
+ all_tags.extend([tag.strip() for tag in tags.split(',')])
+
+tag_counts = pd.Series(all_tags).value_counts().head(30)
+
+print("\n[상위 30개 태그]")
+print(tag_counts)
+
+
+
+
+
+
+
+
+
+
+
++[태그 분석] +태그가 있는 기사: 1322 +태그가 없는 기사: 424 + +[상위 30개 태그] +#언론 657 +#기자 442 +#뉴스 417 +#미디어 387 +#저널리즘 316 +#기사 308 +#신문과방송 213 +#콘텐츠 212 +#보도 211 +#방송 195 +#한국언론진흥재단 194 +#언론인 180 +#신문 170 +#취재 166 +#테크 140 +#이슈 138 +#기술 137 +#인공지능 122 +#AI 110 +#디지털 108 +#언론사 101 +#정치 85 +#미국 71 +#유튜브 64 +#플랫폼 63 +#비즈니스 62 +#코로나19 59 +#카드뉴스 58 +#법률 57 +#TV 55 +Name: count, dtype: int64 ++
+
+
+
+
+
+
+In [32]:
+
+
+
+
+
+# 상위 태그 시각화
+plt.figure(figsize=(14, 8))
+tag_counts.plot(kind='barh', color='coral')
+plt.title('상위 30개 태그 빈도', fontsize=14, fontweight='bold')
+plt.xlabel('빈도')
+plt.ylabel('태그')
+plt.grid(True, alpha=0.3, axis='x')
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [33]:
+
+
+
+
+
+# 콘텐츠와 지표 데이터 병합
+df_contents_with_metrics = df_contents.merge(
+ df_metrics.groupby('article_id').agg({
+ 'views_total': 'sum',
+ 'likes': 'sum',
+ 'comments': 'sum'
+ }).reset_index(),
+ on='article_id',
+ how='left'
+)
+
+print("\n[카테고리별 평균 지표]")
+category_metrics = df_contents_with_metrics.groupby('category').agg({
+ 'views_total': 'mean',
+ 'likes': 'mean',
+ 'comments': 'mean'
+}).round(2)
+
+category_metrics.columns = ['평균_조회수', '평균_좋아요', '평균_댓글수']
+print(category_metrics.sort_values('평균_조회수', ascending=False))
+
+
+
+
+
+
+
+
+
+
+
++[카테고리별 평균 지표] + 평균_조회수 평균_좋아요 평균_댓글수 +category +미디어 人사이드 567.53 10.84 1.41 +아이디어스 470.00 6.73 1.73 +미디어·AI트렌드 386.74 8.40 1.67 +커버스토리 349.11 2.97 0.44 +미디어 리뷰 338.25 6.82 1.35 +미디어현장 300.40 1.87 0.39 +집중점검 275.89 1.36 0.25 +기획연재 267.65 1.32 0.07 +취재기·제작기 255.96 3.83 0.51 +글로벌 미디어 현장 247.54 5.66 1.27 +미디어포럼 212.56 1.68 0.33 +독자가 본 언론 200.20 0.80 0.00 +지금 언론계에선 190.88 0.12 0.00 +테크 165.29 0.12 0.00 +신방에서 알려주는 159.33 0.06 0.00 +재단소식 155.07 0.91 0.23 +미디어 월드 와이드 147.05 0.88 0.27 +산업・정책 136.83 0.17 0.17 +미디어비평 127.23 0.23 0.00 +신문과방송 100.50 3.21 0.62 +한국언론진흥재단 소식 96.50 2.00 2.50 +빅카인즈 53.00 0.07 0.00 +카드뉴스 7.96 0.02 0.02 ++
+
+
+
+
+
+
+
+
+4. 인구통계학적 분석 (demographics)¶
+
+
+
+
+
+
+
+In [34]:
+
+
+
+
+
+print("=" * 80)
+print("인구통계학적 데이터 분석")
+print("=" * 80)
+
+print("\n[데이터 정보]")
+print(df_demo.info())
+
+print("\n[기본 통계]")
+print(df_demo.describe())
+
+print("\n[연령대 분포]")
+print(df_demo['age_group'].value_counts().sort_index())
+
+print("\n[성별 분포]")
+print(df_demo['gender'].value_counts())
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +인구통계학적 데이터 분석 +================================================================================ + +[데이터 정보] +<class 'pandas.core.frame.DataFrame'> +RangeIndex: 1089504 entries, 0 to 1089503 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 article_id 1089504 non-null int64 + 1 period 1089504 non-null object + 2 age_group 1089504 non-null object + 3 gender 1089504 non-null object + 4 views 1089504 non-null int64 + 5 ratio 1089504 non-null float64 +dtypes: float64(1), int64(2), object(3) +memory usage: 49.9+ MB +None + +[기본 통계] + article_id views ratio +count 1.089504e+06 1.089504e+06 1.089504e+06 +mean 2.228001e+11 3.659243e-01 1.823219e+00 +std 5.890834e+08 3.018826e+00 8.688175e+00 +min 2.217634e+11 0.000000e+00 0.000000e+00 +25% 2.222794e+11 0.000000e+00 0.000000e+00 +50% 2.227994e+11 0.000000e+00 0.000000e+00 +75% 2.232544e+11 0.000000e+00 0.000000e+00 +max 2.239501e+11 4.700000e+02 1.000000e+02 + +[연령대 분포] +age_group +0-12 90792 +13-18 90792 +19-24 90792 +25-29 90792 +30-34 90792 +35-39 90792 +40-44 90792 +45-49 90792 +50-54 90792 +55-59 90792 +60- 90792 +전체 90792 +Name: count, dtype: int64 + +[성별 분포] +gender +남 544752 +여 544752 +Name: count, dtype: int64 ++
+
+
+
+
+
+
+In [35]:
+
+
+
+
+
+# 연령대별, 성별 조회수 분석
+# '전체' 제외하고 분석
+df_demo_filtered = df_demo[df_demo['age_group'] != '전체'].copy()
+
+# 연령대별, 성별 총 조회수
+demo_summary = df_demo_filtered.groupby(['age_group', 'gender'])['views'].sum().reset_index()
+demo_pivot = demo_summary.pivot(index='age_group', columns='gender', values='views')
+
+print("\n[연령대별, 성별 총 조회수]")
+print(demo_pivot)
+
+
+
+
+
+
+
+
+
+
+
++[연령대별, 성별 총 조회수] +gender 남 여 +age_group +0-12 49 83 +13-18 4139 15435 +19-24 8922 28672 +25-29 12078 22626 +30-34 10479 13851 +35-39 9083 8529 +40-44 9330 9065 +45-49 8115 8259 +50-54 7405 6222 +55-59 5092 3086 +60- 5949 2869 + +gender 남 여 +age_group +0-12 49 83 +13-18 4139 15435 +19-24 8922 28672 +25-29 12078 22626 +30-34 10479 13851 +35-39 9083 8529 +40-44 9330 9065 +45-49 8115 8259 +50-54 7405 6222 +55-59 5092 3086 +60- 5949 2869 ++
+
+
+
+
+
+
+In [36]:
+
+
+
+
+
+# 연령대별 성별 조회수 시각화
+fig, axes = plt.subplots(1, 2, figsize=(16, 6))
+
+# 막대 그래프
+demo_pivot.plot(kind='bar', ax=axes[0], color=['#FF6B6B', '#4ECDC4'])
+axes[0].set_title('연령대별 성별 총 조회수', fontsize=14, fontweight='bold')
+axes[0].set_xlabel('연령대')
+axes[0].set_ylabel('총 조회수')
+axes[0].legend(title='성별')
+axes[0].grid(True, alpha=0.3, axis='y')
+axes[0].tick_params(axis='x', rotation=45)
+
+# 누적 막대 그래프
+demo_pivot.plot(kind='bar', stacked=True, ax=axes[1], color=['#FF6B6B', '#4ECDC4'])
+axes[1].set_title('연령대별 성별 조회수 (누적)', fontsize=14, fontweight='bold')
+axes[1].set_xlabel('연령대')
+axes[1].set_ylabel('총 조회수')
+axes[1].legend(title='성별')
+axes[1].grid(True, alpha=0.3, axis='y')
+axes[1].tick_params(axis='x', rotation=45)
+
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [37]:
+
+
+
+
+
+# 연령대별 비율 분석
+age_ratio = df_demo_filtered.groupby('age_group')['ratio'].mean().sort_values(ascending=False)
+
+print("\n[연령대별 평균 비율]")
+print(age_ratio)
+
+# 시각화
+plt.figure(figsize=(12, 6))
+age_ratio.plot(kind='bar', color='steelblue')
+plt.title('연령대별 평균 시청 비율', fontsize=14, fontweight='bold')
+plt.xlabel('연령대')
+plt.ylabel('평균 비율')
+plt.grid(True, alpha=0.3, axis='y')
+plt.xticks(rotation=45)
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
++[연령대별 평균 비율] +age_group +19-24 2.209989 +25-29 1.760732 +13-18 1.227277 +30-34 1.216299 +40-44 0.992745 +35-39 0.913717 +45-49 0.903025 +50-54 0.754981 +60- 0.485116 +55-59 0.466950 +0-12 0.008510 +Name: ratio, dtype: float64 ++
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5. 유입 경로 분석 (referrer)¶
+
+
+
+
+
+
+
+In [38]:
+
+
+
+
+
+print("=" * 80)
+print("유입 경로 데이터 분석")
+print("=" * 80)
+
+print("\n[데이터 정보]")
+print(df_referrer.info())
+
+print("\n[기본 통계]")
+print(df_referrer.describe())
+
+print("\n[유입 경로별 비중]")
+referrer_summary = df_referrer.groupby('referrer')['share'].sum().sort_values(ascending=False)
+print(referrer_summary)
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +유입 경로 데이터 분석 +================================================================================ + +[데이터 정보] +<class 'pandas.core.frame.DataFrame'> +RangeIndex: 194947 entries, 0 to 194946 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 article_id 194947 non-null int64 + 1 article_title 194947 non-null object + 2 period 194947 non-null object + 3 referrer 194947 non-null object + 4 referrer_detail 194947 non-null object + 5 share 194947 non-null float64 +dtypes: float64(1), int64(1), object(4) +memory usage: 8.9+ MB +None + +[기본 통계] + article_id share +count 1.949470e+05 194947.000000 +mean 2.230342e+11 14.145289 +std 5.183599e+08 22.409763 +min 2.217634e+11 0.120000 +25% 2.227005e+11 1.890000 +50% 2.231478e+11 5.080000 +75% 2.234090e+11 14.290000 +max 2.239501e+11 100.000000 + +[유입 경로별 비중] +referrer +Google 865059.28 +네이버 통합검색_모바일 607442.08 +네이버 통합검색_PC 504590.71 +네이버 블로그_PC 324031.69 +네이버 블로그_모바일 118964.06 + ... +webmail.arirang.com 0.60 +koreapro.org 0.60 +yu.copykiller.com 0.48 +mail.cu.ac.kr 0.45 +gw.huons.com 0.44 +Name: share, Length: 419, dtype: float64 ++
+
+
+
+
+
+
+In [39]:
+
+
+
+
+
+# 유입 경로 시각화
+fig, axes = plt.subplots(1, 2, figsize=(16, 6))
+
+# 막대 그래프
+referrer_summary.head(20).plot(kind='barh', ax=axes[0], color='teal')
+axes[0].set_title('주요 유입 경로별 비중 (TOP 20)', fontsize=14, fontweight='bold')
+axes[0].set_xlabel('총 비중')
+axes[0].set_ylabel('유입 경로')
+axes[0].grid(True, alpha=0.3, axis='x')
+
+# 파이 차트 (상위 10개)
+top_10_referrers = referrer_summary.head(10)
+others = referrer_summary.iloc[10:].sum()
+pie_data = pd.concat([top_10_referrers, pd.Series({'기타': others})])
+
+axes[1].pie(pie_data, labels=pie_data.index, autopct='%1.1f%%', startangle=90)
+axes[1].set_title('유입 경로 비율 (TOP 10 + 기타)', fontsize=14, fontweight='bold')
+
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [40]:
+
+
+
+
+
+# 기간별 유입 경로 변화
+df_referrer['period'] = pd.to_datetime(df_referrer['period'])
+
+# 주요 유입 경로 5개 선정
+top_5_referrers = referrer_summary.head(5).index.tolist()
+
+# 기간별, 유입 경로별 집계
+referrer_trend = df_referrer[df_referrer['referrer'].isin(top_5_referrers)].groupby(
+ ['period', 'referrer']
+)['share'].sum().reset_index()
+
+# 시각화
+plt.figure(figsize=(14, 7))
+for referrer in top_5_referrers:
+ data = referrer_trend[referrer_trend['referrer'] == referrer]
+ plt.plot(data['period'], data['share'], marker='o', label=referrer, linewidth=2)
+
+plt.title('주요 유입 경로별 추이 (TOP 5)', fontsize=14, fontweight='bold')
+plt.xlabel('기간')
+plt.ylabel('비중')
+plt.legend()
+plt.grid(True, alpha=0.3)
+plt.xticks(rotation=45)
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6. 종합 인사이트 분석¶
+
+
+
+
+
+
+
+In [41]:
+
+
+
+
+
+print("=" * 80)
+print("종합 인사이트 분석")
+print("=" * 80)
+
+# 1. 카테고리별 인구통계학적 특성 분석
+print("\n[1. 카테고리별 주요 독자층 분석]\n")
+
+# 콘텐츠와 인구통계 데이터 병합
+df_content_demo = df_contents[['article_id', 'category']].merge(
+ df_demo_filtered,
+ on='article_id',
+ how='inner'
+)
+
+# 카테고리별, 연령대별 조회수
+category_age = df_content_demo.groupby(['category', 'age_group'])['views'].sum().reset_index()
+
+# 각 카테고리별 주요 연령대 추출
+for category in df_contents['category'].dropna().unique():
+ cat_data = category_age[category_age['category'] == category].sort_values('views', ascending=False)
+ if len(cat_data) > 0:
+ top_age = cat_data.iloc[0]
+ print(f"{category}: 주요 독자층 = {top_age['age_group']}세 (조회수: {top_age['views']:,})")
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +종합 인사이트 분석 +================================================================================ + +[1. 카테고리별 주요 독자층 분석] + +커버스토리: 주요 독자층 = 19-24세 (조회수: 8,858) +빅카인즈: 주요 독자층 = 19-24세 (조회수: 24) +산업・정책: 주요 독자층 = 19-24세 (조회수: 46) +취재기·제작기: 주요 독자층 = 25-29세 (조회수: 5,083) +기획연재: 주요 독자층 = 19-24세 (조회수: 3,323) +지금 언론계에선: 주요 독자층 = 25-29세 (조회수: 129) +미디어포럼: 주요 독자층 = 13-18세 (조회수: 2,335) +미디어 월드 와이드: 주요 독자층 = 19-24세 (조회수: 2,124) +집중점검: 주요 독자층 = 19-24세 (조회수: 4,556) +재단소식: 주요 독자층 = 25-29세 (조회수: 524) +미디어현장: 주요 독자층 = 19-24세 (조회수: 3,562) +테크: 주요 독자층 = 19-24세 (조회수: 331) +카드뉴스: 주요 독자층 = 13-18세 (조회수: 42) +신문과방송: 주요 독자층 = 25-29세 (조회수: 479) +한국언론진흥재단 소식: 주요 독자층 = 19-24세 (조회수: 25) +독자가 본 언론: 주요 독자층 = 19-24세 (조회수: 61) +미디어비평: 주요 독자층 = 13-18세 (조회수: 204) +신방에서 알려주는: 주요 독자층 = 19-24세 (조회수: 549) +미디어·AI트렌드: 주요 독자층 = 25-29세 (조회수: 2,386) +미디어 人사이드: 주요 독자층 = 25-29세 (조회수: 2,430) +미디어 리뷰: 주요 독자층 = 25-29세 (조회수: 2,058) +글로벌 미디어 현장: 주요 독자층 = 25-29세 (조회수: 1,326) +아이디어스: 주요 독자층 = 25-29세 (조회수: 547) ++
+
+
+
+
+
+
+In [42]:
+
+
+
+
+
+# 2. 인기 콘텐츠의 특성 분석
+print("\n" + "=" * 80)
+print("[2. 인기 콘텐츠의 특성]")
+print("=" * 80)
+
+# 조회수 상위 10% 기사 분석
+threshold = df_contents_with_metrics['views_total'].quantile(0.9)
+top_contents = df_contents_with_metrics[df_contents_with_metrics['views_total'] >= threshold]
+
+print(f"\n상위 10% 기사 (조회수 >= {threshold:.0f}): {len(top_contents)}개")
+
+print("\n[상위 10% 기사의 카테고리 분포]")
+print(top_contents['category'].value_counts())
+
+print("\n[상위 10% 기사의 평균 지표]")
+print(f"평균 조회수: {top_contents['views_total'].mean():,.0f}")
+print(f"평균 좋아요: {top_contents['likes'].mean():,.0f}")
+print(f"평균 댓글수: {top_contents['comments'].mean():,.1f}")
+
+
+
+
+
+
+
+
+
+
+
++================================================================================ +[2. 인기 콘텐츠의 특성] +================================================================================ + +상위 10% 기사 (조회수 >= 545): 175개 + +[상위 10% 기사의 카테고리 분포] +category +커버스토리 40 +미디어현장 23 +취재기·제작기 23 +집중점검 19 +미디어포럼 12 +미디어 人사이드 11 +미디어·AI트렌드 11 +기획연재 9 +미디어 리뷰 6 +미디어 월드 와이드 5 +글로벌 미디어 현장 4 +신방에서 알려주는 4 +아이디어스 3 +테크 2 +재단소식 2 +미디어비평 1 +Name: count, dtype: int64 + +[상위 10% 기사의 평균 지표] +평균 조회수: 1,063 +평균 좋아요: 7 +평균 댓글수: 1.2 ++
+
+
+
+
+
+
+In [43]:
+
+
+
+
+
+# 3. 참여도 분석 (Engagement Rate)
+print("\n" + "=" * 80)
+print("[3. 독자 참여도 분석]")
+print("=" * 80)
+
+# 참여도 = (좋아요 + 댓글수) / 조회수
+df_contents_with_metrics['engagement_rate'] = (
+ (df_contents_with_metrics['likes'] + df_contents_with_metrics['comments']) /
+ df_contents_with_metrics['views_total'].replace(0, np.nan)
+) * 100
+
+# 카테고리별 참여도
+category_engagement = df_contents_with_metrics.groupby('category')['engagement_rate'].mean().sort_values(ascending=False)
+
+print("\n[카테고리별 평균 참여도 (%)]")
+print(category_engagement.round(2))
+
+# 시각화
+plt.figure(figsize=(12, 6))
+category_engagement.plot(kind='barh', color='indianred')
+plt.title('카테고리별 평균 참여도', fontsize=14, fontweight='bold')
+plt.xlabel('참여도 (%)')
+plt.ylabel('카테고리')
+plt.grid(True, alpha=0.3, axis='x')
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
++================================================================================ +[3. 독자 참여도 분석] +================================================================================ + +[카테고리별 평균 참여도 (%)] +category +글로벌 미디어 현장 4.05 +미디어·AI트렌드 3.66 +미디어 리뷰 3.32 +한국언론진흥재단 소식 2.60 +미디어 人사이드 2.54 +신문과방송 2.38 +아이디어스 2.12 +취재기·제작기 1.49 +커버스토리 0.93 +미디어현장 0.71 +미디어포럼 0.68 +재단소식 0.61 +독자가 본 언론 0.47 +기획연재 0.47 +미디어 월드 와이드 0.45 +카드뉴스 0.42 +집중점검 0.42 +산업・정책 0.24 +빅카인즈 0.12 +미디어비평 0.08 +지금 언론계에선 0.05 +테크 0.04 +신방에서 알려주는 0.02 +Name: engagement_rate, dtype: float64 ++
+
+
+
+
+
+
+
+
+
+
+
+
+In [44]:
+
+
+
+
+
+# 4. 유입 경로와 콘텐츠 성과의 관계
+print("\n" + "=" * 80)
+print("[4. 유입 경로별 콘텐츠 성과]")
+print("=" * 80)
+
+# referrer 데이터와 metrics 데이터 병합
+df_referrer_metrics = df_referrer.merge(
+ df_metrics.groupby('article_id')['views_total'].sum().reset_index(),
+ on='article_id',
+ how='left'
+)
+
+# 주요 유입 경로별 평균 조회수
+top_10_refs = referrer_summary.head(10).index
+referrer_performance = df_referrer_metrics[df_referrer_metrics['referrer'].isin(top_10_refs)].groupby(
+ 'referrer'
+)['views_total'].mean().sort_values(ascending=False)
+
+print("\n[주요 유입 경로별 평균 조회수]")
+print(referrer_performance.round(0))
+
+# 시각화
+plt.figure(figsize=(12, 6))
+referrer_performance.plot(kind='barh', color='darkgreen')
+plt.title('유입 경로별 평균 조회수 (TOP 10)', fontsize=14, fontweight='bold')
+plt.xlabel('평균 조회수')
+plt.ylabel('유입 경로')
+plt.grid(True, alpha=0.3, axis='x')
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
++================================================================================ +[4. 유입 경로별 콘텐츠 성과] +================================================================================ + +[주요 유입 경로별 평균 조회수] +referrer +네이버 블로그검색_모바일 819.0 +네이버 통합검색_모바일 788.0 +Bing 778.0 +네이버 통합검색_PC 753.0 +네이버 블로그검색_PC 710.0 +네이버 뷰검색_PC 571.0 +네이버 블로그_모바일 563.0 +네이버 뷰검색_모바일 518.0 +Google 510.0 +네이버 블로그_PC 477.0 +Name: views_total, dtype: float64 ++
+
+
+
+
+
+
+
+
+
+
+
+
+
+In [45]:
+
+
+
+
+
+# 5. 시간대별 트렌드 분석
+print("\n" + "=" * 80)
+print("[5. 시간대별 트렌드 분석]")
+print("=" * 80)
+
+# 월별 성장률 계산
+monthly_stats_sorted = monthly_stats.sort_values('기간')
+monthly_stats_sorted['조회수_성장률'] = monthly_stats_sorted['총_조회수'].pct_change() * 100
+monthly_stats_sorted['좋아요_성장률'] = monthly_stats_sorted['총_좋아요'].pct_change() * 100
+
+print("\n[월별 성장률 (전월 대비 %)]")
+print(monthly_stats_sorted[['기간', '조회수_성장률', '좋아요_성장률']].round(2))
+
+# 시각화
+fig, ax = plt.subplots(figsize=(14, 7))
+ax.plot(monthly_stats_sorted['기간'], monthly_stats_sorted['조회수_성장률'],
+ marker='o', label='조회수 성장률', linewidth=2)
+ax.plot(monthly_stats_sorted['기간'], monthly_stats_sorted['좋아요_성장률'],
+ marker='s', label='좋아요 성장률', linewidth=2)
+ax.axhline(y=0, color='red', linestyle='--', alpha=0.5)
+ax.set_title('월별 지표 성장률', fontsize=14, fontweight='bold')
+ax.set_xlabel('기간')
+ax.set_ylabel('성장률 (%)')
+ax.legend()
+ax.grid(True, alpha=0.3)
+plt.xticks(rotation=45)
+plt.tight_layout()
+plt.show()
+
+
+
+
+
+
+
+
+
+
+
++================================================================================ +[5. 시간대별 트렌드 분석] +================================================================================ + +[월별 성장률 (전월 대비 %)] + 기간 조회수_성장률 좋아요_성장률 +0 2023-07-01 NaN NaN +1 2023-08-01 -14.57 -21.70 +2 2023-09-01 -4.10 -1.20 +3 2023-10-01 32.73 1.83 +4 2023-11-01 10.72 -1.20 +5 2023-12-01 -24.62 -13.94 +6 2024-01-01 -11.74 5.63 +7 2024-02-01 -12.30 3.33 +8 2024-03-01 47.20 -28.39 +9 2024-04-01 16.19 161.26 +10 2024-05-01 20.50 -21.38 +11 2024-06-01 -19.01 -17.54 +12 2024-07-01 -6.34 -1.60 +13 2024-08-01 -17.08 -9.19 +14 2024-09-01 -3.62 -13.10 +15 2024-10-01 22.90 21.23 +16 2024-11-01 12.22 -20.90 +17 2024-12-01 -29.03 69.29 +18 2025-01-01 -25.54 -61.60 +19 2025-02-01 4.84 80.22 +20 2025-03-01 27.96 54.88 +21 2025-04-01 0.85 -11.81 +22 2025-05-01 7.43 -44.20 +23 2025-06-01 -17.93 28.80 +24 2025-07-01 -5.85 8.07 +25 2025-08-01 -21.02 -81.03 ++
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7. 핵심 인사이트 요약¶
+
+
+
+
+
+
+
+In [46]:
+
+
+
+
+
+print("=" * 80)
+print("핵심 인사이트 요약")
+print("=" * 80)
+
+insights = """
+### 📊 신문과방송 독자 데이터 분석 핵심 인사이트
+
+#### 1️⃣ 콘텐츠 성과 분석
+- 전체 기사: 1,746개
+- 분석 기간: 2023년 7월 ~ 2024년 9월
+- 카테고리별로 콘텐츠 선호도와 참여도에 차이 존재
+
+#### 2️⃣ 독자 인구통계학적 특성
+- 연령대와 성별에 따라 콘텐츠 소비 패턴이 다름
+- 특정 연령대가 주요 독자층을 형성
+- 카테고리별로 주요 타겟 독자층이 명확히 구분됨
+
+#### 3️⃣ 유입 경로 분석
+- 네이버, 구글 등 검색 엔진을 통한 유입이 주요 경로
+- 소셜미디어와 블로그를 통한 유입도 상당한 비중
+- 유입 경로별로 독자 참여도에 차이 존재
+
+#### 4️⃣ 참여도 (Engagement) 분석
+- 조회수 대비 좋아요와 댓글 비율로 측정
+- 카테고리별로 참여도 편차가 큼
+- 높은 참여도는 콘텐츠 품질과 독자 관심도를 반영
+
+#### 5️⃣ 시간대별 트렌드
+- 월별로 조회수와 참여도 변동 존재
+- 특정 시기에 독자 관심이 집중되는 패턴 발견
+- 계절성 또는 이슈 기반 트렌드 파악 가능
+
+### 💡 개선 방안 제안
+
+1. **타겟 독자층 맞춤 콘텐츠 기획**
+ - 연령대별, 성별 선호 카테고리를 고려한 콘텐츠 제작
+ - 주요 독자층의 관심사를 반영한 주제 선정
+
+2. **유입 경로 최적화**
+ - 검색 엔진 최적화(SEO) 강화
+ - 소셜미디어 채널별 맞춤 홍보 전략 수립
+ - 참여도가 높은 유입 경로에 리소스 집중
+
+3. **참여도 향상 전략**
+ - 독자 댓글 유도 및 상호작용 강화
+ - 참여도가 높은 콘텐츠 형식 벤치마킹
+ - 독자 피드백을 반영한 콘텐츠 개선
+
+4. **데이터 기반 콘텐츠 전략**
+ - 인기 태그와 키워드를 활용한 콘텐츠 기획
+ - 성과가 좋은 카테고리에 리소스 집중
+ - A/B 테스팅을 통한 최적 콘텐츠 형식 발굴
+"""
+
+print(insights)
+
+
+
+
+
+
+
+
+
+
+
+================================================================================ +핵심 인사이트 요약 +================================================================================ + +### 📊 신문과방송 독자 데이터 분석 핵심 인사이트 + +#### 1️⃣ 콘텐츠 성과 분석 +- 전체 기사: 1,746개 +- 분석 기간: 2023년 7월 ~ 2024년 9월 +- 카테고리별로 콘텐츠 선호도와 참여도에 차이 존재 + +#### 2️⃣ 독자 인구통계학적 특성 +- 연령대와 성별에 따라 콘텐츠 소비 패턴이 다름 +- 특정 연령대가 주요 독자층을 형성 +- 카테고리별로 주요 타겟 독자층이 명확히 구분됨 + +#### 3️⃣ 유입 경로 분석 +- 네이버, 구글 등 검색 엔진을 통한 유입이 주요 경로 +- 소셜미디어와 블로그를 통한 유입도 상당한 비중 +- 유입 경로별로 독자 참여도에 차이 존재 + +#### 4️⃣ 참여도 (Engagement) 분석 +- 조회수 대비 좋아요와 댓글 비율로 측정 +- 카테고리별로 참여도 편차가 큼 +- 높은 참여도는 콘텐츠 품질과 독자 관심도를 반영 + +#### 5️⃣ 시간대별 트렌드 +- 월별로 조회수와 참여도 변동 존재 +- 특정 시기에 독자 관심이 집중되는 패턴 발견 +- 계절성 또는 이슈 기반 트렌드 파악 가능 + +### 💡 개선 방안 제안 + +1. **타겟 독자층 맞춤 콘텐츠 기획** + - 연령대별, 성별 선호 카테고리를 고려한 콘텐츠 제작 + - 주요 독자층의 관심사를 반영한 주제 선정 + +2. **유입 경로 최적화** + - 검색 엔진 최적화(SEO) 강화 + - 소셜미디어 채널별 맞춤 홍보 전략 수립 + - 참여도가 높은 유입 경로에 리소스 집중 + +3. **참여도 향상 전략** + - 독자 댓글 유도 및 상호작용 강화 + - 참여도가 높은 콘텐츠 형식 벤치마킹 + - 독자 피드백을 반영한 콘텐츠 개선 + +4. **데이터 기반 콘텐츠 전략** + - 인기 태그와 키워드를 활용한 콘텐츠 기획 + - 성과가 좋은 카테고리에 리소스 집중 + - A/B 테스팅을 통한 최적 콘텐츠 형식 발굴 + ++
+
+
+
+
+
+
+
+In [ ]:
+
+
+
+
+
+# 분석 결과를 텍스트 파일로 저장
+output_file = r'c:\Users\korea\Desktop\dacon_broadcast_paper\analysis_insights.txt'
+
+with open(output_file, 'w', encoding='utf-8') as f:
+ f.write(insights)
+
+print(f"\n✓ 인사이트가 저장되었습니다: {output_file}")
+