NEWS
ニュース

売上予測はじめてみます ~重回帰分析~

2019.12.10

こんにちは、はじまりビジネスパートナーズ共同代表の中小企業診断士 増田です。今回は”IT/データ分析”をテーマにしたいと思います。

前回、売上実績サンプルデータについて単回帰分析を用いて売上予測を行いましたが結果はいまいちでした。売上実績サンプルデータは季節性がありそうなので、今回は、季節性の変数を1つ加えて重回帰分析を用いて将来の売上予測をしてみたいと思います。

まずは、いつも同様、Google Colaboratoryへアクセスし、Google DriveのマウントとMatplotlibの日本語表示のためのフォントインストールおよびキャッシュの削除、売上実績サンプルエクセルデータのDataframeへの読み込みまでを済ませておきます。

from google.colab import drive
drive.mount(‘/content/drive’)
!apt-get -y install fonts-ipafont-gothic
!rm /root/.cache/matplotlib/fontlist-v310.json

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
import matplotlib
%matplotlib inline

filepath=”/content/drive/My Drive/Colab Notebooks/売上実績sample.xlsx”
df_a = pd.read_excel(filepath,usecols=[0,1,2])
df_a[‘年月’]=df_a[‘年’].astype(str) + ‘/’ + df_a[‘月’].astype(str)
df_a = df_a.loc[:,[‘年月’,’売上高’]]

重回帰分析とは?

重回帰分析自体の手法についても、文献やネット上にいっぱい情報があるため、ここでも利用にフォーカスし、詳細な内容は割愛したいと思いますが、簡単には各データと二乗誤差が最小となるy=a1x1+a2x2+…+bを見つける形になります。最小なので、aとbそれぞれの偏微分が0となるa(傾き)とb(切片)を求めればよさそうなのは単回帰分析と同じですね。
今回は、2変数になるので、y=a1x1 + a2x2 + bのイメージになります。

必要なライブラリのインポート

必要なライブラリは単回帰分析と同じです。前回同様必要なライブラリをインポートし、インスタンスを作っておきます。

from sklearn import linear_model
clf = linear_model.LinearRegression()

予測モデル作成までの事前処理

前回の単回帰同様、df_a.iloc[:,1]は、df_aデータフレームの全ての行(:)、1列目(実際には0から始まるので2列目)を意味しています。raw_dataには売上実績データ自体がすべて入るイメージです。
今回も、日付を相対的に扱いたいので、dateutil.realativedeltaライブラリのrelativedeltaクラスをインポートします。X軸データは0,1,2,・・・にするように変換して今回は、numpy array型の変数df_1に一旦格納しています。Y軸データ(売上実績データ)は前回同様変数raw_dataに格納しています。今回も日付は後で相対的に足し算、引き算できるようにdatetime型に変換してu_dateymに格納しています。今回は、周期性を考慮するため、d_cycleで周期を定義して、df_1_1はdf_1をd_cycleで割って、その余りを入れています。最終的にdf_1は0,1,2,,,,101と0,1,2,,,11,0,1,2,,,の2列の行列(x1とx2のイメージ)になります。

# Further Future用のデータ数
f_future_d = 70
# データサイクル
d_cycle = 12

from dateutil.relativedelta import relativedelta
raw_data = df_a.iloc[:,1].astype(‘float32’)
u_dateym = pd.to_datetime(df_a.iloc[:,0])
df_1 = np.array(range(len(raw_data)))
df_1_1 = df_1 % d_cycle
df_l = np.concatenate([np.reshape(df_1,(-1,1)), np.reshape(df_1_1,(-1,1))], axis=1)

モデルの作成

単回帰と違い、fitにはdf_1(x1とx2のNumpy行列)を渡していますが、今回もresultにモデルの結果が入ります。空のリストfurtureを用意して、予測の70ヶ月分の売上データを入れます。clf.coefにはモデルの傾き、clf.interceptにはモデルの切片が入っています。これは単回帰と同じです。

result = clf.fit(df_l, raw_data)
future = []
for i in range(len(raw_data)+1, len(raw_data)+ f_future_d + 1):
    future = np.append(future, clf.coef_[0] * i + clf.coef_[1] * ( i % d_cycle ) + clf.intercept_)

clf.coef_を見てみると傾きはarray([-288269.93207168,  644226.48203268])、切片clf.intercept_は61207023.925073534になっていました。決定係数clf.score(df_1,raw_data)は0.449105685867207で単回帰の0.4199380391267902より若干精度はあがっていますが、1には程遠く、こちらもあまり精度は良くなさそうです。

いよいよグラフ化

plt.rcParams[‘font.family’] = ‘IPAPGothic’
plt.xticks(np.arange(0, len(u_dateym) + 1, 12),rotation=70)
plt.title(“売上サンプル”, fontsize = 16)
plt.xlabel(‘年月’)
plt.ylabel(‘売上高(億円)’)

plt.plot(u_dateym.iloc[0:dm_num].dt.strftime(‘%Y/%m’), df_a[‘売上高’], color=”b”, label=’売上実績’)
plt.plot(range(0, len(raw_data)), clf.predict(df_l), color=”r”, label=”分析結果”)
plt.plot(pd.Series(data=further_date).dt.strftime(‘%Y/%m’), future, color=”y”, label=”予測”)
plt.legend()
plt.savefig(“predict-juukaiki.png”)
plt.show()
plt.close()

出力結果はこちらです。

こちらも単回帰分析同様、今までの売上実績の傾向をざっくり掴むのには使えそうですが、それを用いて今後の売上を予測していますって言うのは見た目的にも、値的にもちょっと無理がありそうです。やはり単純な回帰分析で季節性のある時系列データの予測を行うのは無理があるようです。売上実績サンプルデータは時系列で季節性があるので、次回は季節性の時系列分析手法である、SARIMA(季節自己回帰和分移動平均)を使って売上予測をしてみたいと思います。

はじまりビジネスパートナーズは株式会社ショッパーインサイトと提携して、データマーケティング提案も行なっております。データマーケティングにご興味がある方、活用したいと考えておられる方はこちらからご連絡ください!

一覧へ戻る
Contact

お問い合わせ

まずはお気軽にお問い合わせください。