#この記事について
Aidemyさんの卒業ブログのネタとして記載しているものです。
覚えたての分析手法を実践することが目的のため、データの収集方法、分析方法はともに雑です。参考程度に見て頂ければと思います。
#目的
コロナ禍における巣ごもり需要が、コロナ危機度(新規感染者数)に応じてどう変化したかを可視化する。(瞬発的な需要を見るイメージ)
コロナ特需を受けたサービスとしては"Uber_eats","Amazon_prime","Netflix","teams","Slack"をサンプルとしたが、当然のことならが需要量は公開されていないため、ここではgoogle trendの人気度を代替えとして利用しています。
#分析環境
Google Colab
#データについて
巣ごもり需要のサンプル
google trendで調べた"Uber_eats","Amazon_prime","Netflix","teams","Slack"
コロナ危機度
厚生労働省のオープンデータから入手した新規感染者数を危機度として扱う
※参考として、緊急事態宣言下、オリパラ期間はカテゴリデータ("emergency"カラム)を作ってます。緊急事態宣言下:1、オリパラ期間:2、それ以外:0
※期間は2020/09~2021/09、データ間隔はgoogle trendの仕様により1週間単位
#試した分析手法
主成分分析(次元削減)
線形回帰(多項式)
#分析の流れ
- "Uber_eats","Amazon_prime","Netflix","teams","Slack"を次元削減し、1次元データに圧縮(目的変数)
- 上記1のデータと、"Newly confirmed cases"で多項式線形回帰
※そのまま重回帰分析していない理由は、可視化したかった、、というだけです
#主成分分析
データの傾向把握
相関行列/ヒートマップによりデータの傾向を確認。
このデータをそのまま回帰分析する訳ではないので問題ないと思いますが、多重共線性なるものがよろしくない、、と言う話もあるので、相関の強さを念のため確認。
今回は問題なさそうです。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 標準化
df_tor_s = (df_tor - df_tor.mean(axis=0)) / df_tor.std(axis=0)
# 相関行列
df_tor_coef = np.corrcoef(df_tor_s.values.T)
sns.heatmap(df_tor_coef, annot=True, xticklabels=df_tor.columns, yticklabels=df_tor.columns, cmap="Blues")
plt.show()
固有値/固有ベクトル算出
今回は1次元データに変換したいので、ヒストグラムの4の固有ベクトルを利用します。
固有値より4には全体の36%の分散が含まれていますが、、1次元に次元削減すると60%以上の分散情報が消えてしまいますね。。
う~ん、可視化のためとは言え、これで良いのか疑問ですが続けます。
eigvals, eigvecs = np.linalg.eigh(df_tor_coef)
plt.bar(range(5), eigvals)
plt.title("distribution of eigvals")
plt.xlabel("index")
plt.ylabel("eigvals")
plt.show()
eigvals / np.sum(eigvals)
次元削減とデータ可視化
次元削減したデータ(目的変数)をデータフレームに追加し、"Newly confirmed cases"を説明変数とした散布図を作成。
プロットの色は、赤:緊急事態下、青:オリパラ期間、灰:その他
感覚もっと右肩上がりになると思ってましたが、そうでもないようです。
本データが2020年9月からのデータと言う事もあり、消費者が状況に慣れたことにより、危機度が高くなっても瞬発的に需要が上がることはなかった、、可能性はあるかな。。
# 次元削減した結果をデータフームに追加
df_merge["main_ingredient"] = df_tor_s.dot(eigvecs[:,-1])
plt.figure(figsize=(8,4))
plt.scatter(df_merge.loc[df_merge["emergency"]==0,"Newly confirmed cases"],
df_merge.loc[df_merge["emergency"]==0,"main_ingredient"],
c="grey", alpha=0.5)
plt.scatter(df_merge.loc[df_merge["emergency"]==1,"Newly confirmed cases"],
df_merge.loc[df_merge["emergency"]==1,"main_ingredient"],
c="tomato", alpha=0.5)
plt.scatter(df_merge.loc[df_merge["emergency"]==2,"Newly confirmed cases"],
df_merge.loc[df_merge["emergency"]==2,"main_ingredient"],
c="skyblue", alpha=0.5)
#plt.scatter(df_merge["Newly confirmed cases"], df_merge["main_ingredient"], c=df_merge["emergency"])
plt.show()
#回帰分析
前述の散布図から、回帰線が直線にはならなそうなので、多項式として分析。
こんなデータから推測するのもよろしくないですが、
新規感染者数が増えても、今回の対象サービスに瞬発的な需要が生まれる感じではないようです。
長いコロナ生活の中で需要が一巡し、継続的な需要はあれど、瞬発的な需要増にはならない、、という感じでしょうか。
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import KFold, train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import PolynomialFeatures
deg = PolynomialFeatures(degree=2)
X_train_d2 = deg.fit_transform(X_train.values.reshape(-1, 1))
model.fit(X_train_d2, y_train)
X_test_d2 = deg.fit_transform(X_test.values.reshape(-1, 1))
pred = model.predict(X_test_d2)
np.sqrt(sum((y_test.values - pred)**2))
X_ = deg.fit_transform(np.arange(0,170000,1000).reshape(-1,1))
line = model.predict(X_)