2015年5月5日火曜日

[kdb] Q Math Library (qml) (2) 回帰分析

Q Math Library の使い方メモ (2)

□回帰分析
・単回帰分析
y=c+ax の回帰を行う。データをこの式に代入して行列で表現すると、Y=XA となる。
Yはデータ個数の縦ベクトル、Xはデータ個数行・2列の行列、A=(c a) の縦ベクトル

/ .qml.mlsq[X;Y]   / 公式には.qml.mlsq[A;B]
q)show X: flip (10#1;til 10)   / 0-9で、1列目は固定で1
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9

q)show Y: (10?10) + 2*til 10   / 切片5、傾き2
8 3 13 11 12 16 18 15 24 23

q).qml.mlsq[X;Y]   / 1つめが切片, 2つめが傾き
4.654545 1.921212


回帰分析の各種情報を取りやすくした関数がcontribのlinreg.qに定義されている

参考: Is there linear regression algorithms written by Q language?
https://groups.google.com/forum/#!searchin/personal-kdbplus/linear$20regression/personal-kdbplus/CRf-kOx-v4I/mqqo49tsvTIJ

・contribからソースを入手
http://code.kx.com/wsvn/code/contrib/azholos/linreg.q


/ 単回帰分析
q)show X: (1;til 10)   / flipせずに単純に係数を並べてOK
1
0 1 2 3 4 5 6 7 8 9

q)show Y: (10?10) + 2*til 10   / Yは上と同じ
5 8 8 7 11 13 19 22 18 19

q) linreg[Y;X]
     | ::
X    | (1 0f;1 1f;1 2f;1 3f;1 4f;1 5f;1 6f;1 7f;1 8f;1 9f)
y    | 1 6 7 15 16 19 21 19 20 18f
S    | (4.473113 -0.706281;-0.706281 0.1569513)
b    | 5.145455 2.012121
e    | -4.145455 -1.157576 -2.169697 3.818182 2.806061 3.793939 3.781818 -0.230303 -1.242424 -5.254545
n    | 10
m    | 2
df   | 8
se   | 2.114974 0.3961708
tstat| 2.432869 5.078923
tpval| 0.04101822 0.0009544019
rss  | 103.5879
tss  | 437.6
r2   | 0.7632818
r2adj| 0.733692
fstat| 25.79546
fpval| 0.0009544019



2015年5月1日金曜日

[kdb] Adverbs / each

Adverbsに関するメモ(主にeach)
※間違いがありそう。あればコメントください。

kxwiki - Adverbs

・adverb
function or verb を引数にとって、別の function or verb を作り出す。
each以外はスペースを空けてはならない。

adverbの引数はadverbの前にあるfunction or verbなので、adverbの後ろはfunction or verbの引数。
つまり、f each args の場合、eachの引数はfで、argsはfの引数になる。

個人的によく使いそうなもの
[eachなど]
each  each        - 
  '   each both   - 
 \:   each left   - 
 /:   each right  - 

[関数fに作用]
 f each X  - fは1つ以上の引数をとる関数。
             fからXのそれぞれに作用する関数を作り出す。
             イメージ f[X[0]], f[X[1]],...
 X f' Y    - fは2つ以上の引数をとる関数。
             fからXとYの両方にそれぞれ作用する関数を作り出す。
             イメージ f[X[0];Y[0]], f[X[1];Y[1]],...
 X f\: Y   - fは2つ以上の引数をとる関数。
             fからXのぞれぞれをYに作用させる関数を作り出す。
             イメージ f[X[0];Y], f[X[1];Y],...
 X f/: Y   - fは2つ以上の引数をとる関数。
             fからYのぞれぞれをXに作用させる関数を作り出す。
             イメージ f[X;Y[0]], f[X;Y[0]],...

[実行例]
q)f:{sum x,y}
q)X: 1 2 3
q)Y: 10 20 30

q)f each X
{sum x,y}'[1 2 3]
q)
q)(f each X) Y
11 22 33

q)X f' Y
11 22 33
q)X f\: Y
61 62 63
q)X f/: Y
16 26 36

q)X f/:\: Y   / "X (f/:)\: Y "と同じ, (f/:)を関数と見ればよい
11 21 31
12 22 32
13 23 33


[書き方]
f'[X;Y], f\:[X;Y], f/:[X;Y] とも書ける
q)parse "X f' Y"   / parseすれば同じに見える
(';`f)
`X
`Y
q)parse "f'[X;Y]"  / parseすれば同じに見える
(';`f)
`X
`Y

・eachを使った関数の応用
TBW, maybe...



2015年4月22日水曜日

[kdb] Performance (1) distinct / join key

Performanceメモ (1) distinct / join key

重複を排除するために使用するdistinctのPerformance

・数値のリストのリスト
floatのdistinctは非常に遅いので避けるべき。
通常floatをdistinctするケースは無いが、0.1刻みのデータや意図せずfloatになってしまっているケースもあるので注意

q) L: `float$ 10000000?10000i
q) \t distinct L
305

q) L: 10000000?10000i
q) \t distinct L
29

リストのリストをdistinctするときにより影響が大きい
q)L: til 5
q)LL: do[5; L cross L]
q)LL
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 2
...
q)count LL
15625

q)LLf: 0.5*10000?LL   / floatのListを作成
q)LLf
0.5 0   0   1   0   1  
0   1.5 0.5 2   1.5 1  
1.5 1   2   1   1   1.5

q)\t distinct LLf   / 要素が10000で1sもかかる
965
q)count  distinct LLf
7448

q)\t 0.5* distinct `int$2*LLf   / castの時間を加えても100倍早い
8
q)count  distinct `int$2*LLf
7448


・Join key
上記と同様に、valueとしてfloatのリストが入っているテーブル同士をjoinする場合、
floatのリストをkeyにしてjoinをすると非常に遅い。
q) meta t   / listをkeyにして結合したい
c   | t f a
----| -----
list| F     
... |      
q) count t   / 
47293j
q) t
list              ..
------------------..
1 2 3 4 5 6   7   ..
1 2 3 4 5 6.5 6.5 ..

q) \t (t同士をlistをkeyに自己結合)
200230j

q) \t (t同士をintに変換したlistをkeyに自己結合)
135j




2015年4月19日日曜日

[kdb] Loop: ループと関数

ループ処理に関するメモ
※ループ処理は基本的に遅いので、できるだけループ処理は行わないようにするのがよい


・ループ処理
kdbのループ処理は while, do, 関数(each) で行う。
do[count;exp1;...;expn]
while[test;exp1;...;expn]
function[] each xxx


・for文のループ
for文は存在しないので、for文に相当する処理を行うためには、以下の2通りの方法で行う。
(1) index 付き while or do
(2) 関数をeachで呼ぶ

(1) index 付き while or do
q) i:0; x:1;
q) do[5; x*:2; i+:1]   / do
q) x
32

q) i:0; x:1;
q) while[i<5;  x*:2; i+:1]   / while
q) x
32
(2) 関数をeachで呼ぶ 処理部分を関数化すればeachで呼ぶことができる。peachを使うことで並列実行可能
q) L: -10#til 110
q) x:()
q) i:0
q) do[10; x,:L@i; i+:1]
q) x
100 101 102 103 104 105 106 107 108 109

q) {x@y}[L;] each til 10
100 101 102 103 104 105 106 107 108 109

2015年4月14日火曜日

[kdb] rand: 乱数

乱数に関するメモ

・アルゴリズム
kdbの擬似乱数生成アルゴリズムはキャリー付き乗算らしい

https://groups.google.com/forum/#!searchin/personal-kdbplus/Mersenne/personal-kdbplus/_8HIuv6AV-4/UmjaxVrfanoJ

> simon 2008/09/05
>
> this is the one currently used
> http://en.wikipedia.org/wiki/Multiply-with-carry
> no bitwise operations at the moment
>

・使用方法

kwxiki - rand

各atomの0を引数に入れると、そのatomの乱数が生成される
q)rand 0i
-2074077848i
q)rand each 10#0b
0111000011b
q)rand `float$0    / 当然ですがfloatはダメ
0f

0以外の数字を入れると、[0,X)の値が生成される。Xが含まれないのがポイント
q)rand each 5#100
20 77 5 64 49
q)rand each 5#1.0
0.2149847 0.1007832 0.4520411 0.0196153 0.1262957

q)rand each 100#1b   / trueが含まれないので全部false
00000000000000000000000000000000000000000000000000000000000000000000000000000..

引数がリストの場合は、リストの要素からランダムに抽出
q)rand `A`B`C
`B
q)rand each 5#enlist `A`B`C
`A`A`C`B`B


"?"でも同様。?がkに近い書き方?
q)10?1.0
0.6598286 0.03947309 0.1404332 0.4545668 0.6829453 0.7773633 0.5704403 0.8341..
q)10?0b
1010011100b

q)10?`A`B`C
`A`B`C`C`A`B`B`B`B`C


重複なし、ランダムソート(並び替え)
"?"の前にマイナスをつけると、重複なしとなる。これを使えばランダムソートが可能
q)-10?10   / 重複なしでランダムに取得する
9 3 0 1 5 6 8 4 7 2

q) -11?10   / 数が合わないのでエラー
'length

q)(neg count x)?x   / xのランダムソートになる
`B`A`D`C`E

q)x -5?5   / indexを乱数で作って取得してもよい
`C`D`B`E`A