10
3

More than 1 year has passed since last update.

Pythonでデータ分析をしてみた。

Last updated at Posted at 2021-12-17

はじめに

勉強の為、Pythonでデータ分析を使ってみました。

データ分析の練習の為、SIGNATEの【練習問題】お弁当の需要予測を試してみました。

【練習問題】お弁当の需要予測
https://signate.jp/competitions/24

この練習問題は、お弁当の売れ残り対策の為、お弁当の需要予測を行うという内容で、
曜日、天気、温度等の要因が販売個数とどんな関係があるか分析し、お弁当の需要を予測しましょうという内容となっています。

SIGNATE

SIGNATE は、2018年4月にオープンしたAI開発コンペティションサイトです。 データ分析に関するコンペティションを開催しており、好成績を残したデータサイエンティストは賞金や実績、データを提供した企業や団体は最適な分析結果が得られます。

環境

Python

Python本体をダウンロードし、インストールします。
バージョンは3.9.0を使用しました。

Pythonとは1991年にオランダ人のグイド・ヴァンロッサムというプログラマーによって開発され、オープンソースで運営されているプログラミング言語です。

Anaconda

データ解析に使うライブラリの一式が入ったツールキットをダウンロードし、インストールします。
ツールキットの中にエディタも入っており、仮想環境を作成して、その上でPythonを動かすこともできます。
また、データ解析に使用するパッケージが用意されていて、とても便利で簡単です。

世界中に2500万人以上のユーザーがいる、オープンソースのIndividual Edition(Distribution)は、Python / Rデータサイエンスと機械学習を1台のマシンで実行する最も簡単な方法です。個人開業医向けに開発されたこのツールキットは、何千ものオープンソースパッケージやライブラリを操作できるようにするためのものです。

データ解析をしてみる

今回は、勉強の為にデータ解析に触れてみるだけでソースはほぼお借りしてきたものを流用しています。
それでも、内容の理解の為に調べることが多すぎて中々時間が足りなくなりました。
また、内容について詳細を調べると難しいものが多く勉強したものを紹介する内容となっています。

データ解析

まずはデータ解析に使うデータを用意します。

【練習問題】お弁当の需要予測

必要なデータは、SIGNATEのページに用意されており、2つのCSVファイルをダウンロードします。

・train.csv
学習用データ期間:2013年11月18日 ~ 2014年 9月30日
'y'が目的変数で販売個数になります。

(例)

日時 y 売り切れ 名前 kcal 備考 イベント 給料日 天気 降水量 気温
2013-11-18 90 0 厚切りイカフライ 快晴 -- 19.8
2013-11-19 101 1 手作りヒレカツ 快晴 -- 17.0
2013-11-20 118 0 白身魚唐揚げ野菜あん 快晴 -- 15.5
2013-11-21 120 1 若鶏ピリ辛焼 快晴 -- 15.2
2013-11-22 130 1 ビッグメンチカツ 快晴 -- 16.1

・test.csv
評価用データ期間:2014年10月 1日 ~ 2014年11月30日
このデータに対して評価用データ期間の販売個数を予測します。

ライブラリ・モジュールのインポート

・pandas
データ分析に使用するライブラリ

sample.py
#pandasをインポート
import pandas as pd

・sklearn
Pythonの機械学習ライブラリ

sample.py
#Pythonの機械学習ライブラリからデータを切り分けるモジュールをインポートする。
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression,Ridge
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor

・Pipeline
何重にも重なる処理を、わかりやすく表現する機能。

sample.py
#Pipelineをインポートします。
from sklearn.pipeline import Pipeline

・r2_score
機械学習ライブラリのscikit-learnのr2_score関数を使います。
r2_score関数は決定係数といい、データ解析のモデルの当てはまりの良さを示す指標で、最も当てはまりの良い場合、1.0 となります。

sample.py
#r2_scoreをインポートします。
from sklearn.metrics import r2_score

データ解析用のCSVを読み込み、データを加工する。

ここから実際にデータ解析に使用するデータの読み込みを行います。

sample.py
#CSVからデータを取得

#弁当データCSV(学習用データ期間:2013年11月18日 ~ 2014年 9月30日)
train = pd.read_csv('bento_train.csv')
#テストデータCSV(評価用データ期間:2014年10月 1日 ~ 2014年11月30日)
test = pd.read_csv('bento_test.csv')

目的変数である'y'を

sample.py
#弁当データCSVから目的変数である'y'をCSVデータの表から削除し、変数trainXに代入。
trainX = train.drop('y', axis=1)
#弁当データCSVから目的変数である'y'のデータを変数'y'に代入。
y = train['y']
sample.py
#予測するデータのCSVを読み込みます。
testX = test.copy()


```python:sample.py
#学習用CSVデータの使用しないカラムとデータを削除する。
trainX = trainX.drop(['remarks', 'event', 'payday', 'name', 'precipitation', 'datetime' ], axis=1)
testX = testX.drop(['remarks', 'event', 'payday', 'name', 'precipitation', 'datetime' ], axis=1)
#"kcal"の平均値(mean)で値の入っていないデータを補填する。
trainX["kcal"] = trainX["kcal"].fillna(trainX["kcal"].mean())
testX["kcal"] = testX["kcal"].fillna(testX["kcal"].mean())

データ解析ライブラリのpandasを使用してダミー変数を作成する。
読み込んだCSVデータ内の曜日と天気を数字に変換しています。

sample.py
#ダミー変数を作成するカラムをリストにする。
dummy_colums = ['week','weather']

#trainXのカラムに対してダミー変数を作成する。
trainX = pd.get_dummies(trainX, dummy_na=False, columns=dummy_colums)

#testXのカラムに対してダミー変数を作成する。
testX = pd.get_dummies(testX, dummy_na=False, columns=dummy_colums)

データ分析処理

Pandas、sklearnを用いて回帰分析を行います。
1つ1つの説明が長すぎて書ききれないので紹介だけします。
詳細は参考文献を参照してください。

・ols (Pandas)
最小二乗法(OLS: Ordinary Least Squares) 誤差の二乗が最も小さくなるようにする。

・Ridge (sklearn)
リッジ回帰「L2正則化(またはRidge)」とは、特に正則化項(罰則項)として「L2ノルム」を採用した正則化のこと
機械学習において、過剰に学習させてしまう過学習を抑制する効果がある。
正則化とは機械学習において、モデルの過学習を抑えるために損失関数(誤差関数)に正則化項を導入する手法のこと。

・DecisionTreeRegressor(sklearn)
決定木分析 (Decision Tree Analysis) は、機械学習の手法の一つで決定木と呼ばれる、木を逆にしたようなデータ構造を用いて分類と回帰を行います。

・RandomForestRegressor(sklearn)
複数の決定木を使って各決定木の予測結果の多数決で結果を求める方法です。

・GradientBoostingRegressor(sklearn)
勾配ブースティング回帰という手法、難しすぎて説明はできないので参考資料を参照ください。

sample.py
# pipelineを使用して、データ分析を行う。
pipelines = {
     'ols': Pipeline([('scl',StandardScaler()),
                      ('est',LinearRegression())]),

     'ridge':Pipeline([('scl',StandardScaler()),
                       ('est',Ridge(random_state=0))]),

     'tree': Pipeline([('scl',StandardScaler()),
                     ('est',DecisionTreeRegressor(random_state=0))]),

     'rf': Pipeline([('scl',StandardScaler()),
                     ('est',RandomForestRegressor(random_state=0))]),

     'gbr1': Pipeline([('scl',StandardScaler()),
                      ('est',GradientBoostingRegressor(random_state=0))]),

     'gbr2': Pipeline([('scl',StandardScaler()),
                      ('est',GradientBoostingRegressor(n_estimators=200,
                                                       random_state=0))])
}
sample.py
# 機械学習を実行する。
scores = {}
for pipe_name, pipeline in pipelines.items():
    pipeline.fit(X_train, y_train)
    scores[(pipe_name,'train')] = r2_score(y_train, pipeline.predict(X_train))
    scores[(pipe_name,'test')] = r2_score(y_test, pipeline.predict(X_test))
sample.py
# 機械学習結果の表示
           test     train
gbr1   0.703323  0.945273
gbr2   0.672755  0.981484
ols    0.305589  0.523082
rf     0.630820  0.954129
ridge  0.328230  0.522096
tree   0.426131  1.000000
sample.py
#機械学習モデルを作成する
model = GradientBoostingRegressor()
model.fit(trainX, y)


データ解析結果

データ解析結果の表示

sample.py
#データ解析結果
pred = model.predict(testX)

#目的変数:販売予測個数の表示
[ 70.53448298  65.18182648  72.74002415  68.84283309  61.25705554
  57.47444883  62.03288102  69.23002959  56.65529706 112.29291597
  70.65305346  67.25483235  75.78145572  70.25964217 110.69620083
 104.56811264  72.94582533  68.92227057  73.39214705  69.3901024
  62.55510811  70.75695636  77.06749736 113.91819978  62.13074626
  70.29577602  66.89244724 111.60799719 114.53484058  60.77451103
  91.9875916  131.79963899 113.6323069  109.66488392 116.62545708
  95.00540798 117.70979352 117.96092206 104.16261241  94.09085023]

・上記で作成した内容をtest.csvの内容と合わせて表にすると以下のようになります。
以下の表は、不要なカラムを省いています。

年月日 販売予想個数 曜日 お弁当名 天気 温度
2014/10/1 70.53448298 メンチカツ 20.2
2014/10/2 65.18182648 バーベキューチキン 23.9
2014/10/3 72.74002415 豚肉のマスタード焼き 晴れ 28.7
2014/10/6 68.84283309 麻婆春雨 21.5
2014/10/7 61.25705554 厚揚げ肉みそ炒め 晴れ 22.1
2014/10/8 57.47444883 完熟トマトのホットカレー 晴れ 23.3
2014/10/9 62.03288102 豚キムチ炒め 22.5
2014/10/10 69.23002959 ポークカレー 薄曇 26.1
2014/10/14 56.65529706 若鶏梅肉包揚げ 快晴 26.8
2014/10/15 112.292916 ミックスグリル 15.6
2014/10/16 70.65305346 豚肉と白菜の中華炒め 晴れ 18.6
2014/10/17 67.25483235 ヒレカツ 快晴 23
2014/10/20 75.78145572 豚柳川 薄曇 23.9
2014/10/21 70.25964217 ポーク生姜焼き 20.2
2014/10/22 110.6962008 麻婆豆腐 15.5
2014/10/23 104.5681126 ビーフストロガノフ 14.7
2014/10/24 72.94582533 唐揚げ丼 快晴 18.7
2014/10/27 68.92227057 マス塩焼き 薄曇 22.7
2014/10/28 73.39214705 チンジャオロース 快晴 19.1
2014/10/29 69.3901024 厚切イカフライ 快晴 19.6
2014/10/30 62.55510811 鶏肉と野菜の黒胡椒炒め 晴れ 19.6
2014/10/31 70.75695636 八宝菜 18.8
2014/11/4 77.06749736 豚肉の生姜焼き 晴れ 18.9
2014/11/5 113.9181998 ハンバーグ 16
2014/11/6 62.13074626 彩り野菜と鶏肉の黒酢あん 19.2
2014/11/7 70.29577602 ポークカレー 晴れ 20.1
2014/11/10 66.89244724 親子煮 快晴 21.2
2014/11/11 111.6079972 ポークのバーベキューソテー 14.7
2014/11/12 114.5348406 鶏肉の唐揚げ 14.4
2014/11/13 60.77451103 白身魚味噌焼き 快晴 19.5
2014/11/14 91.9875916 エビフライ・エビカツ 快晴 15.8
2014/11/17 131.799639 野菜ごろごろシチュー 薄曇 14.3
2014/11/18 113.6323069 麻婆豆腐 快晴 16.1
2014/11/19 109.6648839 ベルギー風チキンのクリーム煮 快晴 14.9
2014/11/20 116.6254571 スタミナ炒め 10.5
2014/11/21 95.00540798 ロコモコ丼 快晴 14.9
2014/11/25 117.7097935 なすと挽肉のはさみ揚げ 11.4
2014/11/26 117.9609221 鶏肉の治部煮風 9.2
2014/11/27 104.1626124 牛丼風 快晴 15.1
2014/11/28 94.09085023 鶏肉のスイートチリソース 15.3

まとめ・感想

初心者がデータ解析に触ってみたということで、内容はお借りしてきたものが多く、書いている間は何をしているのか調べるのが9割でしたが、それでも難しく最後の表に当てはめるまで出来てよかったとホッとするくらいで、内容の理解が追い付いていない状態です。
はじめにPythonについて何ができるのか調べたところ、人工知能やデータ解析ができ、シンプルなコードで読みやすいとあったのでテーマに選びました。
しかし、データ解析は調べれば調べるほど難しい内容となっていて、ちゃんと勉強するなら数カ月はかかるものじゃないかと思うような難易度で、気軽にやってみようというものではなかったです。

参考文献

・Pythonとは?特徴やできること・人気の理由を初心者向けに解説
https://www.sejuku.net/blog/7720
・データ分析のライブラリ!Pandasとは【初心者向け】
https://techacademy.jp/magazine/17697
・Scikit-learnとは?データ分析や機械学習に欠かせないScikit-learnのメリットや機能まとめ
https://ai-kenkyujo.com/scikit-learn/
・[SIGNATE練習問題]お弁当の需要予測をやってみた
https://nanjamonja.net/archives/46#i-4
・Pandasでダミー変数を作成するget_dummies関数の使い方
https://deepage.net/features/pandas-get-dummies.html
・Pandasで最小二乗法(ols)を使った回帰を行う方法
https://deepage.net/features/pandas-ols.html
・【初学者向け】L2正則化をわかりやすく解説【リッジ回帰】
https://mathmatical22.xyz/2019/09/23/%E3%80%90%E5%88%9D%E5%AD%A6%E8%80%85%E5%90%91%E3%81%91%E3%80%91l2%E6%AD%A3%E5%89%87%E5%8C%96%E3%80%90%E3%83%AA%E3%83%83%E3%82%B8%E5%9B%9E%E5%B8%B0%E3%80%91/
・超入門!リッジ回帰・Lasso回帰・Elastic Netの基本と特徴をサクッと理解!
https://aizine.ai/ridge-lasso-elasticnet/#toc1
・scikit-learn で決定木分析 (CART 法)
https://pythondatascience.plavox.info/scikit-learn/scikit-learn%E3%81%A7%E6%B1%BA%E5%AE%9A%E6%9C%A8%E5%88%86%E6%9E%90
・機械学習手法「ランダムフォレスト」でクラス分類にチャレンジしよう
https://www.sejuku.net/blog/64455
・勾配ブースティング回帰木を使用した回帰分析
https://jpn.nec.com/hpc/sxauroratsubasa/column/012.html
・勾配ブースティング回帰の実践的な説明
https://ichi.pro/kobai-bu-suthingu-kaiki-no-jissenteki-na-setsumei-5290993901470

10
3
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
10
3