TensorFlow实战——使用LSTM预测彩票

原创文章,转载请注明出处:
http://blog.csdn.net/chengcheng1394/article/details/78756522
请安装TensorFlow1.0,Python3.5,seaborn
项目地址:
https://github.com/chengstone/LotteryPredict

前言

使用人工智能技术来预测彩票,是这次的主题,那么预测哪种彩票呢?我们先选择简单一些的,就是排列组合少一些的,如果证明我们的模型work,再扩展到其他的彩票上。最终我选择了排列三, 从000-999的数字中选取1个3位数,一共有1000种,中奖概率就是千分之一,够简单了吧。
历史数据在这里
数据是按照每期一组数的顺序排列的,从第一期到最新的一期,实际上是时间序列的数据。跟回归预测有很大的区别,因为特征上没有特殊的意义,不具备一组特征x映射到label y的条件。但是按照时间序列来训练的话就不一样了,输入x是一期的开奖结果,要学习的y是下一期的开奖结果。

LSTM介绍

我们需要从过往的历史数据中寻找规律,LSTM再适合不过了。如果你对LSTM不熟悉的话,以下几篇文章建议你阅读:
Understanding LSTM Networks
[译] 理解 LSTM 网络
RNN以及LSTM的介绍和公式梳理

看看数据集的结构

数据情况:
不重复单词(彩票开奖记录)的个数: 988
开奖期数: 4656期
行数: 4657
平均每行单词数: 1.0

开奖记录从 0 到 10:
202
243
580
306
598
900
761
262
891
623

一共4656条记录,4600多期了。共出现了988个不重复的结果,就是说还有(1000 – 988)12组数到现在还没有开出来过。文件中第一行是最新的一期,第二行是之前的一期,。。。,最后一行是第一期。
我们可以把三个数组合成一组数,就像数据集中体现的那样,并且把一组数当作一个数或者说当作一个单词。这样在预处理数据集的时候会简单一些,从索引到单词(0 -> ‘000’)和从单词到索引(‘012’-> 12)其实都是同一个数。

预测网络介绍

网络的输入是每一期的开奖结果,总共有1000组数,用one hot编码是一个1000维的稀疏向量:
这里写图片描述
使用one hot稀疏向量在输入层与网络第一层做矩阵乘法时会很没有效率,因为向量里面大部分都是0, 矩阵乘法浪费了大量的计算,最终矩阵运算得出的结果是向量中值为1的列所对应的矩阵中的行向量。
这里写图片描述
图片来源
这看起来很像用索引查表一样,one hot向量中值为1的位置作为下标,去索引参数矩阵中的行向量。
为了代替矩阵乘法,我们将参数矩阵当作一个查找表(lookup table)或者叫做嵌入矩阵(embedding matrix),将每组开奖数据所对应的数作为索引,比如“958”,对应索引就是958,然后在查找表中找第958行。
这里写图片描述
这其实跟替换之前的模型没有什么不同,嵌入矩阵就是参数矩阵,嵌入层仍然是隐层。查找表只是矩阵乘法的一种便捷方式,它会像参数矩阵一样被训练,是要学习的参数。
下面就是我们要构建的网络架构,从嵌入层输出的向量进入LSTM层进行时间序列的学习,然后经过softmax预测出下一期的开奖结果。
这里写图片描述
网络训练的代码,使用了几个trick,在下文<构建计算图>和<训练>章节会做说明,<结论>在最后。

主要代码讲解

完整代码请参见项目地址

实现数据预处理

首先要做的事是对数据进行预处理,要实现下面的函数:
Lookup Table

使用词向量之前,我们需要先准备好单词(彩票开奖记录)和ID之间的转换关系。在这个函数中,创建并返回两个字典:

  • 单词到ID的转换字典: vocab_to_int
  • ID到单词的转换字典: int_to_vocab
import numpy as np
from collections import Counter

def create_lookup_tables():
    """
    Create lookup tables for vocabulary
    :param text: The text of tv scripts split into words
    :return: A tuple of dicts (vocab_to_int, int_to_vocab)
    """
    vocab_to_int = {str(ii).zfill(3) : ii for ii in range(1000)}
    int_to_vocab = {ii : str(ii).zfill(3) for ii in range(1000)}
    return vocab_to_int, int_to_vocab

构建神经网络

输入

def get_inputs():
    """
    Create TF Placeholders for input, targets, and learning rate.
    :return: Tuple (input, targets, learning rate)
    """
    inputs = tf.placeholder(tf.int32, [None, None], name="input")
    targets = tf.placeholder(tf.int32, [None, None], name="targets")
    LearningRate = tf.placeholder(tf.float32)
    return inputs, targets, LearningRate

构建RNN单元并初始化
将一个或多个BasicLSTMCells 叠加在MultiRNNCell中,这里我们使用2层LSTM cell。

def get_init_cell(batch_size, rnn_size):
    """
    Create an RNN Cell and initialize it.
    :param batch_size: Size of batches
    :param rnn_size: Size of RNNs
    :return: Tuple (cell, initialize state)
    """
    lstm_cell = tf.contrib.rnn.BasicLSTMCell(rnn_size)#num_units=embed_dim
    cell = tf.contrib.rnn.MultiRNNCell([lstm_cell] * 2)
    InitialState = cell.zero_state(batch_size, tf.float32)
    InitialState = tf.identity(InitialState, name="initial_state")
    return cell, InitialState

词嵌入

  • embed_matrix:嵌入矩阵,后面计算相似度(距离)的时候会用到。
  • embed_layer:从嵌入矩阵(查找表)中索引到的向量。
def get_embed(input_data, vocab_size, embed_dim):
    """
    Create 
  • 46
    点赞
  • 315
    收藏
    觉得还不错? 一键收藏
  • 55
    评论
评论 55
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值