Amazon SageMakerでpythonデータサイエンス入門その2

はじめに

本稿は Amazon SageMakerでPythonデータサイエンス入門 の連載記事になります。

その1. Amazon SageMaker の環境構築、事前準備、基礎分析と可視化について
その2. 線形回帰を用いたお弁当の売り上げ予測  ←【本稿】
その3. 決定木を用いた銀行の顧客ターゲティング

以下の Udemy のコースをベースに記事を作成しています。

【ゼロから始めるデータ分析】 ビジネスケースで学ぶPythonデータサイエンス入門

本稿の内容

  • 線形回帰(単回帰、重回帰分析)を用いたお弁当の売り上げ予測
  • 特徴量(説明変数)の作成

予測とは

データを基にある値がどのような値になるかを推定することです。
予測を行うには予測対象と予測を行う上で有用なデータが必要となります。
分析業務では予測対象を目的変数、有用なデータを説明変数と言う場合が多いです。

また本稿では線形回帰を利用したお弁当の売上予測を行います。

線形回帰

回帰とはデータから適する関数を抽出する方法のことです。
線形回帰は回帰分析の手法の中で1次関数を利用して予測モデルを導出する手法です。

線形回帰を用いたお弁当の売り上げ予測

今回は skit-learn を用いて、線形回帰(単回帰分析、重回帰分析)を行います。

単回帰分析編

まずは、単回帰分析(説明変数が1つ)で、お弁当の売り上げを予測します。

  • その1で作成した case1 フォルダーに新しい notebook を conda_python3 で作成してください。

モジュールのインポートと設定

データ(csvファイル)の読み込み

  • trainの先頭行を確認しておきましょう。

実行結果
<img width=”467″ alt=”01.png” src=””>

説明変数と目的変数の用意

  • 説明変数は train から temperature を選択し、変数 trainX に代入します。
  • 目的変数は train から y を選択し、変数 y に代入します。

  • test からも同じ説明変数の temperature を選択し、変数名を testX に代入します。

  • 説明変数のデータの形を整えます。
    ※単回帰の場合のみ必要な操作となります。

回帰モデルの作成

  • 回帰モデルの箱を作る。
    モデルを作成するために用いる手法を変数(モデルの箱)に覚えさせます。
    今回は model1 という変数にLinearRegression(線形回帰)という手法を覚えさせます。

  • 単回帰モデルの作成
    ()の中に、説明変数、目的変数の順番に書くことで、 model1 に格納されている手法でモデルを作成します。

  • 作ったモデルの傾き、切片を確認します。

実行結果

お弁当の売り上げ予測を行う

  • 予測を実行。
    予測結果は変数 pred に格納します。
    ()内にはテスト用の説明変数 testX を入力すると、作成したモデル(model1)で y を予測します。

  • sample の中身を確認し、予測結果を代入します。
    sample[0] には日付( test の日付と同じ)が入っているので、 sample[1] に予測結果を代入します。

実行結果
<img width=”85″ alt=”02.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/0ef958e9-ac71-ed02-6ee6-3723e8c88dc2.png”>

  • sample を csv ファイルで書き出します。
    オプションには、”submit1.csv”(ファイル名)、index=None、header=Noneを書きます。

SIGNATE に結果を投稿し、確認

保存したcsvファイルをSIGNATEに投稿して、精度を確認します。

  • こちらからSIGNATEのサイトを開いて、Competitionsを選択。
    <img width=”821″ alt=”02.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/97d3dbeb-9905-2e91-d99a-952769aad8b6.png”>

  • 練習問題を選択。
    <img width=”840″ alt=”03.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/2f1c9d92-f06b-e5cc-19ca-9e698d329804.png”>

  • 下にスクロールしてお弁当の需要予測を選択。
    <img width=”840″ alt=”04.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/4b7b4d8b-6312-e160-3108-836f04bc8066.png”>

  • 投稿を選択。
    <img width=”837″ alt=”05.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/dd72fe42-b897-3290-4354-d8ab3c126323.png”>

  • ファイルは先ほど作成した submit1.csv を選択。
    メモには使用した説明変数は temperature と書いておきます。
    <img width=”685″ alt=”06.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/21b86e8e-984e-b65b-e56c-800aada7fdcc.png”>

  • これで投稿完了です。結果が出るまで2、3分あるので少し待ちましょう。
    <img width=”834″ alt=”07.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/6741a419-bcda-f15c-69a8-63ee9f28fab3.png”>

  • 結果が出ました。
    ここでは評価の数が小さいほど精度がいいということになります。
    このモデルの精度は42ほどなので、まだまだというところです。
    <img width=”838″ alt=”08.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/04afc40d-0c52-18df-9991-b23bd362f8eb.png”>

別の説明変数で予測をする

先ほどは説明変数をtemperatureでモデル作成、予測を行いましたが他のカラムを説明変数にしたら結果が変わるだろうと考えます。
ここでは試しに説明変数をkcalにしてモデル作成、予測を行います。

新たな説明変数を取り出す。

  • 説明変数として kcal を選択し、それぞれ trainX 、 testX に代入します。

欠損値の補間

  • 欠損値の有無を確認します。

実行結果

  • 補間に用いる値を計算。
    今回は、補間に kcal の平均値を用います。

実行結果

  • trainX と testX の欠損値を補間します。

  • trainXの中身をする。

実行結果

モデルの作成と予測

  • ここから先の手順は先ほどの手順とほとんど同じなので、コードのみ記述します。

SIGNATEに結果を投稿し、確認

  • 先ほどと同じ手順で sample2.csv を投稿する。
    メモには説明変数は kcal と書いておきます。
    <img width=”717″ alt=”09.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/837d80d1-6524-55d1-1388-38f09d67d20d.png”>

  • 結果が出たら結果を確認。
    sample1.csv の結果と比べると若干精度が上がっていることがわかります。
    このように説明変数を変えるだけで、同じ手法でも精度は変わってきます。
    しかし、精度は39程度とまだまだです。
    <img width=”753″ alt=”10.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/4fc41391-69a9-5dbe-c2ea-a48d30fa3335.png”>

重回帰分析編

もっと良い精度のモデルを作成するために説明変数を増やして、重回帰分析をします。

データは単回帰分析で使ったデータと同じデータを使用します。
重回帰分析は別の notebook で行います。
同じ notebook で作業を行う方は、モジュールのインポートと設定、データの読み込みを飛ばしてください。

モジュールのインポートと設定

データ(csvファイル)の読み込み。

python:read_csv.py
train=pd.read_csv("train.csv")
test=pd.read_csv("test.csv")
sample=pd.read_csv("sample.csv",header=None)

<pre><code><br />- trainのweek列の各値がそれぞれいくつあるか確認します。

Python
train[“week”].value_counts()
#実行結果
木 43
水 43
火 41
金 41
月 39
Name: week, dtype: int64

文字列データの加工(ダミ-変数化)

  • まず、pandasでダミー変数を作成する、get_dummies関数について説明します。
  • get_dummies関数
    ()内にカテゴリー変数(文字列)が含まれるデータを入力することで、カテゴリー変数をダミー変数(数値)に置き換えます。

  • 今回、説明変数は train から week と temperature を選択します。
    しかし、 week には文字列(カテゴリー変数)が含まれるため、その文字列をダミー変数(数値)に置き換えます。
    行末に.head()を付け加えて結果の確認もします。

実行結果
<img width=”84″ alt=”03.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/7fa425ac-2e20-6c44-434f-aa176b0c32f8.png”>

説明変数と目的変数の取り出し

  • 説明変数として、 train から week と temperature を抜きだし、ダミー変数化したものを変数 trainX に代入します。
    代入後、 trainX の中身を確認しておきます。

目的変数として、 train から y を取り出し、変数yに代入。

test からも同じ説明変数の week と temperature を選択し、同様の手順で変数名 testX に代入し、確認します。

実行結果
<img width=”229″ alt=”04.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/c2837657-3740-dab7-afc5-08cdd632000a.png”>

モデルの作成と予測

  • ここから先の手順は単回帰分析の手順とほとんど同じなので、コードのみ記述します。

SIGNATE に結果を投稿し、確認

  • 先ほどと同じ手順で sample3.csv を投稿します。
    メモには説明変数は week と temperature と書いておきます。
    <img width=”715″ alt=”14.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/0d897ac7-181e-534a-c04b-71bf91e2d723.png”>

  • 結果が出たら結果を確認。
    精度は kcal を説明変数にした時より、下がってしましました。
    精度を上げるには説明変数をただ増やせばいいというわけではありません。
    精度を上げるために、次は追加する説明変数をデータの特徴から考えて作ってみましょう。
    <img width=”755″ alt=”15.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/193ece3d-b568-2378-a412-20a28804346e.png”>

特徴量(説明変数)を作って解析してみる。

  • お弁当の売り上げの特徴を確認します。
    y の折れ線グラフを描く。
    見やすいように figsize=(12,5) としておきます。
    x 軸が時間、 y 軸が売り上げ。

実行結果
<img width=”406″ alt=”05.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/e005dacb-142d-596a-6cf0-f4e33e0f8341.png”>

グラフから時間が進むにつれて、売り上げが少なくなっていることがわかります。
先ほどの予測では時間に関する特徴量が入っていなかったので、時間に関する特徴量を作成します。

特徴量の作成

  • train の datetime から年と月のデータを取り出し、 train の新たなカラムとして追加します。
    その後 train の中身を確認する。
    train の datetime は”年-月-日”という文字列で構成されています。
    年、月のカラム名はそれぞれ year 、 month とする。
    年と月を取り出すために apply 関数と split 関数、 lambda 式を使用します。
  • apply 関数
    指定された列の各値に関数を適用させる関数。
  • split 関数
    文字列を指定された区切り文字で区切ってリスト化する関数。
  • lambda 式
    無名関数
    x を引数、 y を戻り値とした無名の関数を作れます。
    関数の引数として関数を使うときに用いられます。

  • train の datetime 列に対して apply 関数で各値に関数を適用します。
    適用する関数を無名関数として定義します。
    その無名関数の中では、入力として入ってきた文字列を”-“で区切ってリストにするために split 関数を使用。
    split 関数で文字列を区切って作成されたリストの[0]にある年のデータを train の新しいカラム year として追加します。
    month についても同様です。

実行結果
<img width=”497″ alt=”06.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/f493b7af-dd87-9176-a8ad-0c4a0fbfee83.png”>

  • test の説明変数にも同様の手順を行います。

  • train のデータ型を確認します。

実行結果

  • train , test のデータの型を整数( int )に変換します。
    train.info() で見た通り、先ほど追加した year と month は数値ではなく、文字列として保存されています。
    データの型を変換したい場合は、astype 関数を使います。
    オプション(かっこの中)には変換先のデータの型を入れます。

  • データの型が変更されたか確認します。

実行結果

  • testについても同様にデータ型を変更します。

説明変数と目的変数の用意

  • train と test から説明変数の year 、 month を取り出し、新たなカラムとして追加します。

  • trainからyを取り出します。

モデルの作成と予測

  • ここから先の手順は先ほどの手順とほとんど同じなので、コードのみ記述します。

SIGNATE に結果を投稿し、確認

  • 先ほどと同じ手順で sample4.csv を投稿する。
    メモには説明変数は year と month と書いておきます。
    <img width=”716″ alt=”18.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/b597f144-9abc-7f5c-fc7d-c546df22bbf7.png”>

  • 結果が出たら結果を確認。
    今までより精度がかなり上がりました。
    さらに精度を上げるために、新たな説明変数を追加してみましょう。
    <img width=”771″ alt=”19.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/8041df7c-cee6-97b2-fc6c-af78fffa55ff.png”>

追加する特徴量の検討

先ほどは折れ線グラフから特徴を確認し、特徴量の作成を行いました。
次は、別の方法で特徴を確認し、特徴量を追加します。

実際のyの値と予測したyの差から特徴を確認する。

  • trainXに対して予測を行い、trainXの予測値と、trainXの実際の値を比べることができます。
    まず、trainXから先ほど作ったモデルを利用して予測値を求めます。

  • 予測値predを新たなカラムとして追加します。

  • 予測値と実際の値を引き算した値を新たなカラムとして追加します。

  • 先ほど追加したカラムでソートして中身を確認します。
    大きな差があるデータからから共通する要素が見つけられれば、その要素を加えることで更に精度が良いモデルを作れる可能性があります。

実行結果
<img width=”558″ alt=”08.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/02c067cd-6259-d920-8f39-69fce24b660c.png”>

  • 実行結果を確認する。
    結果の下のほうを見ると、誤差が大きい行にはお楽しみメニューであるのがわかります。
    <img width=”557″ alt=”09.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/3a2543e9-8fd3-a386-1bc6-6cb8f1ce11ed.png”>

新たな特徴量を追加する準備

  • 特徴量としてお楽しみメニューを使いするにはお楽しみメニューを数値化する必要があります。
    具体的にはお楽しみメニューなら1、そうでないなら0という特徴量を作成したいと考えます。
    特徴量を作成するために、関数を作成します。
    関数の作成には def文 と if 文を使用します。
  • def文
    自分で関数を作成できます。
  • if文
    条件の結果によって処理を分けられます。

  • お楽しみメニューなら1、そうでないなら0という関数を作成します。

  • 作成した jisaku1 関数と apply 関数を使用して、新たなカラム fun を作成します。

  • trainの中身を確認します。

実行結果
<img width=”559″ alt=”10.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/8eaf1ed9-e2a5-6618-0547-b8040f8c8ecf.png”>

  • 説明変数の取り出し。
    今回は、year 、 month 、 fun 、 temperatureを説明変数として取り出します。

モデルの作成と予測

  • ここから先の手順は先ほどの手順とほとんど同じなので、コードのみ記述します。

SIGNATE に結果を投稿し、確認

  • 先ほどと同じ手順で sample5.csv を投稿する。
    メモには、説明変数はyear、month、fun、temperatureと書いておきます。
    <img width=”714″ alt=”24.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/a0b27ca3-1afd-505b-bd4a-054127b43ee1.png”>

  • 結果が出たら結果を確認。
    今までで一番良い精度の予測ができました。
    このように、関係する特徴量をよく考えて作ったり、追加したりすることで精度を上げることができます。
    <img width=”754″ alt=”25.png” src=”https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390035/2c92ecc7-7e8e-7da5-dcc7-8e5a3f99dac3.png”>

#おわりに
今回は実際にpythonでプログラミングをしながら、お弁当の売り上げ予測を線形回帰で行いました。
次のその3では決定木を用いた銀行の顧客ターゲティングについてまとめていきますので、よろしくお願いします。

 

SageMakerの導入ならナレコムにおまかせください。

日本のAPNコンサルティングパートナーとしては国内初である、Machine Learning コンピテンシー認定のナレコムが導入から活用方法までサポートします。お気軽にご相談ください。

ソリューションページはこちら

 

 

この記事を書いた人

aws-recipe-user