summaryrefslogtreecommitdiffstats
path: root/hw3/2.py
blob: 6ccbcfd5abcec6e8d5bb44ceff4595b051a271f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from numpy.random import normal
import numpy as np
from pickle import load
from random import shuffle


def init_vectors(K, sigma=0.01):
    U = normal(0, sigma, size=(n+1, K))
    V = normal(0, sigma, size=(m+1, K))
    return U, V


def init_vectors_bis(K, sigma=0.01):
    U = normal(0, sigma, size=(n+1, K))
    V = normal(0, sigma, size=(m+1, K))
    a = np.ones(n+1)
    b = np.ones(m+1)
    g = 1
    return U, V, a, b, g


def sgd_step(U, V, lamb=0.05, sigmas=1.0):
    keys = train.keys()
    shuffle(keys)
    for (i, j) in keys:
        r = train[(i, j)]
        ui = np.copy(U[i])
        vj = np.copy(V[j])
        a = (lamb / sigmas) * (float(r) - np.inner(ui, vj))
        U[i] += a * vj
        V[j] += a * ui


def sgd_step_bis(U, V, a, b, g, lamb=0.05, sigmas=1.0):
    keys = train.keys()
    shuffle(keys)
    for (i, j) in keys:
        r = train[(i, j)]
        ui = np.copy(U[i])
        vj = np.copy(V[j])
        e = (lamb / sigmas) * (float(r) - np.inner(ui, vj) - a[i] - b[j] - g)
        U[i] += e * vj
        V[j] += e * ui
        a[i] += e
        b[j] += e
        g += e
    return g


def mse(U, V, d):
    serror = sum((float(r) - np.inner(U[i], V[j])) ** 2
                 for (i, j), r in d.iteritems())
    return serror / len(d)


def mse_bis(U, V, a, b, g, d):
    serror = sum((float(r) - np.inner(U[i], V[j]) - a[i] - b[j] - g) ** 2
                 for (i, j), r in d.iteritems())
    return serror / len(d)


def part_c():
    for K in xrange(1, 11):
        U, V = init_vectors(K)
        for t in xrange(10):
            sgd_step(U, V)
        print K, mse(U, V, train), mse(U, V, test)


def part_d():
    U, V, a, b, g = init_vectors_bis(2)
    for t in xrange(10):
        print t
        g = sgd_step_bis(U, V, a, b, g)
    print g
    i = range(len(b))
    mi = min(i, key=lambda x: b[x])
    ma = max(i, key=lambda x: b[x])
    print mi, b[mi]
    print ma, b[ma]
    print mse_bis(U, V, a, b, g, train), mse_bis(U, V, a, b, g, test)


if __name__ == "__main__":
    n, m, train, test = load(open("data.pickle", "rb"))
    part_d()