ページ

2013年4月21日日曜日

最小二乗法をpostgresで説く

postgresにも数学用の関数がいくつか用意されています。
こちらを利用し、最小二乗法が実現可能です。
ただし、作成できるのは線形(y=ax+b)のみなので利用用とは初級では限界があるかもしれません。
でも出来るだけでもありがたい。

環境
環境情報 構築日 ソフトウェア
CentOS 5.6 2013/04/20 postgresql 9.2
まずは、テーブルを作成
-- データ格納用テーブル.
CREATE TABLE target(
date TIMESTAMP, --  日付
sales NUMERIC(19, 0) -- 値
);
続いてデータを作成
INSERT INTO target VALUES('2013/01/01', 200);
INSERT INTO target VALUES('2013/01/02', 300);
INSERT INTO target VALUES('2013/01/03', 400);
INSERT INTO target VALUES('2013/01/04', 500);
INSERT INTO target VALUES('2013/01/05', 600);
INSERT INTO target VALUES('2013/01/06', 700);
INSERT INTO target VALUES('2013/01/07', 800);
INSERT INTO target VALUES('2013/01/08', 900);
INSERT INTO target VALUES('2013/01/09', 1000);
INSERT INTO target VALUES('2013/01/10', 1100);
INSERT INTO target VALUES('2013/01/11', 1200);
INSERT INTO target VALUES('2013/01/12', 1300);
INSERT INTO target VALUES('2013/01/13', 1400);
INSERT INTO target VALUES('2013/01/14', 1500);
INSERT INTO target VALUES('2013/01/15', 1600);
INSERT INTO target VALUES('2013/01/16', 1700);
INSERT INTO target VALUES('2013/01/17', 1800);
これで利用準備が整いました
では今回解く式はy=ax+bです。
日付は、日にちと考え、年月を集約します
xを日付、yを値とすると
インサートしたデータを利用すると式は
y=100x+100ができるはずです。
SQLを作成します。
-- 傾き(a)にあたる部分を取得
SELECT regr_slope(sales, to_char(date, 'dd'):: integer) FROM target ;
-- 切片(b)にあたる部分を取得
SELECT regr_intercept(sales, to_char(date, 'dd'):: integer) FROM target ;
今回のデータは参考用のためきれいな値が求まりましたが もっと複雑なのも大丈夫です。 今回利用した集約関数(postgresマニュアル参照)では下記の説明がなされています
regr_intercept(Y, X)(X, Y)の組み合わせで決まる、線型方程式に対する最小二乗法のY切片。
regr_slope(Y, X)(X, Y)の組み合わせで決まる、最小二乗法に合う線型方程式の傾き。