In [1]:
%matplotlib inline

In [2]:
import numpy as np
import pandas as pd

# 統計用ツール
import statsmodels.api as sm
import statsmodels.tsa.api as tsa
from patsy import dmatrices

#描画
import matplotlib.pyplot as plt
from pandas.tools.plotting import autocorrelation_plot

#株価
import pandas as pd
import pandas_datareader.data as web
import datetime

#深層学習
import chainer
from chainer import cuda, Function, gradient_check, Variable, optimizers, serializers, utils
from chainer import Link, Chain, ChainList
import chainer.functions as F
import chainer.links as L

#k平均法
from sklearn.cluster import KMeans

In [4]:
s = (1990, 1, 1)
e = (2015, 9, 30)
t = 'Adj Close'
start = datetime.datetime(s[0], s[1], s[2])
end = datetime.datetime(e[0], e[1], e[2])
SaP = web.DataReader('GSPC', 'yahoo', start, end)[t]
N225 = web.DataReader('^N225', 'yahoo', start, end)[t]
DJI = web.DataReader('^DJI', 'yahoo', start, end)[t]
IXIC = web.DataReader('^IXIC', 'yahoo', start, end)[t]

In [5]:
SaP = np.array([SaP[1:].values - SaP[:-1].values]).T*100

In [6]:
def fuzzy(SaP):
    kms = KMeans(n_clusters=3).fit_predict(SaP)

    mean1 = SaP[kms == 0].mean()
    var1 = SaP[kms == 0].var()
    mean2 = SaP[kms == 1].mean()
    var2 = SaP[kms == 1].var()
    mean3 = SaP[kms == 2].mean()
    var3 = SaP[kms == 2].var()

    for t in range(100):
        f = SaP[t:t+20]

        v = np.array([])
        for i in range(20):
            v1 = np.round(np.exp(-1*(f[i] - mean1)**2/var1), 5)
            v2 = np.round(np.exp(-1*(f[i] - mean2)**2/var2), 5)
            v3 = np.round(np.exp(-1*(f[i] - mean3)**2/var3), 5)
            v = np.append(v, v1)
            v = np.append(v, v2)
            v = np.append(v, v3)

        if t != 0:
            fs = np.c_[fs, v]
        else:
            fs = np.array([v]).T
    return fs

In [87]:
class DRNN(object):
    def __init__(self, data):
        self.data = data
        self.model = DeepLearning()
        self.optimizer = optimizers.Adam()
        self.optimizer.setup(self.model)
        
    def fuzzy(self):
        self.fs = fuzzy(self.data).T
        
    def autoencorder(self, num):
        ft = np.array(self.fs, dtype='float32')
        
        n, m = ft.shape
        bs = 5
        
        for j in range(num):
            sffindx = np.random.permutation(n)
            for i in range(0, n, bs):
                self.ib = i+bs
                x = Variable(ft[sffindx[i:(i+bs) if (i+bs) < n else n]])
                self.model.zerograds()
                loss = self.model.ae(x)
                loss.backward()
                self.optimizer.update()
            if j % 1000 == 0:
                print('epoch:', j)
                print('train mean loss={}'.format(loss.data))
                print(' - - - - - - - - - ')
            
    def reinforcement(self, n):
        for i in range(n):
            self.optimizer = optimizers.Adam()
            self.optimizer.setup(self.model)
            for t in range(100):
                loss = self.model.rnn(self.fs, t)
                loss.backward()
                self.optimizer.update()
            print('epoch:', i)
            print('profit={}'.format(-loss.data[0][0]))
            print(' - - - - - - - - - ')
        
    def initialization(self, n=3000, m=100):
        self.fuzzy()
        self.autoencorder(n)
        self.reinforcement(m)
        
    def learning(self, maxc=10):
        c = 0
        while c < maxc:
            for t in range(100):
                loss = self.model(self.fs, t)
                loss.backward()
                self.optimizer.update()
                print('epoch:', c)
                print('time:', t)
                print('profit={}'.format(-loss.data[0][0]))
                print(' - - - - - - - - - ')
                c += 1
            
    def strategy():
        self.model.delta(self.fs)

In [88]:
class DeepLearning(chainer.Chain):
    def __init__(self):
        super(DeepLearning, self).__init__(
            w = L.Linear(20, 1),
            b = L.Linear(1, 1),
            u = L.Linear(1, 1),
            l1 = L.Linear(60, 60),
            l2 = L.Linear(60, 60),
            l3 = L.Linear(60, 60),
            l4 = L.Linear(60, 20),
            l5 = L.Linear(20, 60),
            m1 = L.Linear(1, 60),
            m2 = L.Linear(1, 60),
            m3 = L.Linear(1, 60),
            m4 = L.Linear(1, 20),
        )
    
    def ae(self, x):
        bv, fv = self.ae_fwd(x)
        loss = F.mean_squared_error(bv, x)
        return loss
    
    def ae_fwd(self, x):
        h1 = F.sigmoid(self.l1(x))
        h2 = F.sigmoid(self.l2(h1))
        h3 = F.sigmoid(self.l3(h2))
        fv = F.sigmoid(self.l4(h3))
        bv = self.l5(fv)
        return bv, fv
    
    def rnn(self, fs, t, c=1):
        fs = np.array(fs, dtype='float32')
        bv, Fs = self.ae_fwd(Variable(fs))        
        Fs = Fs.data
        
        d_1 = Variable(np.zeros((1, 1), dtype=np.float32))
        old_grad = np.array([np.zeros(21)], dtype='float32')
        one = Variable(np.array([[1]], dtype=np.float32))
        zero = Variable(np.array([[0]], dtype=np.float32))

        loss = 0
        for i in range(len(Fs[:, 0])):
            x_k = Variable(np.array([Fs[i]], dtype=np.float32))
            d = F.tanh(self.w(x_k) + self.b(one) + self.u(d_1))
            z = Variable(np.array([[Fs[i][-1]]], dtype=np.float32))
            R = d_1.__rmatmul__(z) - c*(d - d_1).__abs__()
            loss += R
            d_1 = d
        return -loss
    
    def delta(self, Fs):
        one = Variable(np.array([[1]], dtype=np.float32))

        d_1 = Variable(np.zeros((1, 1), dtype=np.float32))
        d = np.zeros(100)
        d[0] = 1
        for i in range(1, len(Fs[:, 0])):
            Ft = Variable(np.array([Fs[i]], dtype=np.float32))
            ds = F.tanh(self.w(Ft) + self.b(one) + self.u(d_1))
            d[i] = ds.data[0]
        return d
        
    def __call__(self, fs, t, c=1):
        fs = np.array(fs, dtype='float32')
        bv, Fs = self.ae_fwd(Variable(fs))
        Fs_Var = Fs
        
        d_1 = Variable(np.zeros((1, 1), dtype=np.float32))
        old_grad = np.array([np.zeros(21)], dtype='float32')
        one = Variable(np.array([[1]], dtype=np.float32))
        zero = Variable(np.array([[0]], dtype=np.float32))
        loss = 0
        
        Fs = Fs.data
        for i in range(len(Fs[:, 0])):
            d = self.delta(Fs_Var.data).data
            if i == t:
                ft = Variable(np.array([fs[t]], dtype=np.float32))
                d = Variable(np.array([[d[t]]], dtype=np.float32))
                h1 = F.sigmoid(self.l1(ft) + self.m1(d)) 
                h2 = F.sigmoid(self.l2(h1) + self.m2(d))
                h3 = F.sigmoid(self.l3(h2) + self.m3(d))
                Ft = F.sigmoid(self.l4(h3) + self.m4(d)) 
                d = F.tanh(self.w(Ft) + self.b(one) + self.u(d_1))
                z = Variable(np.array([[Fs[i][-1]]], dtype=np.float32))
                R = d_1.__rmatmul__(z) - c*(d - d_1).__abs__()
                loss += R
                d_1 = d
            else:
                Ft = Variable(np.array([Fs[i]], dtype=np.float32))
                d = F.tanh(self.w(Ft) + self.b(one) + self.u(d_1))
                z = Variable(np.array([[Fs[i][-1]]], dtype=np.float32))
                R = d_1.__rmatmul__(z) - c*(d - d_1).__abs__()
                loss += R
                d_1 = d
        return -loss

In [91]:
drnn = DRNN(SaP)
drnn.initialization()


epoch: 0
train mean loss=0.3211595118045807
 - - - - - - - - - 
epoch: 1000
train mean loss=0.008461804129183292
 - - - - - - - - - 
epoch: 2000
train mean loss=0.007551076356321573
 - - - - - - - - - 
epoch: 0
profit=51.91835403442383
 - - - - - - - - - 
epoch: 1
profit=95.23589324951172
 - - - - - - - - - 
epoch: 2
profit=97.85733795166016
 - - - - - - - - - 
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-91-52e8439c874b> in <module>()
      1 drnn = DRNN(SaP)
----> 2 drnn.initialization()

<ipython-input-87-46eda291c970> in initialization(self, n, m)
     44         self.fuzzy()
     45         self.autoencorder(n)
---> 46         self.reinforcement(m)
     47 
     48     def learning(self, maxc=10):

<ipython-input-87-46eda291c970> in reinforcement(self, n)
     34             self.optimizer.setup(self.model)
     35             for t in range(100):
---> 36                 loss = self.model.rnn(self.fs, t)
     37                 loss.backward()
     38                 self.optimizer.update()

<ipython-input-88-25277be73f52> in rnn(self, fs, t, c)
     42         for i in range(len(Fs[:, 0])):
     43             x_k = Variable(np.array([Fs[i]], dtype=np.float32))
---> 44             d = F.tanh(self.w(x_k) + self.b(one) + self.u(d_1))
     45             z = Variable(np.array([[Fs[i][-1]]], dtype=np.float32))
     46             R = d_1.__rmatmul__(z) - c*(d - d_1).__abs__()

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/links/connection/linear.py in __call__(self, x)
     90             with cuda.get_device(self._device_id):
     91                 self._initialize_params(x.size // x.shape[0])
---> 92         return linear.linear(x, self.W, self.b)

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/functions/connection/linear.py in linear(x, W, b)
     77         return LinearFunction()(x, W)
     78     else:
---> 79         return LinearFunction()(x, W, b)

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/function.py in __call__(self, *inputs)
    187 
    188         if self.type_check_enable:
--> 189             self._check_data_type_forward(in_data)
    190 
    191         hooks = chainer.get_function_hooks()

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/function.py in _check_data_type_forward(self, in_data)
    271         in_type = type_check.get_types(in_data, 'in_types', False)
    272         try:
--> 273             self.check_type_forward(in_type)
    274         except type_check.InvalidType as e:
    275             msg = """

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/functions/connection/linear.py in check_type_forward(self, in_types)
     26             b_type = in_types[2]
     27             type_check.expect(
---> 28                 b_type.dtype == x_type.dtype,
     29                 b_type.ndim == 1,
     30                 b_type.shape[0] == w_type.shape[0],

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in f(x, y)
     75 
     76 def _make_bool_operator(exp, inv, func):
---> 77     def f(x, y):
     78         return BoolBinaryOperator(x, y, exp, inv, func)
     79     return f

KeyboardInterrupt: 

In [92]:
drnn.learning()


epoch: 0
time: 0
profit=97.97662353515625
 - - - - - - - - - 
epoch: 1
time: 1
profit=97.97737121582031
 - - - - - - - - - 
epoch: 2
time: 2
profit=97.97809600830078
 - - - - - - - - - 
epoch: 3
time: 3
profit=97.97891235351562
 - - - - - - - - - 
epoch: 4
time: 4
profit=97.979736328125
 - - - - - - - - - 
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-92-e9875fbd549d> in <module>()
----> 1 drnn.learning()

<ipython-input-87-46eda291c970> in learning(self, maxc)
     50         while c < maxc:
     51             for t in range(100):
---> 52                 loss = self.model(self.fs, t)
     53                 loss.backward()
     54                 self.optimizer.update()

<ipython-input-88-25277be73f52> in __call__(self, fs, t, c)
     74         Fs = Fs.data
     75         for i in range(len(Fs[:, 0])):
---> 76             d = self.delta(Fs_Var.data).data
     77             if i == t:
     78                 ft = Variable(np.array([fs[t]], dtype=np.float32))

<ipython-input-88-25277be73f52> in delta(self, Fs)
     57         for i in range(1, len(Fs[:, 0])):
     58             Ft = Variable(np.array([Fs[i]], dtype=np.float32))
---> 59             ds = F.tanh(self.w(Ft) + self.b(one) + self.u(d_1))
     60             d[i] = ds.data[0]
     61         return d

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/links/connection/linear.py in __call__(self, x)
     90             with cuda.get_device(self._device_id):
     91                 self._initialize_params(x.size // x.shape[0])
---> 92         return linear.linear(x, self.W, self.b)

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/functions/connection/linear.py in linear(x, W, b)
     77         return LinearFunction()(x, W)
     78     else:
---> 79         return LinearFunction()(x, W, b)

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/function.py in __call__(self, *inputs)
    187 
    188         if self.type_check_enable:
--> 189             self._check_data_type_forward(in_data)
    190 
    191         hooks = chainer.get_function_hooks()

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/function.py in _check_data_type_forward(self, in_data)
    271         in_type = type_check.get_types(in_data, 'in_types', False)
    272         try:
--> 273             self.check_type_forward(in_type)
    274         except type_check.InvalidType as e:
    275             msg = """

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/functions/connection/linear.py in check_type_forward(self, in_types)
     28                 b_type.dtype == x_type.dtype,
     29                 b_type.ndim == 1,
---> 30                 b_type.shape[0] == w_type.shape[0],
     31             )
     32 

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in expect(*bool_exprs)
    465     for expr in bool_exprs:
    466         assert isinstance(expr, Testable)
--> 467         expr.expect()
    468 
    469 prod = Variable(numpy.prod, 'prod')

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in expect(self)
    429     def expect(self):
    430         left = self._eval_left()
--> 431         right = self._eval_right()
    432 
    433         if not self.func(left, right):

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in _eval_right(self)
    391 
    392     def _eval_right(self):
--> 393         return _eval_expr(self.rhs)
    394 
    395     def __str__(self):

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in _eval_expr(v)
    220 def _eval_expr(v):
    221     if isinstance(v, Expr):
--> 222         return v.eval()
    223     elif isinstance(v, list):
    224         return list(map(_eval_expr, v))

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in eval(self)
    332 
    333     def eval(self):
--> 334         return _eval_expr(self.obj)[_eval_expr(self.key)]
    335 
    336 

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in _eval_expr(v)
    220 def _eval_expr(v):
    221     if isinstance(v, Expr):
--> 222         return v.eval()
    223     elif isinstance(v, list):
    224         return list(map(_eval_expr, v))

/Users/masakato/anaconda/lib/python3.6/site-packages/chainer/utils/type_check.py in eval(self)
    296 
    297     def eval(self):
--> 298         return getattr(_eval_expr(self.obj), _eval_expr(self.name))
    299 
    300 

KeyboardInterrupt: 

In [93]:
bv, Ft = drnn.model.ae_fwd(np.array(drnn.fs, dtype=np.float32))
drnn.model.delta(Ft.data)


Out[93]:
array([ 1.        ,  0.99993312,  0.99993312,  0.999933  ,  0.99993306,
        0.99993306,  0.99993312,  0.99993312,  0.99993306,  0.999933  ,
        0.99993312,  0.99993306,  0.99993312,  0.999933  ,  0.99993306,
        0.99993312,  0.99993318,  0.99993306,  0.99993312,  0.99993306,
        0.99993306,  0.99993312,  0.99993312,  0.99993312,  0.99993306,
        0.99993306,  0.99993312,  0.99993294,  0.99993312,  0.99993306,
        0.99993312,  0.99993306,  0.99993306,  0.99993312,  0.99993306,
        0.99993306,  0.99993306,  0.99993312,  0.99993312,  0.99993312,
        0.99993306,  0.99993306,  0.99993306,  0.99993306,  0.999933  ,
        0.99993294,  0.99993312,  0.99993312,  0.99993318,  0.99993312,
        0.999933  ,  0.99993306,  0.99993294,  0.999933  ,  0.999933  ,
        0.99993306,  0.99993318,  0.99993289,  0.99993306,  0.99993312,
        0.99993318,  0.999933  ,  0.99993306,  0.99993312,  0.999933  ,
        0.99993312,  0.99993312,  0.99993306,  0.99993294,  0.99993318,
        0.99993306,  0.99993306,  0.999933  ,  0.99993306,  0.99993312,
        0.99993306,  0.999933  ,  0.99993306,  0.99993318,  0.99993312,
        0.999933  ,  0.999933  ,  0.99993312,  0.99993306,  0.99993294,
        0.999933  ,  0.99993306,  0.99993312,  0.99993324,  0.999933  ,
        0.99993306,  0.99993318,  0.99993312,  0.99993312,  0.99993306,
        0.99993312,  0.99993306,  0.99993306,  0.99993306,  0.99993318])