時系列パート(基礎編:データ可視化の基礎)#
ここでは,カフェの顧客データ(cafe_customers.csv)を使用してデータ可視化のスキルを学習します.
必要なライブラリのインポート#
matplotlib.pyplot (plt)
役割: 基本的なグラフ作成・細かいカスタマイズ
特徴: 低レベルAPI,完全制御可能,論文品質の図表作成に適用
用途: 軸の詳細設定,複数グラフの配置,出版用図表
seaborn (sns)
役割: 統計的可視化・美しいデフォルトスタイル
特徴: 高レベルAPI,統計情報の自動計算・表示
用途: 探索的データ分析,プレゼンテーション用グラフ
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 警告メッセージを非表示にするライブラリ・設定
import warnings
warnings.filterwarnings('ignore')
データの読み込みと前処理#
# データの読み込みと前処理
df = pd.read_csv('../data/raw/cafe_customers.csv')
# 時系列処理
df['Timestamp'] = pd.to_datetime(df['Timestamp'])
df['Date'] = df['Timestamp'].dt.date
df['Hour'] = df['Timestamp'].dt.hour
df['DayOfWeek'] = df['Timestamp'].dt.dayofweek
df['WeekdayName'] = df['Timestamp'].dt.day_name()
df['IsWeekend'] = df['DayOfWeek'].isin([5, 6])
df['DayType'] = df['IsWeekend'].map({True: 'Weekend', False: 'Weekday'})
# TimeStampをインデックスに設定
df_indexed = df.set_index('Timestamp')
時系列データの可視化#
グラフスタイルとサイズの最適化#
# グラフのサイズとスタイル設定
plt.style.use('seaborn-v0_8')
plt.rcParams['figure.figsize'] = (12, 8)
1時間ごとの客数推移を可視化#
# 1時間ごとの客数推移を作成
hourly_customers = df_indexed.resample('H')['Customers'].sum()
print(hourly_customers.head())
# 可視化(折れ線グラフ)
plt.figure(figsize=(15, 6))
plt.plot(hourly_customers.index, hourly_customers.values, linewidth=1, alpha=0.8)
plt.title('Customer Count Over Time (Hourly)', fontsize=16, fontweight='bold')
plt.xlabel('Date', fontsize=12)
plt.ylabel('Number of Customers', fontsize=12)
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
1週間ごとの客数推移を可視化#
# 1週間ごとの客数推移を作成
weekly_customers = df_indexed.resample('W')['Customers'].sum()
print(weekly_customers.head())
# 可視化(折れ線グラフ)
plt.figure(figsize=(15, 6))
plt.plot(weekly_customers.index, weekly_customers.values, marker='o', linewidth=2, markersize=6, color='green')
plt.title('Weekly Customer Count', fontsize=14, fontweight='bold')
plt.xlabel('Date')
plt.ylabel('Weekly Total Customers')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
時間帯別分析の可視化#
棒グラフ(Bar Chart)と 散布図(Scatter Plot)の使い分け#
棒グラフの特徴:
カテゴリ別比較: 時間帯(離散値)ごとの平均値比較に最適
視覚的インパクト: 差異を明確に表現
統計的意味: 各時間帯の代表値(平均)を強調
散布図の特徴:
生データの分布: 実際のデータ点の散らばりを表示
異常値検出: 平均から大きく外れる値を発見
分散の把握: データのばらつき具合を視覚的に理解
# 時間帯別の平均客数を作成
hourly_stats = df.groupby('Hour')['Customers'].mean()
print(hourly_stats.head())
# 可視化(棒グラフ)
plt.figure(figsize=(15, 6))
plt.bar(hourly_stats.index, hourly_stats.values, color='skyblue', alpha=0.8, edgecolor='navy', linewidth=1)
plt.title('Average Customer Count by Hour of Day', fontsize=16, fontweight='bold')
plt.xlabel('Hour of Day')
plt.ylabel('Average Number of Customers')
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.show()
# 可視化(散布図)
plt.figure(figsize=(15, 6))
plt.scatter(df['Hour'], df['Customers'], alpha=0.5, s=10)
plt.title('Customer Count vs Hour of Day')
plt.xlabel('Hour of Day')
plt.ylabel('Number of Customers')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
曜日別分析の可視化#
多次元時系列データの可視化戦略#
この分析では曜日×時間帯の2次元データを以下の手法で可視化します:
1. 多系列折れ線グラフ
目的: 曜日ごとの時間変化パターンを同時比較
利点: 各曜日の特徴的な変動を一目で把握
2. ヒートマップ
目的: 全体パターンの俯瞰的把握
利点: 「平日の午後」「週末の夜」など具体的なシーンでの値を直観的に理解
# 曜日×時間帯の客数平均を作成
hourly_by_day = df.groupby(['WeekdayName', 'Hour'])['Customers'].mean().unstack(level=0)
hourly_by_day.head()
# 可視化(折れ線グラフ)
plt.figure(figsize=(15, 6))
for day in hourly_by_day.columns:
plt.plot(hourly_by_day.index, hourly_by_day[day], marker='o', linewidth=2, label=day, alpha=0.8)
plt.title('Customer Count by Hour for Each Day of Week', fontsize=16, fontweight='bold')
plt.xlabel('Hour of Day')
plt.ylabel('Average Number of Customers')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 可視化(ヒートマップ)
plt.figure(figsize=(15, 6))
sns.heatmap(hourly_by_day.T, annot=True, fmt='.1f', cmap='YlOrRd', cbar_kws={'label': 'Average Customers'})
plt.title('Customer Count Heatmap: Day of Week vs Hour', fontsize=16, fontweight='bold')
plt.xlabel('Hour of Day')
plt.ylabel('Day of Week')
plt.tight_layout()
plt.show()
箱ひげ図による営業時間のみの顧客数の可視化#
箱ひげ図(Box Plot)の統計学的意義#
箱ひげ図は5数要約(最小値,第1四分位数,中央値,第3四分位数,最大値)を視覚化し,分布の特徴を包括的に把握できます:
箱ひげ図から読み取れる情報:
中央値: データの中心傾向(平均値より外れ値に頑健)
四分位範囲(箱の高さ): データの50%が含まれる範囲
ひげの長さ: データの広がり具合
外れ値: 異常に高い/低い値の存在
# 営業時間(7時~21時)の客数分布を作成
business_hours_df = df[(df['Hour'] >= 7) & (df['Hour'] <= 21)]
hourly_groups = [business_hours_df[business_hours_df['Hour'] == h]['Customers'].values for h in range(7, 22)]
# 可視化(箱ひげ図)
plt.figure(figsize=(15, 6))
plt.boxplot(hourly_groups, labels=range(7, 22))
plt.title('Customer Count Distribution by Hour')
plt.xlabel('Hour of Day')
plt.ylabel('Number of Customers')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
演習問題#
演習1: 営業時間(7-21時)の時間帯別平均客数を可視化してください#
💡ヒント:
営業時間(7:00-21:00)でフィルタリング
時間帯別の平均客数を計算
# 回答欄
演習2: 曜日別の平均客数を可視化してください#
# 回答欄