ML ボードの使い方(数値回帰タイプ)

ML Board How-To Guide

数値回帰モデルを利用した需要予測

はじめに

ML ボードに用意された数値回帰モデルは、何らかの事象から数値を予測することに利用できます。例えば天候や曜日などから来場者数や販売数を予測したり、交通機関の利用者数を予測したりといった場合です。

最初に知っておくべきこと

予測因子

天候や曜日から販売数を予測する場合、予測のもとになる天候や曜日といったデータのことを予測因子と呼びます。この予測因子は、正確な予測を行うためにとても重要です。何らかの因果関係がある予測因子を正しく選択することで、予測精度は飛躍的に高まりもしますし、逆に選択を間違えてしまうと、まったく精度が出なくなります。

なので、数値回帰モデルによる予測を行う場合、まずは、「なぜこの商品を購入するのか」といったことをよく考えなければなりません。必要に応じてデータを分析し、購買との関連が予測される因子を見つけ出す作業も必要です。そして適切なデータを因子とすることができれば、ML ボードは販売数につながる特徴をつかむことができ、予測精度はとても高くなることでしょう。

ベンチマーク

予測因子の選択をするのと同時に、準備しておくべきなのは、ベンチマークです。ベンチマークとは、新しい予測の仕組みを作る前に準備しておく、「精度の物差し」です。この物差しを利用して、予測精度が高くなっているのかどうかを評価します。

予測数値を評価するということは、実際の数値とくらべてどのくらいバラつきがあるかということを調べることになります。バラつきを表すのには、一般的に二乗平均平方根誤差(RMSE: Root Mean Square Error)がよく利用されます。

RMSE の式は、以下のようになり、数値が小さいほど誤差が少ないということになります。

RMSE

サンプルで解決する課題について

ここでは、電力会社が実際に公開している情報をもとに、電力使用量を予測する仕組みを構築してみます。

ところで電力消費との因果関係が想定される因子とは何でしょうか?

電気は、冷暖房や除湿に利用されるということを考えると、気温や湿度との関係が想定されます。

また照明に利用されるということを考えると、昼と夜の時間も影響があるのではないかと想定されます。

以上のことから、まずは気温・湿度・日の出から日の入りまでの時間を因子として予測をしてみたいと思います。

より精度をあげるためには、祝祭日の情報や、オリンピックなど大きなイベントの情報などを因子として入れたり、予測する地域を細分化し、地域的な特性を入れながら予測モデルを構築し、全体としての精度を上げていくなどの方法が考えられます。

ML ボードを使った予測システム構築の流れ

実際に ML ボードを使って予測を行う前に、おおまかな流れについて説明します。

  1. モデルの選択: 需要予測なので、数値回帰モデルを選択します。ML ボードのモデルは、今後拡張していく予定です。

  2. 予測因子に関する考察: 何を予測因子にすべきかを考えることが、需要予測の肝です。しっかりと分析し考えましょう。今回は、まず入り口として気温・湿度・日中時間を因子としてみます。

  3. 学習データの作成: 因子が決まったら学習データを作成します。学習データとは、ML ボードに特徴がどこにあるのかを考えさせるデータです。今回の場合、気温・湿度・日中時間とその日の電力使用実績を学習データとします。このデータを与えてあげれば、ML ボードは気温・湿度・日中時間と電力使用量との関係を計算し、未来の気温や湿度、日中時間を渡すと電力使用量を予測してくれるようになります。

  4. 学習: データが準備できたら、ML ボードに学習させます。学習にあたっては、最適化を自動的に行うことも実施します。これにより、幾つかのパターンを実行させ、最も精度の高い学習済モデルを利用できるのです。

  5. 評価: いったん学習が終われば、BLOCKS の Big Data ボードを利用して学習済みモデルを利用した予測を行うことができます。ここで学習に利用していないデータを使い、予測精度に関する評価をします。もし精度が十分でなければ、予測因子に関する考察から見直し、どんな因子を ML ボードに見せるべきか、見せる場合にどのように見せたら良いのかからもう一度考えてください。

  6. 利用: 実用的な学習済モデルが完成したら、BLOCKS の Big Data ボードを使って予測を行ったり、BLOCKS の IoT ボードを使って継続的に因子データを収集して、より高い精度の予測を行えるようにしたりと、様々な応用を考えてみてください。そしてこうした一連の作業を BLOCKS で行っている限り、プログラムを作成したりインフラを構築したりといったことが大幅に削減でき、とても効率のよいシステム構築が行えるはずです。

学習のためのデータ作成

データについて

電力需要予測をするために、気象、日の出・日の入りを予測因子にしますが、幸いなことに公開されているデータがあるので、これを利用します。

  1. 気象: 気象庁
  2. 日の出・日の入り: 国立天文台
  3. 電力使用量: 東京電力パワーグリッド

それぞれ 2016 年のデータを学習に利用し、2017 年のデータで予測精度を検証してみたいと思います。2017 年の予測検証については、気象は実測値を入れて検証します。予測因子自体の正確な予測データがない場合、その因子を予測するモデルを作成する必要があるかもしれませんが、ここでは省略します。

予測因子としては、以下の 5 項目になります。

  • 最高気温
  • 最低気温
  • 日照時間
  • 平均湿度
  • 日中時間(日の出から日没までの時間)

予測対象は、日毎の電力使用量とします。

  • 電力使用量(日毎)

つまり気温・日照時間・湿度・日中時間とその日の電力使用量を見せることによって、ML ボードに特徴を見つけさせます。うまく見つけることができると、気温・日照時間・湿度・日中時間を見せるだけで、電力使用量が予測できるようになります。

予測因子データ取得

気象データ

まず気象データを取得してみましょう。

気象データは、気象庁のホームページ からダウンロードできます。以下に、気象庁のホームページからダウンロードした気象データを用意しました。まず、この気象データをダウンロードしてみましょう。


weather_tokyo_utf8.csv

東京の 2016 年 4 月 1 日から 2017 年 1 月 4 日までの日最高気温、日最低気温、日照時間、日平均相対湿度の CSV ファイルです。

左のリンクをクリックしてダウンロードしてください。

もし、ダウンロードされず画面に気象データが表示される場合は、左のリンクをマウスの右ボタンでクリックしてください。表示されるメニューからリンク先を保存する旨のメニュー項目を選択するとダウンロードできます。

東京電力管轄全体の電力消費量を予測するのに、東京都の気象データだけを因子にするのは正確性に問題があるのではないかと思われるかもしれません。もちろん、もう少しエリアを区切り、因子との関係を強くして学習させるということは効果があるかもしれませんが、まずは機械学習のスタート地点として、東京都の気象データで学習してみます。

もし最新の気象データで試したい方は、以下の検索条件を参考にダウンロードしてください。なお、検索条件は、上記ダウンロードデータと同じ、東京の 2016 年 4 月 1 日から 2017 年 1 月 4 日までの日最高気温、日最低気温、日照時間、日平均相対湿度をダウンロードする際の例です。

検索項目 条件
地点を選ぶ
  • 都道府県: 東京
  • 地点: 東京のみ
項目を選ぶ
  • データの種類: 日別値
  • 過去の平均値との比較オプション: なにも選択しない
  • 項目
    • 気温: 日最高気温日最低気温
    • 日照/日射: 日照時間
    • 湿度/気圧: 日平均相対湿度
期間を選ぶ
  • 連続した期間で表示する:
    期間: 2016 年 4 月 1 日から 2017 年 1 月 4 日まで
表示オプションを選ぶ
  • 利用上注意が必要なデータの扱い: 値を表示(格納)しない。
  • 観測環境などの変化の前後で、値が不均質となったデータの扱い: 観測環境などの変化前の値を表示(格納)しない。
  • ダウンロードCSVファイルのデータ仕様: すべて数値で格納(現象あり・なし情報、品質情報は数値で格納):
    • 日付の形式: 日付リテラルで格納
  • その他: 日付に曜日を表示(日別値選択時)
表示オプションを選ぶ操作動画
日の出、日の入りデータ

日の出・日の入りは、国立天文台のホームページ からダウンロードできます。以下に、国立天文台のホームページからダウンロードした日の出・日の入りデータを用意しました。このデータを元に日中時間を計算します。


sunrise_sunset_2016.csv

東京の 2016 年 4 月 1 日から 2016 年 12 月 31 日までの日の出・日の入りデータの CSV ファイルです。

左のリンクをクリックしてダウンロードしてください。

もし、ダウンロードされず画面に日の出・日の入りデータが表示される場合は、左のリンクをマウスの右ボタンでクリックしてください。表示されるメニューからリンク先を保存する旨のメニュー項目を選択するとダウンロードできます。


sunrise_sunset_2017.csv

東京の 2017 年 1 月 1 日から 2017 年 1 月 4 日までの日の出・日の入りデータの CSV ファイルです。

左のリンクをクリックしてダウンロードしてください。

もし、ダウンロードされず画面に日の出・日の入りデータが表示される場合は、左のリンクをマウスの右ボタンでクリックしてください。表示されるメニューからリンク先を保存する旨のメニュー項目を選択するとダウンロードできます。

この日の出・日の入りデータは、国立天文台に著作権があります。また、このデータを利用した一切の行為について国立天文台は何ら責任を負いません。

電力使用量データ取得

電力消費量は、東京電力パワーグリッドのホームページ からダウンロードできます。ここからも 2016 年と 2017 年のデータをダウンロードしましょう。

ダウンロードは、2016 年と 2017 年のリンクをそれぞれマウスの右ボタンでクリックしてください。表示されるメニューからリンク先を保存する旨の項目を選択するとダウンロードできます。

学習データについて

必要なデータを全て取得したら、次に学習データを作成します。ML ボードは、このデータを元に学習をはじめます。正しく学習させるために、データは次の 2 つに分けておく必要があります。

  1. 訓練データ: 学習のために使われるデータ
  2. 検証データ: 学習には利用せず、学習の検証に使います。こうすることで未知のデータに対する性能(汎化性能)を ML ボードが評価できるようになります。

どちらのデータも、CSV ファイル(カンマ区切りファイル)にしてください。ファイルフォーマットの基本的ルールはひとつだけ。一行毎に、予測因子を並べて、最後に予測対象を置くことです(予測対象は数値型のみ)。

なので、今回の例では、次のように並べていきます。

日最高気温, 日最低気温, 日照時間, 日平均相対湿度, 日中時間, 電力使用量

フルサービスプランの場合

2 つのファイルは、BLOCKS が用意する Google Cloud Storage(GCS)に保存してください。この GCS を利用するためには、Google アカウントが別途必要です。

すでに、Google アカウントをお持ちの場合は、「プロジェクト設定」の「GCP アクセス」からその Google アカウントを登録してください。

Google アカウントをお持ちでない場合は、「Google アカウントを作成する」を参考に Google アカウントを作成してから、「プロジェクト設定」の「GCP アクセス」で、その Google アカウントを登録してください。

セルフサービスプランの場合

2 つのファイルは、GCS にファイル格納のためのバケットを作成 して、そこに保存しておいてください。このドキュメントでは、gs://magellan-blocks-doc-train/ に格納しますが、みなさんが作成する場合は、オリジナルの名前をつけてください。

warning ここで使用する GCS バケットは、デフォルトのストレージクラスが「Regional」で、Regional のロケーションが「us-central1」もののみとしてください。これ以外のバケットを使用した場合の動作は保証できません。

学習データの作成方法

学習データを作成する一番簡単な方法は、Google Spreadsheet や Excel などの表計算ソフトにデータを持ってきて、各カラムに因子を並べ、最後に予測対象がくるようにして表を作成。その表から CSV ファイルを作成するだけで OK です。

とは言え、データ量が大きかったら表計算ソフトに入り切らないかもしれませんし、頻繁に使う場合などは自動化したいと思うかもしれません。そういう場合は、BLOCKS の Big Data ボードを使ってください。大量データを高速に処理することができますし、なによりも処理が自動化されます。

今回の例では、データ量的にはそれほど多くないのですが、自動化などを志向される方のためにも、Big Data ボードで作成する方法を紹介します。

簡単にすませたいなぁ。と思う方は、表計算ソフトでちゃちゃっとやっても構いません。

データアップロード

Big Data ボードにデータを入れるには、GCS のバケットにファイルを入れておく必要があります。さきほども学習データは GCS に入れてくださいと言いましたが、その学習データを作るための準備も、GCS に基礎データを入れるところから始まるのです。

このドキュメントでは、バケット名とファイル名を以下のようにしました。このバケット名やファイル名は、自由に変えてもらっても構いません。

  • GCS バケット: gs://magellan-blocks-doc-data/
  • 各種データファイル名
    • 気象データ: weather_tokyo_utf8.csv
    • 日中時間データ(2016): sunrise_sunset_2016.csv
    • 日中時間データ(2017): sunrise_sunset_2017.csv
    • 電力使用量(2016): juyo-2016.csv
    • 電力使用量(2017): juyo-2017.csv

ちなみに全てのファイルは、コードを UTF-8 にしておいてください。特に気象庁からダウンロードできるファイルは UTF-8 ではないので注意してください。

UTF-8 にするには、nkf などのツールを使えば簡単に変換できます。

フルサービスプランの場合

データをアップロードするには、Google Cloud Console を利用します。

  1. 「プロジェクト設定」の「GCP サービスアカウント」を開きます。

    プロジェクト設定(GCP サービスアカウント)
  2. 登録済みアカウントのデータアップロードの gs:// で始まる URL をクリックします。ウェブブラウザーの別タブが開き Google Cloud Console の画面が表示されます。

    info 「gs://****」の **** 部分が GCS のバケット名です。以降、バケット名はここで表示されているバケット名に読み替えてください。

  3. Google Cloud Console 画面上部の「ファイルをアップロード」をクリックして、各種データをアップロードします。

    Cloud Console の GCS の画面(アップロードステップ)

ここまでできたら、必要なデータは全て BLOCKS に取り込める状態になりました。ではいよいよビッグデータ処理をはじめていきます。

セルフサービスプランの場合

データをアップロードするには、以下のように gsutil コマンドを利用します。

gsutil mb -c regional -l us-central1 gs://バケット名
gsutil cp アップロードするファイル gs://バケット名

例:

gsutil mb -c regional -l us-central1 gs://magellan-blocks-doc-data
gsutil cp weather_tokyo_utf8.csv gs://magellan-blocks-doc-data

gsutil のインストール方法については、Google のドキュメント「gsutil をインストールする」を参照してください。

ここまでできたら、必要なデータは全て BLOCKS に取り込める状態になりました。ではいよいよビッグデータ処理をはじめていきます。

Big Data ボードへのデータ投入

BLOCKS の Big Data ボードは、BigQuery を利用して処理を行っています。BigQuery は、Google が提供しているビッグデータ処理の基盤サービスで、データ量に制限を受けることなく利用できるだけでなく、処理速度は世界最速でありながら、価格が極めて安価であるという特徴があります。BLOCKS を使えば、こうした BigQuery を手軽に利用できますので、ML ボードの学習データ作成だけでなく、その前にデータを分析してみたいという人も、ぜひ Big Data ボードを使って BigQuery を活用してみてください。

さて、GCS にアップロードしたデータですが、これを BLOCKS の Big Data ボードで処理できるように読み込み処理を行っていきます。この読み込み処理を行うと、Big Data ボードの処理基盤である BigQuery にデータが入ります。

BLOCKS の処理は、画面上に機能ブロックを置いて線でつないだフローというものが処理の単位になります。

フローは、「フローの開始」ブロックからつないで、「フローの終了」ブロックで終わります。この 2 つのブロックは、ブロックリストの「基本」に入っています。

フローの開始」ブロックには、開始する時間などを指定できるほか、すぐに実行するためのボタンなどが入っています。URL の設定もできますので、外部プログラムから実行 open_in_new したり、業務に組み込むときなどに応用してください。

気象データの読み込み

まずは気象データを読み込みましょう。データの読み込みは、ブロックリストの「BigQuery」に入っている「GCSから単一テーブルへロード」というブロックを利用します。

では、「フローの開始」ブロックから「GCSから単一テーブルへロード」ブロックをつなぎ、「フローの終了」ブロックまでつないでください。

気象データの読み込み

そのままではわかりづらい場合は、ブロックの名称を変えられますので、わかりやすい名前に変えてください。

GCSから単一テーブルへロード」ブロックには、いくつか設定ができますので、以下のように設定してください。

プロパティ
投入データのファイルGCS URL gs://magellan-blocks-doc-data/weather_tokyo_utf8.csv
投入先のデータセット blocks_ml_juyo
投入先のテーブル tokyo_city_20160401_20170104_raw
スキーマ設定
date STRING NULLABLE
weekday STRING NULLABLE
max_temp STRING NULLABLE
min_temp STRING NULLABLE
hours_of_sunshine STRING NULLABLE
other STRING NULLABLE
humidity_avg STRING NULLABLE

スキーマの設定は、スキーマ設定プロパティの「JSONで編集」リンクをクリックして、以下のコードを貼り付けると簡単です。

[
 {
  "name": "date",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "weekday",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "max_temp",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "min_temp",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "hours_of_sunshine",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "other",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "humidity_avg",
  "type": "STRING",
  "mode": "NULLABLE"
 }
]
空でないテーブルが存在したとき 上書き
ファイル形式 CSV
CSVの区切り文字 カンマ(,)
読み飛ばし行数

6 行

※これは気象データの CSV ファイルに、ヘッダー(ファイルの先頭にあるデータを含まない)行が 6 行ある前提です。ヘッダー行がない場合は、0 とします。

このようにすることで、GCS 上のファイルが BigQuery に投入されます。投入されるデータは、BigQuery のデータセットにあるテーブルという場所に入ります。テーブルにはスキーマが必要なので、ここで設定します。

設定が完了したら、画面右上の保存ボタンをクリックしてフローを保存しておきましょう。フローは、保存されていないと実行できません。

フローの保存が完了したら、このフローを実行します。「フローの開始」ブロックを選択し、プロパティの「」ボタンをクリックするとフローが実行されます。

実行結果は、ログに出力されます。ログは、画面下端のログと書かれたバー部分をクリックすると確認できます。ログについて詳しくは、基本操作ガイドのログを参照してください。

もし、フローの実行に失敗した場合は、ブロックのプロパティに設定した内容に間違いがないか確認してください。間違いがあれば訂正し、再度フローを保存し実行してください。

以降、フローの実行は同じ手順を踏みます。

日の出・日の入りデータの読み込み

次に気象データと同じように日の出・日の入りデータを読み込んでみましょう。同じく「フローの開始」ブロックから「GCSから単一テーブルへロード」ブロックをつなぎ、「フローの終了」ブロックまでをひとつのフローとします。

日の出・日の入りデータの読み込み

GCSから単一テーブルへロード」ブロックの設定は、以下のとおりです。まずは 2016 年のデータ。

プロパティ
投入データのファイルGCS URL gs://magellan-blocks-doc-data/sunrise_sunset_2016.csv
投入先のデータセット blocks_ml_juyo
投入先のテーブル tokyo_city_sunrise_sunset_2016_raw
スキーマ設定
date STRING NULLABLE
sunrise_time STRING NULLABLE
sunrise_orientation STRING NULLABLE
meridian_passage STRING NULLABLE
altitude STRING NULLABLE
sunset_time STRING NULLABLE
sunset_orientation STRING NULLABLE

スキーマの設定は、スキーマ設定プロパティの「JSONで編集」リンクをクリックして、以下のコードを貼り付けると簡単です。

[
 {
  "name": "date",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "sunrise_time",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "sunrise_orientation",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "meridian_passage",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "altitude",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "sunset_time",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "sunset_orientation",
  "type": "STRING",
  "mode": "NULLABLE"
 }
]
空でないテーブルが存在したとき 上書き
ファイル形式 CSV
CSVの区切り文字 カンマ(,)
読み飛ばし行数

1 行

※これは日の出・日の入りデータの CSV ファイルに、ヘッダー(ファイルの先頭にあるデータを含まない)行が 1 行ある前提です。ヘッダー行がない場合は、0 とします。

次に 2017 年のデータブロックも同様に設定します(「投入データのファイルGCS URL」と「投入先のテーブル」の 2016 を 2017 に変更します)。

設定が完了したら、フローを保存して実行します。

電力使用量データの読み込み

最後に電力使用量を読み込んでみましょう。同じようにフローを作成します。

電力使用量データの読み込み

GCSから単一テーブルへロード」ブロックの設定は以下のとおりです。

プロパティ
投入データのファイルGCS URL gs://magellan-blocks-doc-data/juyo-2016.csv
投入先のデータセット blocks_ml_juyo
投入先のテーブル juyou_2016_raw
スキーマ設定
date STRING NULLABLE
time STRING NULLABLE
used STRING NULLABLE

スキーマの設定は、スキーマ設定プロパティの「JSONで編集」リンクをクリックして、以下のコードを貼り付けると簡単です。

[
 {
  "name": "date",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "time",
  "type": "STRING",
  "mode": "NULLABLE"
 },
 {
  "name": "used",
  "type": "STRING",
  "mode": "NULLABLE"
 }
]
空でないテーブルが存在したとき 上書き
ファイル形式 CSV
CSVの区切り文字 カンマ(,)
読み飛ばし行数

3 行

※これは電力使用量データの CSV ファイルに、ヘッダー(ファイルの先頭にあるデータを含まない)行が 3 行ある前提です。ヘッダー行がない場合は、0 とします。

次に 2017 年のデータブロックも同様に設定します(「投入データのファイルGCS URL」と「投入先のテーブル」の 2016 を 2017 に変更します)。

設定が完了したら、フローを保存して実行します。

データの作成

全ての基礎データが読み込めたところで、いよいよ学習データを作成していきます。

とはいえ、それぞれのデータは、フォーマットがバラバラなので、このあたりからはじめ、最後に全てのデータをひとつにまとめます。手順としては以下のとおりです。

  1. 年月日のフォーマットを合わせる: 気象データと電力データは、月と日が一桁の場合があるため、一桁の場合は 0 を挿入します。

  2. レコードの粒度を揃える: 気象データ、日の出・日の入りデータは日毎のデータであるが、 電力使用量のデータは 1 時間毎のデータになっているため、日毎の総電力使用量データに変換します。

  3. 年月日で結合する: すべてのデータを、年月日で結合します。

データを作成するフローは、少し長いフローですが、ブロックをつないでいくだけなので、ひとつひとつやっていけば難しいところはないと思います。

さきほどと同じように「フローの開始」ブロックを置くところからはじめます。同時に実行できる部分は、「並列分岐」ブロックを置けば、並列実行もできます。

データの結合
データのフォーマットを合わせる
気象データのフォーマットをあわせる

では、気象データの年月日フォーマットをあわせるブロックの説明からはじめます。図では「気象データ 結合キー整形 2016-2017」という名前がついているブロックです。このブロックは、ブロックリストの「BigQuery」から「クエリーの実行」ブロックを使って設定します。設定は以下のとおりです。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT  REGEXP_REPLACE(REGEXP_REPLACE(date,"(/)([0-9]{1})($)","\\10\\2\\3"),"(/)([0-9]{1})(/)","\\10\\2\\3") AS date,
  max_temp,
  min_temp,
  hours_of_sunshine,
  humidity_avg
FROM
  blocks_ml_juyo.tokyo_city_20160401_20170104_raw
ORDER BY
  date
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル weather_2016_2017
空でないテーブルが存在したとき 上書き
電力データのフォーマットを合わせる

電力データのフォーマットは、少しだけ複雑です。もともとのデータは、時間ごとになっているのですが、これを日毎のデータに変換しなければならないからです。

これを一度にやると面倒ですが、ひとつひとつ処理していけば単純になります。こうした複雑な処理をする時、ひとつのブロックで解決しようとしないで、複数の単純なブロックの組み合わせで処理するほうが、保守性もよくなりますし、開発も楽になります。

年月日フォーマットを合わせる

では、最初に電力データの年月日フォーマットをあわせるところから行きましょう。図では、「電力データ結合キー整形 2016」という名前のブロックです。これもブロックリストの「BigQuery」の中にある「クエリーの実行」ブロックです。

ブロックの設定は、以下のとおりです。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT  REGEXP_REPLACE(REGEXP_REPLACE(date,"(/)([0-9]{1})($)","\\10\\2\\3"),"(/)([0-9]{1})(/)","\\10\\2\\3") AS date,
  time,
  used
FROM
  blocks_ml_juyo.juyou_2016_raw
ORDER BY
  date,
  time
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyou_2016_tmp
空でないテーブルが存在したとき 上書き
時間毎のデータを日毎のデータに変換する

次に時間ごとになっているデータを、日毎のデータに変換します。図では、「日毎レコードに変換」という名前のブロックです。これも同じく「クエリーの実行」ブロックを使って処理します。

ブロックの設定は、以下のとおりです。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  date,
  SUM(cast(used as int64)) as used_sum
FROM
  blocks_ml_juyo.juyou_2016_tmp
GROUP BY
  date
ORDER BY
  date
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyou_2016
空でないテーブルが存在したとき 上書き

年月日で結合する

最後に、すべてのデータを年月日で結合します。図では、「データ結合 2016」という名前のブロックです。これも同じく「クエリーの実行」ブロックを使って処理します。

ブロックの設定は、以下のとおりです。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  juyo.date,
  weather.max_temp,
  weather.min_temp,
  weather.hours_of_sunshine,
  weather.humidity_avg,
  daytime.sunrise_time,
  daytime.sunset_time,
  juyo.used_sum
FROM
  blocks_ml_juyo.juyou_2016 AS juyo
LEFT JOIN
  blocks_ml_juyo.weather_2016_2017 AS weather
ON
  juyo.date = weather.date
LEFT JOIN
  blocks_ml_juyo.tokyo_city_sunrise_sunset_2016_raw AS daytime
ON
  weather.date = daytime.date
ORDER BY
  date
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyo_all_data_2016
空でないテーブルが存在したとき 上書き

設定が完了したら、フローを保存して実行します。

不正データの除去

次に考えなければならないのは、データに不正な値が入っている場合、それを除去しなければならないということです。気象系のオープンデータは、機器の故障などにより計測できていない値が入っていることがあります。こうしたデータをそのままにしておくと、ML ボードが特徴を掴もうとするときに間違えてしまう可能性があります。

なので不正データの除去をやってみましょう。

データの整形・集計

今回の気象データには、非平均相対湿度に ”null” という値が入っています。これを除去するのですが、これも「クエリーの実行」ブロックで行います。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  *
FROM
  blocks_ml_juyo.juyo_all_data_2016
WHERE
  date != "null"
  AND used_sum IS NOT NULL
  AND max_temp != "null"
  AND min_temp != "null"
  AND hours_of_sunshine != "null"
  AND humidity_avg != "null"
  AND sunrise_time != "null"
  AND sunset_time != "null"
ORDER BY
  date
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyo_all_data_2016_no_error
空でないテーブルが存在したとき 上書き
データの型を合わせる

次にデータの型をあわせましょう。型を合わせておくと、後々集計が簡単に行えます。型変換するときに、エラーが出る場合は、データに不正な値が入っている可能性があります。その場合は、データを見直してみてください。これも「クエリーの実行」ブロックを使います。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  date,
  used_sum,
  CAST(max_temp AS float64) AS max_temp,
  CAST(min_temp AS float64) AS min_temp,
  CAST(hours_of_sunshine AS float64) AS hours_of_sunshine,
  CAST(humidity_avg AS float64 ) AS humidity_avg,
  PARSE_TIMESTAMP("%%R", sunrise_time ) AS sunrise_time,
  PARSE_TIMESTAMP("%%R", sunset_time ) AS sunset_time
FROM
  blocks_ml_juyo.juyo_all_data_2016_no_error
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyo_all_data_2016_cast
空でないテーブルが存在したとき 上書き
日中時間の計算

国立天文台から取得した日の出と日の入り時間から、日中時間を計算します。これも「クエリーの実行」ブロックを使います。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  date,
  max_temp,
  min_temp,
  hours_of_sunshine,
  humidity_avg,
  TIMESTAMP_DIFF(sunset_time,sunrise_time,minute) AS daytime_time,
  used_sum
FROM
  blocks_ml_juyo.juyo_all_data_2016_cast
ORDER BY
  date
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyo_all_data_2016_daytime
空でないテーブルが存在したとき 上書き

設定が完了したら、フローを保存して実行します。

訓練データ、検証データの作成

以上で学習データのもととなるデータは完成しました。ここから ML ボードに学習させるためのデータを作成します。

学習データは、訓練データと検証データの 2 つに分けます。訓練データは、ML ボードが特徴を見つけ出していくためのデータで、検証データは、見つけた特徴の精度を見極めるためのデータです。この 2 つのデータを使いながら、ML ボードは正しい学習をしていきます。

学習データを作るときに注意すべきなのは、今のままではデータ時系列に並んでいるということです。データというのは、ある特定の時期だけに似たような傾向を示すことがあります。例えば与えたデータが夏のデータだけだったとき、冬の特徴をつかめないかもしれません。

こうしたことを避けるために、データはランダムに抽出する必要があります。また訓練データと検証データの数ですが、十分な訓練を行うために訓練データのボリュームを確保する意味からも、訓練データと検証データのデータ量は、8:2 になるように分割します。

こうした一連の処理を行うために、レコード毎に乱数の項目を追加し、乱数の大きさで順位をつけ、それを上位 8 割とそれ以外にわけるということを行います。

トレーニングデータの作成

こうした作業も、「クエリーの実行」ブロックを使います。まずは、ランダムな番号を付与するブロックです。

プロパティ
SQL 文法 Standard SQL
クエリー
WITH
  tmp AS (
  SELECT
    date,
    used_sum,
    max_temp,
    min_temp,
    hours_of_sunshine,
    humidity_avg,
    daytime_time,
    RAND() AS rand
  FROM
    blocks_ml_juyo.juyo_all_data_2016_daytime)
SELECT
  date,
  used_sum,
  max_temp,
  min_temp,
  hours_of_sunshine,
  humidity_avg,
  daytime_time,
  ROW_NUMBER() OVER (ORDER BY rand) AS row_num
FROM
  tmp
order by row_num
結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル juyo_all_data_2016_no
空でないテーブルが存在したとき 上書き

次に、訓練データを作成します。訓練データは、いったん BigQuery のテーブルとして作成します。この処理も「クエリーの実行」ブロックを使います。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  max_temp,
  min_temp,
  hours_of_sunshine,
  humidity_avg,
  daytime_time,
  used_sum
FROM
  blocks_ml_juyo.juyo_all_data_2016_no
WHERE
  row_num <= 219

row_num <= 219 は、学習データのデータ量によって変わります。ここでは、学習データのデータ量を 274 件と想定し、訓練データと検証データのデータ量が 8:2 となるように 219 としました。

結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル train_data
空でないテーブルが存在したとき 上書き

テーブルとして作成したデータを、GCSへCSVファイルとしてエクスポートします。この処理は、「単一テーブルからGCSへエクスポート」ブロックを使います。

プロパティ
出力先ファイルのGCS URL gs://magellan-blocks-doc-train/train_data.csv
出力元のデータセット blocks_ml_juyo
出力元のテーブル train_data
ヘッダー行を出力する チェックを外す

次に検証データを作成します。これもいったん BigQuery のテーブルに書き出します。この処理は、訓練データと同様に「クエリーの実行」ブロックを使います。

プロパティ
SQL 文法 Standard SQL
クエリー
SELECT
  max_temp,
  min_temp,
  hours_of_sunshine,
  humidity_avg,
  daytime_time,
   used_sum
FROM
  blocks_ml_juyo.juyo_all_data_2016_no
WHERE
  row_num > 219 

row_num > 219 は、学習データのデータ量によって変わります。ここでは、学習データのデータ量を 274 件と想定し、訓練データと検証データのデータ量が 8:2 となるように 219 としました。

結果格納先のデータセット blocks_ml_juyo
結果格納先のテーブル eval_data
空でないテーブルが存在したとき 上書き

テーブルに書き出した検証データを、GCS へ CSV ファイルとしてエクスポートします。この処理も訓練データと同様に「単一テーブルからGCSへエクスポート」ブロックを使います。

プロパティ
出力先ファイルのGCS URL gs://magellan-blocks-doc-train/eval_data.csv
出力元のデータセット blocks_ml_juyo
出力元のテーブル eval_data
ヘッダー行を出力する チェックを外す

設定が完了したら、フローを保存して実行します。

学習

ようやく学習までやってきました。BLOCKS の ML ボードは、学習や予測はとても簡単に利用できます。なので、予測因子を考え、データを作るところまでに手間がかかりますが、精度の高い機械学習のためには、与えるデータが全てです。どのような因子が適しているのかをよく考えるところには、手間を惜しまないでください。

ML ボード作成

学習のために、ML ボードを作ります。BLOCKS ボード一覧から「新規ボード作成」ボタンをクリックしてください。

新規ボード作成

新規ボード作成画面から「ML ボード」を選択します。

ML ボード選択

数値回帰タイプを選択します。

タイプ選択

ボード名を入力します。

ボード名設定

↓以下はセルフサービスプランの場合のみのステップです。

BLOCKS は、内部で Google のクラウドプラットフォーム(Cloud Machine Learning Engine という機械学習のためのプラットフォームなど)を利用しています。そのために GCP サービスアカウントが必要ですので、ここでアップロードしてください。また、API が有効化されていない場合は、API を有効化します。

GCP サービスアカウント設定

次に Cloud Machine Learning Engine (Cloud ML Engine) プラットフォームが、GCS にアクセスできるように許可を与えます。このために Google Cloud Console の画面右上にある「Cloud Shellを有効にする」というボタンを押し、Cloud Shell 画面を表示してください。

そうするとコマンドプロンプトが出てくるので、以下のコマンドを入力して Cloud ML Engine から利用できるように初期化します。

gcloud ml-engine init-project

ここで許可を与えるかどうか聞いてくるので、「Y」と入力したら終了です。

Cloud ML Engine 設定

学習が終了したら結果は GCS に保存されます。ですので保存先のバケット、ディレクトリを選択してください。

warning ここで使用する GCS バケットは、デフォルトのストレージクラスが「Regional」で、Regional のロケーションが「us-central1」もののみとしてください。これ以外のバケットを使用した場合の動作は保証できません。

ストレージ設定

↑ここまでがセルフサービスプランの場合のみのステップです。

次に、ML ボードで、学習データの項目名、型、次元を設定します。

ここで注意しなければならないのは、学習データ自体には、因子データの最後に予測する数値データ(今回は電力消費量)が入っていますが、ML ボードで項目・型・次元などを指定するのは、因子データだけです。予測することになるデータは指定しません。この点、注意してください。

トレーニングデータ設定

入力した値は、以下を表しています。

項目名 次元数 説明
max_temp 数値型 1 予測日の最高気温
min_temp 数値型 1 予測日の最低気温
hours_of_sunshine 数値型 1 予測日の日射量
humidity_avg 数値型 1 予測日の平均湿度
daytime_time 数値型 1 予測日の日中時間

最後に、入力内容を確認します。

入力内容の確認

学習の開始

さて、全ての準備が整ったので、トレーニングを開始します。

ML ボード詳細

トレーニング開始をクリックします。

トレーニング開始
  • 画面から、トレーニング名を入力します。
  • 訓練データURL、検証データ URL は、GCS に保存した訓練データと検証データの場所になります。
    • 訓練データ URL 例: magellan-blocks-doc-train/train_data.csv
    • 検証データ URL 例: magellan-blocks-doc-train/eval_data.csv
  • トレーニングの経過制限時間(分)を設定したい場合は、制限時間を入れてください。
  • トレーニングの最大試行回数を設定します。ここに試行回数を指定すれば、ML ボードは自動的にパラメータを変更して、最適な結果ができるようにチューニングをはじめます。

開始をクリックすると、トレーニングが始まり、トレーニング状況を確認できます。

トレーニング詳細

学習結果の適用

トレーニングが終わるとステータスが成功に変わり、適用ボタンが表示されます。適用ボタンをクリックすると、学習は終わりです。これで予測が行えます。

予測は、適用ボタンクリック後、時間を数分空けてから行ってください。現バージョンでは、適用後直ちに予測を行うとエラーになる可能性があります。もし、エラーになった場合は、しばらく時間を空けてから再度予測を行ってください。

予測

さて、学習が完了したので、予測を行ってみましょう。

予測フロー作成

予測は、Big Data ボードで行います。

以下のフローを作成します。

予測フロー

簡単に確認するために、Big Data ボードのブロックリストの「基本」から「オブジェクト生成」ブロックを使用します。ここに電力使用量を予測したい日の因子となるデータを入れます。

プロパティ
データ
オブジェクト生成ブロックのデータプロパティ例(回帰)

ここでは、4 種類のデータで予測します。data.0 / data.1 / data.2 / data.3 がそれぞれのデータです。オブジェクト生成ブロックでは、このような複数データを列挙する場合は、「Array」型を使用します。data.0 / data.1 / data.2 / data.3 は、Array 横の「+」ボタンを使って追加します。

それぞれのデータは、「Object」型を使用して、データを識別するキー(key)/ 日最高気温(max_temp)/ 日最低気温(min_temp)/ 日照時間(hours_of_sunshine)/ 日平均相対湿度(humidity_avg)/ 日中時間(daytime_time)をひとつにまとめます。まとめる各データは、Object 横の「+」ボタンを使って追加します。

次にブロックリストの「機械学習」から「ML Board オンライン予測」ブロックをフローに配置して、設定を行います。

プロパティ
MLボード名 (MLボードで作成したボード名)
予測因子データの変数 _.data

予測結果をどのように使うのかは、いろいろな方法があると思いますが、ここでは結果を BigQuery に入れてみたいと思います。このためには、ブロックリストの「BigQuery」から「変数からテーブルへロード」ブロックを利用します。

プロパティ
投入データの変数 _
投入先のデータセット blocks_ml_juyo
投入先のテーブル predict_result
スキーマ設定
predictions RECORD REPEATED
predictions.output FLOAT NULLABLE
predictions.key INTEGER NULLABLE

スキーマの設定は、スキーマ設定プロパティの「JSONで編集」リンクをクリックして、以下のコードを貼り付けると簡単です。

[
 {
  "name": "predictions",
  "type": "RECORD",
  "mode": "REPEATED",
  "fields": [
   {
    "name": "output",
    "type": "FLOAT",
    "mode": "NULLABLE"
   },
   {
    "name": "key",
    "type": "INTEGER",
    "mode": "NULLABLE"
   }
  ]
 }
]

予測結果をファイルとして受け取りたい場合は、同じくブロックリストの「BigQuery」から「単一テーブルからGCSへエクスポート」ブロックを利用します。

プロパティ
出力先ファイルのGCS URL gs://magellan-blocks-doc-data/predict_result.json
出力元のデータセット blocks_ml_juyo
出力元のテーブル predict_result
ファイル形式 NEWLINE_DELIMITED_JSON
予測の実施

さあこれで全て準備ができたので、予測を行ってみましょう。

フロー開始ブロックプロパティの「」を押して予測を実行します。

予測結果は JSON ファイルとして GCS に保存されているので、確認してみましょう。

ファイル名: gs://magellan-blocks-doc-data/predict_result.json

{
  "predictions":[
    {
      "output":84442.0390625,
      "key":"20170101"
    },
    {
      "output":81434.53125,
      "key":"20170102"
    },
    {
      "output":78059.7421875,
      "key":"20170103"
    },
    {
      "output":75184.3125,
      "key":"20170104"
    }
  ]
}

output が 電力使用量の予測値となります。

評価

予測ができるようになったら、学習したモデルに対して評価をしてみましょう。事前に決めていたベンチマークとの比較などを行って、評価をするとよいです。

ここではベンチマークを設定していないので、予測精度を改善するための方法について考えてみることとします。

データ量を増やす

今回の例では、学習に使ったデータ 2016 年の 1 年分しかありませんでした。なのでデータ量としてはちょっと少ないので、まず精度をあげるためにデータ量を増やす努力をしてみましょう。

残念ながら東京電力のオープンデータは、一年分しかなかったので、この例でデータ量を増やすのは難しいのですが、みなさんの会社には、過去数年分のデータがありませんか?少なくとも 3 年分くらいのデータを入れて学習させると、精度はさらに高くなると思います。

試行回数・経過時間を増やす

精度をあげるには、試行回数を増やしたり、経過時間を伸ばすのも効果があります。

ML ボードは、試行回数を指定すると、パラメータを変えて試行してくれます。この数を増やすことで、より精度の高いパラメータを見つけやすくなります。

また経過時間を増やすのも効果があるかもしれません。経過時間は、学習をどこまで頑張るのかを、時間で制約するものです。なので、長く設定すると、精度が高くなりそうであれば、設定された時間まで頑張ります。

こうしたことから、試行回数を増やすことと、経過時間を伸ばすことは、精度向上に役立つかもしれません。しかし、それだけ学習時間が伸びるので、ご注意ください。

因子を見直す

電力消費に影響のある因子は、他にもありませんか?例えば、曜日などは因子として影響があると思います。平日は企業が活動していますから、休日よりも消費量が多いと思います。同じように考えるなら、祝祭日や年末年始、お盆なども影響が考えられます。

こうした要素を加味して、予測精度の改善をしてみましょう。

これまでのモデルで学習をさせた場合の誤差を、「ベンチマーク」のところで説明した RMSE で図ってみると、8,000 を切るくらいでした。つまり 8,000 万 kW 以内の誤差です。

オープンデータを元にした 1 日の発電量予測値が、60,000 万 kW から 90,000 万 kW くらいの値なので、簡単に因子を選択したわりには、そこそこの結果が出ていると思いますが、因子の追加だけでこの精度をさらに上回れるか試してみます。

追加する因子は、曜日と祝日とします。

まず、CSV ファイルに 2 つのカラムを追加します。曜日と祝日です。

学習データ

この例では、6 つめのカラムを曜日とし、月曜を 0、火曜を 1 として、日曜日を 6 として指定しています。ここでは数字で指定していますが、後ほどこの 7 つの数字を曜日として指定します。次に 7 つめのカラムを祝日とし、祝日であれば 1、そうでなければ 0 とします。

次に ML ボードのスキーマを変更します。

曜日は、曜日という型がありますので、それを選択してください。祝日は、型は「文字列列記型」を指定し、キーワードリストに「0,1」と指定してください。

スキーマが定義できたら、さきほどと同じように学習をさせてください。

学習が完了したら、誤差はどうなっているでしょうか?

わたしたちの学習結果では、RMSE で 4,500 を切っており、誤差はほぼ半分になりました。

まとめ

需要予測の精度をあげる因子探しは、結局のところ「どうして電気を使うのか」とか、「どうして商品を買うのか」という消費ニーズの根源的なことを考えることにつながります。なので、最適因子を見つけるには、ビジネスの現場に精通している必要があります。

わたしたちグルーヴノーツが、誰もが使えるサービスを作り機械学習の民主化をすすめているのは、ここに理由があります。コンピュータの専門家ではなく、ビジネスの専門家こそが、機械学習の主役なのです。

BLOCKS の ML ボードを使って、みなさん独自のサービスをどんどん作ってください。