【プログラミング初心者】が売上を予測してみました (vol.4:データ整理編)
この記事は、週毎の売上分析、予測に気象庁のデータを加えることで、予測精度が上がるかどうかをまとめたものです。
内容は2部構成になっています。
vol.4 : データ整理編
vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル
です。
これまでに
「【プログラミング初心者】が売上を予測してみました」
では週毎の売上分析・予測を、
vol.1 : データ整理編
vol.2 : 時系列解析編
vol.3 : 回帰編
3部構成でまとめており、
「【プログラミング初心者】が在庫を予測してみました」
では在庫状況を分析し、未来の在庫を予測しています。
今回は「【プログラミング初心者】が売上を予測してみました」
のvol.1〜vol.3 でまとめた週毎の売上分析・予測を改良し、気象庁のデータを加えることで、予測の精度が上がるか検証します。
今回は「Vol.4 : データ整理編」です。
【売上データクレンジング・成形】
売り上げexcelデータの読み込み
まずは2018年から2020年までの3年分の週毎の売上データを読み込んでいきます。
試しに2018年度 MD1週のデータを表示します。
import pandas as pd
filepass="2018年度売上週報/MD1週売上週報.xlsx"
df= pd.read_excel("/content/drive/MyDrive/2018年度売上週報2/MD1週売上週報.xlsx")
df = df.iloc[:,1:]
df.head(10)
箇所を指定して再度表示します。
df2=df[4:6]
df2
'zMN'店舗のデータだけを抽出します。
targetname=['zWM']
columns_name=df2.columns[1]
df2.columns=["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績", "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8","Unnamed: 9"]
df2= df2.query("tar in @targetname")
df2
1列目は不要なので、削除します。
df3=df2.drop("Unnamed: 0", axis=1)
df3
'zMN'店舗の週実績の列のみを取り出します。
df = pd.DataFrame(columns=['MD週','zWM'])
df.loc[0,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
df
MD週 zWM
0 2018MD1 18820
続けて2018年MD2週目以降、2019、2020年度の売上データも読み込んでいきます。
import pandas as pd
import glob
targetfolder=["2018年度売上週報2", "2019年度売上週報2", "2020年度売上週報2"]
df_all = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
targetfiles=glob.glob(folder +"/*.xlsx")
print(targetfiles)
for filename in targetfiles:
filepass=filename
print(filepass)
df= pd.read_excel(filepass)
df = df.iloc[:,1:]
df2=df[:10]
try:
df2.columns=["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績", "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
except:
col = ["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績", "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
diff = len(df2.columns) - len(col)
for i in range(diff):
col.append("")
df2.columns=col
df2= df2.query("tar in @targetname")
df3=df2.drop("Unnamed: 0", axis=1)
df_all.loc[counter,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
counter+=1
並べ替え
抜けている部分がないか確認するため、ソートで昇順に並べ替えます。
df_all.sort_values(by="MD週")
df_all
欠損値の確認
昇順に並べ替えをしつつ、欠損値を確認します。
import glob
targetfolder=["2018年度売上週報2", "2019年度売上週報2", "2020年度売上週報2"]
df_all = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
#targetfiles=glob.glob(folder +"/*.xlsx")
#print(targetfiles)
for num in range(53):
filepass=folder+"/MD{}週売上週報.xlsx".format(num)
try:
df= pd.read_excel(filepass)
df = df.iloc[:,1:]
print(filepass)
df2=df[:10]
try:
df2.columns=["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績", "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
except:
col = ["Unnamed: 0", "tar", "Unnamed: 2", "MD1週", "週実績", "Unnamed: 5", "Unnamed: 6", "Unnamed: 7", "Unnamed: 8", "Unnamed: 9"]
diff = len(df2.columns) - len(col)
for i in range(diff):
col.append("")
df2.columns=col
df2= df2.query("tar in @targetname")
df3=df2.drop("Unnamed: 0", axis=1)
df_all.loc[counter,:]=[filepass.split("年")[0]+filepass.split("/")[1].split("週売")[0]]+list(df3.loc[:,"週実績"])
counter+=1
except:
print("/MD{}週売上週報 はありませんでした".format(num))
csvデータに変換します。
df_all.to_csv("tmp.csv")
欠損値の補完
csvデータを読み込みます。
import pandas as pd
df= pd.read_csv("tmp.csv", index_col=0)
df
欠損値を補完するため、各列ごとに平均や標準偏差、最大値、最小値、最頻値などの要約統計量を取得します。
df.describe()
今回は平均値で補完します。
mean_data=df.describe().loc["mean"]
mean_data
zWM 16789.626984
Name: mean, dtype: float64
欠損している部分に平均値を補完します。
import glob
targetfolder=["2018", "2019", "2020"]
new_df = pd.DataFrame(columns=['MD週','zWM'])
counter=0
targetname=['zWM']
for folder in targetfolder:
#targetfiles=glob.glob(folder +"/*.xlsx")
#print(targetfiles)
for num in range(1, 53):
tmp=folder+ "MD"+ str(num)
data=df.query("MD週==@tmp")
if len(data) == 0:
new_df.loc[counter,:]= [tmp]+ list(mean_data)
else:
new_df.loc[counter,:]= data.values
counter+=1
new_df
list(data.values)
[array(['2020MD52', 11638], dtype=object)]
csvデータの作成
csvデータに変換します。
new_df.to_csv("/content/drive/MyDrive/new_df_zWM.csv")
【気象庁データクレンジング・成形】
気象庁のCSVデータ読み込み
続けて気象庁のCSVデータを読み込んでいきます。
import pandas as pd
df= pd.read_csv("data.csv", encoding='cp932', header=2)
df
0行目と1行目は不要なため、削除します。
df= df.drop([0,1])
df
今回欲しいデータ、"年月日", "降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"だけを取り出します。
target_column= ["年月日", "降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"]
for col in df.columns:
if col in target_column:
pass
else :
df= df.drop(col, axis=1)
df
csvデータに変換します。
df.to_csv("wether.csv")
週毎の売り上げデータとデータ数を揃えるため、日毎の気象データを週毎のデータに変更します。
df= pd.read_csv("wether.csv", index_col=0)
df= df.reset_index(drop=True)
df= df.drop(df.index[-7:])
df
"降水量の合計(mm)", "最高気温(℃)", "最低気温(℃)"を週毎の平均数値にします。
new_df = pd.DataFrame(columns=df.columns[1:])
counter=0
for i in range(0, len(df), 7):
tmp= df.iloc[i : i+7, 1: ].describe()
new_df.loc[counter,:]= tmp.loc["mean"]
counter+=1
new_df
csvデータに変換します。
new_df.to_csv("wether_week.csv")
【売り上げCSVデータと気象庁CSVデータの統合】
データ読み込み
作成した、売り上げCSVデータと気象庁CSVデータを統合します。
まずは売上CSVデータを読み込んでいきます。
import pandas as pd
df_s= pd.read_csv("new_df_zWM.csv", index_col=0)
df_s
続けて気象庁のCSVデータを読み込んでいきます。
import pandas as pd
df_w= pd.read_csv("wether_week.csv", index_col=0)
df_w
売り上げCSVデータと気象庁CSVデータを統合します。
df= pd.concat([df_s, df_w], axis=1)
df
csvデータの作成
csvデータに変換します。
df.to_csv("sales_wether.csv")
前回必要なデータを揃えるのに、約10時間、データの整形に約10時間かかりましたが、回数を重ねることで必要なデータの見極めがスムーズになり、2時間程度で整えることができました。
データの読み込みを始める前に、ある程度データの中身を確認し、あらかじめ整えておくことでスムーズに進められてよかったです。
「【プログラミング初心者】が売上を予測してみました(vol.4:データ整理編)」はこちらで終わりです。
続きは「vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル」です。こちらもぜひご覧くださいませ。
もしよければ、「【プログラミング初心者】が売上を予測してみました(vol.1 : データ整理編)、(vol.2 : 時系列解析編)、(vol.3 : 回帰編)」
「【プログラミング初心者】が在庫を予測してみました 」もあわせてぜひご覧くださいませ。
最後まで読んでいただき、ありがとうございました。