CW-RNN收益率時間序列回歸

內(nèi)容來自:A Clockwork RNN
Jan Koutník, Klaus Greff, Faustino Gomez, Jürgen Schmidhuber

360截圖20170629152646685.jpg

CW-RNN是一個帶時鐘頻率的RNN變種目胡,似乎是對回歸有不錯的效果测垛,不過這個有爭論太示。對一個時間序列砰琢,無論是回歸還是分類都是將數(shù)據(jù)經(jīng)過循環(huán)按照時間序列輸入驾茴,RNN使用隱藏矩陣進行記憶,然后判定輸出销凑。針對原始RNN對長序列記憶效果極差溉苛,作者在這里設(shè)計了一種將隱藏狀態(tài)矩陣(記憶機制)分割成g個小模塊并使用類時鐘頻率掩碼的方式,將RNN的記憶分割成幾個部分签餐,然后經(jīng)過特定設(shè)計寓涨,使CW-RNN記憶矩陣中每個部分處理不同的時刻的數(shù)據(jù),加強記憶效果氯檐。

在論文中作者列舉的數(shù)據(jù)顯示這種設(shè)計在特定的應用中具有更優(yōu)的效果缅茉。例如,對一個長度為L的時間序列進行預測男摧,在使用CW-RNN的時候可以通過設(shè)置時鐘頻率人工設(shè)定記憶序列蔬墩。如,L長度為36耗拓,那我們可以設(shè)置CW為[1,2,4,8,16,12,18,36]拇颅,這相當于在長度為36的序列設(shè)置了多個記憶點,每個記憶點基于此記憶點之前的輸入值進行抽象記憶乔询。這個設(shè)計與RNN經(jīng)典變種LSTM有巨大的差異樟插。LSTM通過gate結(jié)構(gòu)實現(xiàn)自動的記憶選擇汲取,這里的CW設(shè)計需要有一種類似于先驗值的CW設(shè)定,這并不是一種十分優(yōu)雅的設(shè)計黄锤。但這種設(shè)計增加的人工設(shè)定序列節(jié)點選取的操作空間搪缨,應該可以在一定程度上對標收益率的時間序列進行特別設(shè)計,從而取得不錯的回歸效果鸵熟。

該設(shè)計進行時間序列回歸擬合副编,在取局部圖的時候可以觀察到,LSTM的回歸效果相對平滑流强,而CW-RNN并沒有這種缺陷痹届。

360截圖20170629152817533.jpg
import numpy as np
import pandas as pd
# import statsmodels.api as sm
import tensorflow as tf
# import matplotlib.pylab as plt
import seaborn as sns
# %matplotlib inline
sns.set_style('whitegrid')


class ClockworkRNN(object):
    def __init__(self,
                 in_length,
                 in_width,
                 out_width,
                 training_epochs=1e2,
                 batch_size=1024,
                 learning_rate=1e-4,
                 hidden_neurons=360,
                 Rb=60,
                 Ti=2,
                 Ti_sum=6,
                 display=1e2):
        #
        self.in_length = in_length
        self.in_width = in_width
        self.out_width = out_width
        self.batch_size = batch_size
        self.learning_rate = learning_rate
        self.display = display
        #
        self.hidden_neurons = hidden_neurons
        self.Rb = Rb
        self.Ti = Ti
        self.Ti_sum = Ti_sum
        self.clockwork_periods = [self.Ti ** x for x in range(self.Ti_sum)]
        self.training_epochs = training_epochs
        self.inputs = tf.placeholder(dtype=tf.float32, shape=[None, self.in_length, self.in_width], name='inputs')
        self.targets = tf.placeholder(dtype=tf.float32, shape=[None, self.out_width], name='targets')
        #
        self.__inference()

        #  下三角掩碼矩陣,處理g-moduels劃分形成的上三角權(quán)重矩陣

    def __Mask_Matrix(self, W, k):
        length = np.int(W / k)
        tmp = np.ones([W, W])
        for i in range(length)[1:]:
            tmp[i * k:(i + 1) * k, :i * k] = 0
        tmp[(i + 1) * k:, :i * k] = 0
        return np.transpose(tmp)

    def __inference(self):
        self.sess = sess = tf.InteractiveSession()

        # 標準RNN初始權(quán)重
        with tf.variable_scope('input_layers'):
            self.WI = tf.get_variable('W', shape=[self.in_width, self.hidden_neurons],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
            self.bI = tf.get_variable('b', shape=[self.hidden_neurons],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))

        traingular_mask = self.__Mask_Matrix(self.hidden_neurons, self.Rb)
        self.traingular_mask = tf.constant(traingular_mask, dtype=tf.float32, name='mask_upper_traingular')
        with tf.variable_scope('hidden_layers'):
            self.WH = tf.get_variable('W', shape=[self.hidden_neurons, self.hidden_neurons],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
            self.WH = tf.multiply(self.WH, self.traingular_mask)
            self.bH = tf.get_variable('b', shape=[self.hidden_neurons],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))

        with tf.variable_scope('output_layers'):
            self.WO = tf.get_variable('W', shape=[self.hidden_neurons, self.out_width],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
            self.bO = tf.get_variable('b', shape=[self.out_width],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))

        # 輸入訓練數(shù)據(jù)轉(zhuǎn)換為列表
        X_list = [tf.squeeze(x, axis=[1]) for x
                  in tf.split(value=self.inputs, axis=1, num_or_size_splits=self.in_length, name='inputs_list')]

        with tf.variable_scope('clockwork_rnn') as scope:
            # 定義初始時刻的隱藏狀態(tài)打月,設(shè)定為全0
            self.state = tf.get_variable('hidden_sate', shape=[self.batch_size, self.hidden_neurons],
                                         initializer=tf.zeros_initializer(), trainable=False)
            for i in range(self.in_length):

                # 獲取g_moduels索引
                if i > 0:
                    scope.reuse_variables()
                g_counter = 0
                for j in range(self.Ti_sum):
                    if i % self.clockwork_periods[j] == 0:
                        g_counter += 1
                if g_counter == self.Ti_sum:
                    g_counter = self.hidden_neurons
                else:
                    g_counter *= self.Rb

                # t時刻eq1
                tmp_right = tf.matmul(X_list[i], tf.slice(self.WI, [0, 0], [-1, g_counter]))
                tmp_right = tf.nn.bias_add(tmp_right, tf.slice(self.bI, [0], [g_counter]))
                self.WH = tf.multiply(self.WH, self.traingular_mask)
                tmp_left = tf.matmul(self.state, tf.slice(self.WH, [0, 0], [-1, g_counter]))
                tmp_left = tf.nn.bias_add(tmp_left, tf.slice(self.bH, [0], [g_counter]))
                tmp_hidden = tf.tanh(tf.add(tmp_left, tmp_right))

                # 更新隱藏狀態(tài)
                self.state = tf.concat(axis=1, values=[tmp_hidden, tf.slice(self.state, [0, g_counter], [-1, -1])])

            self.final_state = self.state
            self.pred = tf.nn.bias_add(tf.matmul(self.final_state, self.WO), self.bO)
            # self.cost_sum = tf.reduce_sum(tf.square(self.targets - self.pred))
            self.cost = tf.reduce_sum(tf.square(self.targets - self.pred))
        self.optimizer = tf.train.AdamOptimizer(self.learning_rate).minimize(self.cost)
        self.sess.run(tf.global_variables_initializer())

    def fit(self, inputs, targets):
        sess = self.sess
        for step in range(np.int(self.training_epochs)):
            for i in range(np.int(len(targets) / self.batch_size)):
                batch_x = inputs[i * self.batch_size:(i + 1) * self.batch_size].reshape(
                    [self.batch_size, self.in_length, self.in_width])
                batch_y = targets[i * self.batch_size:(i + 1) * self.batch_size].reshape(
                    [self.batch_size, self.out_width])
                sess.run(self.optimizer, feed_dict={self.inputs: batch_x, self.targets: batch_y})
            if len(targets) % self.batch_size != 0:
                batch_x = inputs[-self.batch_size:].reshape([self.batch_size, self.in_length, self.in_width])
                batch_y = targets[-self.batch_size:].reshape([self.batch_size, self.out_width])
                sess.run(self.optimizer, feed_dict={self.inputs: batch_x, self.targets: batch_y})
            if step % self.display == 0:
                print(sess.run(self.cost, feed_dict={self.inputs: batch_x, self.targets: batch_y}))

    def prediction(self, inputs):
        sess = self.sess
        tmp = np.zeros(self.out_width)
        for i in range(np.int(len(inputs) / self.batch_size)):
            batch_x = inputs[i * self.batch_size:(i + 1) * self.batch_size].reshape(
                [self.batch_size, self.in_length, self.in_width])
            tmp = np.vstack((tmp, sess.run(self.pred, feed_dict={self.inputs: batch_x})))
        if len(inputs) % self.batch_size != 0:
            batch_x = inputs[-self.batch_size:].reshape([self.batch_size, self.in_length, self.in_width])
            tp = np.vstack((tmp, sess.run(self.pred, feed_dict={self.inputs: batch_x})))
            l = len(targets) % self.batch_size
            tp = tp[-l:]
            tmp = np.vstack((tmp, tp))
        tmp = np.delete(tmp, 0, 0)
        return tmp


tmp = pd.read_csv('SHCOMP.csv')
tmp['trading_moment'] = pd.to_datetime(tmp['DATE'].values)
tmp.set_index('trading_moment', drop=True, inplace=True)
tmp['Returns'] = np.log(tmp.Close.shift(-10) / tmp.Close)
tmp.dropna(inplace=True)
tp = np.array(tmp['Returns'])
# del tmp['Unnamed: 0']

in_length = 36
out_length = 1
inputs = np.zeros(in_length)
targets = np.zeros(1)
for i in range(len(tp))[in_length:-out_length]:
    m = tp[i - in_length:i]
    R = tp[i:i + 1]
    inputs = np.vstack((inputs, m))
    targets = np.vstack((targets, R))
targets = np.delete(targets, 0, 0)
inputs = np.delete(inputs, 0, 0)

T_inputs = inputs[:512]
T_targets = targets[:512]

a = ClockworkRNN(36, 1, 1, training_epochs=2e4, batch_size=512)
a.fit(T_inputs, T_targets)

outputs = a.prediction(T_inputs)
CW_RNN = outputs
show = pd.DataFrame([T_targets.ravel('C'), outputs.ravel('C')]).T
show.plot()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末队腐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子奏篙,更是在濱河造成了極大的恐慌柴淘,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秘通,死亡現(xiàn)場離奇詭異悠就,居然都是意外死亡慎式,警方通過查閱死者的電腦和手機臊岸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來繁涂,“玉大人盹靴,你說我怎么就攤上這事炸茧。” “怎么了稿静?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵梭冠,是天一觀的道長。 經(jīng)常有香客問我改备,道長控漠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任悬钳,我火速辦了婚禮盐捷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘默勾。我一直安慰自己碉渡,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布母剥。 她就那樣靜靜地躺著滞诺,像睡著了一般形导。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上习霹,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天朵耕,我揣著相機與錄音,去河邊找鬼淋叶。 笑死阎曹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的爸吮。 我是一名探鬼主播芬膝,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼望门,長吁一口氣:“原來是場噩夢啊……” “哼形娇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起筹误,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桐早,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厨剪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哄酝,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年祷膳,在試婚紗的時候發(fā)現(xiàn)自己被綠了陶衅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡直晨,死狀恐怖搀军,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勇皇,我是刑警寧澤罩句,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站敛摘,受9級特大地震影響门烂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兄淫,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一屯远、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捕虽,春花似錦氓润、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挨措。三九已至,卻和暖如春崩溪,著一層夾襖步出監(jiān)牢的瞬間浅役,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工伶唯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留觉既,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓乳幸,卻偏偏與公主長得像瞪讼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子粹断,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容