LoginSignup
0
0

More than 1 year has passed since last update.

新規感染者数とコロナ特需サービスの回帰分析(初心者)

Last updated at Posted at 2021-09-27

この記事について

Aidemyさんの卒業ブログのネタとして記載しているものです。
覚えたての分析手法を実践することが目的のため、データの収集方法、分析方法はともに雑です。参考程度に見て頂ければと思います。

目的

コロナ禍における巣ごもり需要が、コロナ危機度(新規感染者数)に応じてどう変化したかを可視化する。(瞬発的な需要を見るイメージ)
コロナ特需を受けたサービスとしては"Uber_eats","Amazon_prime","Netflix","teams","Slack"をサンプルとしたが、当然のことならが需要量は公開されていないため、ここではgoogle trendの人気度を代替えとして利用しています。

分析環境

Google Colab

データについて

巣ごもり需要のサンプル
google trendで調べた"Uber_eats","Amazon_prime","Netflix","teams","Slack"
コロナ危機度
厚生労働省のオープンデータから入手した新規感染者数を危機度として扱う

image.png

※参考として、緊急事態宣言下、オリパラ期間はカテゴリデータ("emergency"カラム)を作ってます。緊急事態宣言下:1、オリパラ期間:2、それ以外:0
※期間は2020/09~2021/09、データ間隔はgoogle trendの仕様により1週間単位

試した分析手法

主成分分析(次元削減)
線形回帰(多項式)

分析の流れ

  1. "Uber_eats","Amazon_prime","Netflix","teams","Slack"を次元削減し、1次元データに圧縮(目的変数)
  2. 上記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()

image.png

固有値/固有ベクトル算出
今回は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)

image.png

次元削減とデータ可視化
次元削減したデータ(目的変数)をデータフレームに追加し、"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()

image.png

回帰分析

前述の散布図から、回帰線が直線にはならなそうなので、多項式として分析。

こんなデータから推測するのもよろしくないですが、
新規感染者数が増えても、今回の対象サービスに瞬発的な需要が生まれる感じではないようです。
長いコロナ生活の中で需要が一巡し、継続的な需要はあれど、瞬発的な需要増にはならない、、という感じでしょうか。

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_)

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0