LinearRegressionとRandomForestを使って売上予測の精度を出す
今回はkaggle内で提供されているデータセット「pizza_place_sales」を使って2モデルで予測の精度を測ってみました。
LinearRegressionモデルだと99%という数字が出てしまったので、特徴量の作成に課題を見つけた分析でした。
学習を始めて2ヶ月強経過しますが、ここまで一人でできるようになったため記録として記事を残します。
まだ分からないことだらけですが、自己研鑽を積んでスキルアップを目指して行きたいと思います。
#ライブラリのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
#csvファイルの読み込み
train = pd.read_csv("/kaggle/input/pizza-place-sales/pizzaplace.csv")
print(len(train))
#データ先頭5行を出力
train.head()
このデータ、かなり綺麗なデータで手直しが少なさそうな印象です。
#データ全体の要約を確認
train.info()
#カラム"date"をdatetime型に変更
train["date"] = pd.to_datetime(train["date"], format="%Y-%m-%d")
#行名に割り当て
train = train.set_index("date", drop=True)
#時系列データのリサンプリング
train_month = train["price"].resample("M").sum()
#月別に売上推移をグラフにプロット
train_month.plot()
#商品別の売上をサイズ毎にプロット
plt.figure(figsize=(50,10))
sns.barplot(x="name", y="price", hue="size", data=train)
商品名が多いためデフォルトでグラフが表示しきれず、、、拡大して傾向を確認しました。
#商品別に売上をプロット
plt.figure(figsize=(50,10))
sns.boxplot(x="name", y="price", data=train)
#商品タイプ別に売上をプロット
plt.figure(figsize=(50, 10))
sns.barplot(x="type", y="price", hue="name", data=train)
#分析に不要と思われるカラムを削除
train_df = train.drop(["Unnamed: 0", "id", "time"], axis=1)
train_df.head()
#欠損値の確認
train_df.isnull().sum()
#加工したデータ要約を確認
train_df.info()
#オブジェクト型のデータをダミー変数にカテゴライズ
train_df = pd.get_dummies(train_df, columns=["size", "type", "name"])
train_df.head()
#回帰モデルと評価するための決定係数をインポート
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
#検証用データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(train_df.drop(["price"], axis=1),
train_df["price"], test_size=0.2, shuffle=False)
#回帰分析モデルを準備
model = LinearRegression()
#モデルの学習
model.fit(X_train, y_train)
#評価
pred = model.predict(X_test)
y_pred = r2_score(y_test, pred)
print(pred)
print(y_pred)
99パーセントの結果が出たんですがこれでは結果が高すぎて信憑性が無いため、ランダムフォレストで再度精度を予測してみます。
def yyplot(pred, y_pred):
yvalues = np.concatenate([pred.flatten(), y_pred.flatten()])
ymin, ymax, yrange = np.amin(yvalues), np.amax(yvalues), np.ptp(yvalues)
fig = plt.figure(figsize=(8, 8))
plt.scatter(pred, y_pred)
plt.plot([ymin - yrange * 0.01, ymax + yrange * 0.01], [ymin - yrange * 0.01, ymax + yrange * 0.01])
plt.xlim(ymin - yrange * 0.01, ymax + yrange * 0.01)
plt.ylim(ymin - yrange * 0.01, ymax + yrange * 0.01)
plt.xlabel('y_observed', fontsize=24)
plt.ylabel('y_predicted', fontsize=24)
plt.title('Observed-Predicted Plot', fontsize=24)
plt.tick_params(labelsize=16)
plt.show()
return fig
np.random.seed(0)
pred = np.random.normal(size=(1000, 1))
y_pred = pred + np.random.normal(scale=0.3, size=(1000, 1))
fig = yyplot(pred, y_pred)
この図は参考までに試したものです。点が中央に集まればより良い予測が出ている物を測るためのプロット図とのことです。
#学習モデルのインポート
from sklearn import tree
#モデルの準備とハイパーパラメータの調整
model = tree.DecisionTreeRegressor(max_depth=3, random_state=0)
#モデルの学習
model.fit(X_train, y_train)
#モデルの評価
pred = model.predict(X_test)
y_pred = model.score(X_test, y_test)
print(pred)
print(y_pred)
plt.figure(figsize=(50,20))
tree.plot_tree(model, feature_names=None, fontsize=10)
結果は91%と回帰モデルより少し信憑性が持てました。max_depthの値を上限することで予測精度が変わってくるところが面白いです。
これは参考までにランダムフォレストでどのような計算がされているのかを興味本位でプロットしたものです。
今回のデータは非常に綺麗で、欠損値もなく加工処理も少なかったため比較的簡単に分析が行えました。
予測精度が高すぎるのが少し気がかりではありますので次は”time”のカラムも説明変数に加えて特徴量を作成し、分析してみたいと思います。
良い特徴量が作成できるよう色んなデータを扱うのが課題です。
未経験から、しかも40代でITエンジニアを目指して時間が経ちますが転職活動はなかなかうまくいきません。
もっとスキルを磨き、企業様にアピールできる強みを増やして行きたいと思います。
花粉の季節になりましたね。
皆様、体調にはお気をつけて良い日々をお過ごしください。
ご覧いただきありがとうございました。