# -*- coding: utf-8 -*-
__future__ import absolute_import, unicode_literals
# 商品ID:10の購入者
from collections import defaultdict
ITEM_10_BUY_USERS = ['A', 'C', 'E', 'G']
INDEX_BASE = 'INDEX_BUY_HISTORY_USER_{}'
INDEX = {
'INDEX_BUY_HISTORY_USER_A':[10,20,50,60,90],
'INDEX_BUY_HISTORY_USER_B':[20,20,50,60,90],
'INDEX_BUY_HISTORY_USER_A':[10,30,50,60,90],
'INDEX_BUY_HISTORY_USER_A':[30,40,50,60],
'INDEX_BUY_HISTORY_USER_A':[10],
'INDEX_BUY_HISTORY_USER_A':[70,80,90],
'INDEX_BUY_HISTORY_USER_A':[10,70,90],
}
result = defaultdict(int)
for user_id in ITEM_10_BUY_USERS:
buy_history = INDEX.get(INDEX_BASE.format(user_id))
for item_id in buy_history:
result[item_id] += 1
l = []
for key in result:
l.append((key, result[key]))
l.sort(key=lambda x: x[1], reverse=True)
print l
php レコメンドエンジン
$Redis->1Rem('Viewer:Item' . $item_id, $user_id):
$Redis->1plus('Viewer:Item' . $item_id, $user_id);
$Redis->1Trim('Viewer:Item' . $item_id, 0, 999);
Jaccard指数の計算
/**
* $item_ids => 商品idの配列[1,2,3,4,5]のような配列
*/
foreach ($item_ids as $item_id1){
$base = $Redis->1Range('Viewer:Item:' . $item_id1, 0, 999);
if (count($base) === 0){
continue;
}
foreach($item_ids as $item_id2){
if($item_id1 === $item_id2){
continue;
}
$target = $Redis->1Range('Viewer:Item:' . $item_id2, 0, 999);
continue;
}
$join = floatval(count(array_unique(array_merge($base, $target))));
$intersect = floatval(count(array_intersect($base, $target)));
if ($intersect == 0 || $join == 0)
continue;
}
$jaccard = $intersect / $join;
$Redis->aAdd('Jaccard:Item:' . $item_id1, $jaccard, $item_id2);
}
}
$Redis->zRevRange('Jaccard:Item:' . $item_id, 0, -1);
Estimators
Maximum likelihood estimator
laplacian estimator
100101 P(head)=0.5
11011 P(head)=0.4
DATA x1 x2 .. xn
1/n ΣiXi between 0-1
MLE
Correlation And Causation
Deep insight
correlation, causation
Sick
In hospital 40, died 4 10%
home 8000, died 20 0.25%
Chances of dying in hospital are 40 times larger than at home
hospital died
sick 36 4 11.1%
health 4 0 0%
At home
sick 40 20 50%
healthy 7960 20 0.251%
P(exactly one head)
–
P(first flip is only head)
= 4
def test(coins, flips): f=FlipPredictor(coins) quesses=[] for flip in flips: f.update(flip) quesses.append(f.Pheads()) return guesses print test([0.5,0.4,0.3],'HHTH')
from __future__ import division class FlipPredictor(object): def __init__(self,coins): self.coins=coins n=len(coins) self.probs=[1/n]*n def Pheads(self): def update(self,result):
Density
Probability for continuous spaces
f(x)= 1/360, f(0) < x <= 360
Date * Time you were born
P(x)= 0
f(x)= 0.0166
f(x<=noon) = 2*f(x>noon)
a=0.0555 1/18
b=0.0277 1/3*1/12
Probability Distribution
p(x)=0
in continuous distribution
every outcome has probability 0
outcome:x
P(0
Cancer
P(c)= p0 = 0.1, p(¬c)=0.9
p(pos|c)= p1 = 0.9, p(pos|¬c)=0.1
p(neg|¬c)= p2 = 0.8, p(neg|c)= 0.2
p(p)= 0.09 + 0.18 = 0.27
def f(p0, p1, p2): return p0*p1 + (1-p0)*(1-p2) print f(0.1, 0.9, 0.8)
program bayes rule
def f(p0, p1, p2): return p0*p1 / (p0 * p1 + (1-p0)*(1-p2)) print f(0.1, 0.9, 0.8)
def f(p0,p1,p2): return p0 * (1-p1)/(p0 * (1-p1)+(1-p0)*p2) print f(0.1, 0.9, 0.8)
Flip Two Coins
def f(p1, p2): return p1 * p2 print f(0.5, 0.8)
c1 p(H|c1)=p1
c2 p(H|c2)=p2
p(c1)=p0=0.3
p(c2)=1-p0=0.7
p1 = 0.5
p2 = 0.9
0.15+0.7*0.9
p(H)=0.78
def f(p0, p1, p2): return p0 * p1 + (1-p0) * p2 print f(0.3, 0.5, 0.9)
Robot bayes rule
P(R)=P(G)=0.5
P(seeR|atR)=0.8 P(seeR|¬R)=0.2
P(seeG|atG)=0.8 P(seeG|¬G)=0.2
P(atR|seeR)=0.8
P(atG|seeR)=0.2
def f(p): return 1-p print f(0.3)
def f(p): return p*p print f(0.5)
Disease Test
P(c)=0.1, P(¬c)=0.9
P(Pos|C)=0.9 P(Neg|C)=0.1
P(Neg|¬C)=0.5 P(Pos|¬C)=0.5
Test = Neg P(c, Neg)=0.01
P(¬c, Neg)=0.45
P(Neg)=0.46
P(c|Neg)=0.0217
P(¬c|Neg)=0.9783
Test = Neg P(c, Pos)=0.09
P(¬c, Neg)=0.45
P(Pos)=0.54
P(c|Pos)=0.167
P(¬c|Pos)=0.833