Prestoで単回帰分析を行う


はじめに

PrestoとはFacebookが開発している分散型SQLクエリエンジンです。1 Prestoはもう一つの分散型SQLクエリエンジンであるHiveに比べインテラクティブにビッグデータに対してアクセスできるため、簡単なデータの分析や出力にはPrestoが用いられることが多いです。しかしHiveはHivemallという豊富な機械学習ライブラリが存在しており、Prestoに比べ機械学習などの複雑なクエリの実行が容易に行えます。

しかしPrestoでも簡単な単回帰予測ぐらいであれば実装ができてしまうことがわかったのでその方法について書きます。

そもそも単回帰分析とは

単回帰分析に関しては僕が書くよりももっとわかりやすい記事や文献がたくさんあると思うので省きます。
簡単にいうと、単回帰分析とは一つの入力と出力結果を複数学習させることで、それらのデータの関係を導き出し、ある入力に対して出力を予測するための手法です。

一般的に直線($y = ax + b$)をモデルにして学習を行い、$a$と$b$の値を導き出すパターンが多いです。

これ以上かいても粗が多いと思うのでやめます。
とにかく今からやりたいのは、関係がある二つのパラメータ(部屋の広さと家賃のデータなど)を学習させてもっとも精度の良い直線式$y = ax + b$の$a$と$b$を見つけることです。

これらの$a$(傾き)と$b$(切片)をPrestoで計算します。

データセット

具体的なデータは以下のようなものを用意しました。このクエリの後に後述するクエリを記述すれば全て動きます。
基本的に書くクエリは全てTreasureDataで実行しています。(おそらくPrestoであればどの環境でも動くと思います)

WITH data AS (
  SELECT *
  FROM (
    VALUES
      (1, 20),
      (2.1, 30),
      (2.9, 39)
  ) AS t (x, y)
) 

傾きの計算

Prestoではregr_slopeという関数だけで$a$(傾き)を計算することができます。

使い方はhttps://prestodb.io/docs/current/functions/aggregate.html にかいてある通り

SELECT regr_slope(y, x) AS slope FROM data

みたいな感じで書くだけです。ここで注意なのが、引数の順番です。
第一引数が出力(y)で第二引数が入力(x)です。

実際にデータに対して実行すると値は9.95になりました。

切片の計算

切片の計算も簡単でregr_interceptという関数を使うだけです。
使い方もhttps://prestodb.io/docs/current/functions/aggregate.html にかいてある通り。こちらも引数の順番に注意。

SELECT regr_intercept(y, x) AS intercept FROM data

ちなみに今回のデータに対する切片の値は9.78でした。

結論

SELECT  regr_slope(y, x) AS slope, regr_intercept(y, x) AS intercept FROM data

と書けば傾きも切片も計算できます。あとはこの値を使って予測したい入力に対して計算を行うだけです。

WITH data AS (
  SELECT *
  FROM (
    VALUES
      (1, 20),
      (2.1, 30),
      (2.9, 39)
  ) AS t (x, y)
), predict AS(
  SELECT  regr_slope(y, x) AS slope, regr_intercept(y, x) AS intercept FROM data
)

SELECT slope * 2 + intercept FROM predict /* => 29.67 */

  1. 今はコアメンバーはFacebookを退職しており、Facebookとは枝分かれしてPrestoの開発を行っています。Treasure Dataも枝分かれした方を参照しているらしいですGitHub (Thanks! @ebyhr