基于steam的游戏销量预测 — PART 3 — 基于BP神经网络的机器学习与预测
语言:c++
环境:windows
训练内容:根据从steam中爬取的数据经过文本分析制作的向量以及标签
使用相关:无
解释:
就是一个BP神经网络,借鉴参考了一些博客的解释和代码,具体哪些忘了,给出其中一个:
http://blog.csdn.net/zhongkejingwang/article/details/44514073
代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#define TAG_NUM 200
#define VEC_NUM 216
#define BASE_SCORE 5
#define MX_STR 2400
#define DIV 1000000.0
#define INF (1e9 + 44)
using namespace std;
namespace BPnamespace
{
#define IN_NODE_NUM 216 //输入节点数
#define HIDDEN_NODE_NUM 24 //隐含节点数
#define HIDDEN_LAYER_NUM 1 //隐含层数
#define OUT_NODE_NUM 9 //输出节点数
#define LEARNING_RATE 0.03 //学习速率
#define MAX_RAND_SEG (int)144e4
inline double xrand() // 0.1 ~ -0.1
{
) / 10.0;
}
inline double sigmoid(double x) //sigmoid
{
/ ( + exp(-x));
return ret;
}
struct InputNode
{
double value; //固定输入值
vector<double> weight; //到首个隐含层权值
vector<double> wdelta_sum; //到首个隐含层权值的delta值累积
InputNode()
{
weight.clear();
wdelta_sum.clear();
}
};
struct OutputNode
{
double value;
double delta; //与正确值之间的偏差值
double rightout; //正确值
double bias; //偏移量
double bdelta_sum; //bias的delta累积
OutputNode(){ }
};
struct HiddenNode
{
double value;
double delta; //BP推导出的delta
double bias; //偏移量
double bdelta_sum; //bias的delta值累积
vector<double> weight; //对于下一层的每个节点的权值
vector<double> wdelta_sum; //对于下一层的权值delta累积
HiddenNode()
{
weight.clear();
wdelta_sum.clear();
}
};
struct RandSegNode
{
int id, val;
} rand_seg[MAX_RAND_SEG];
struct Sample
{
vector<double> in, out;
};
bool cmpRandSeg(RandSegNode a,RandSegNode b)
{
return a.val < b.val;
}
class BP
{
public:
double error;
InputNode* input_layer[IN_NODE_NUM];
OutputNode* output_layer[OUT_NODE_NUM];
HiddenNode* hidden_layer[HIDDEN_LAYER_NUM][HIDDEN_NODE_NUM];
void load()
{
string file_name = "data\\data.txt";
ifstream infile(file_name.c_str(), ios::in);
; i < IN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
infile >> input_layer[i]->weight[j];
; k < HIDDEN_LAYER_NUM - ; k++)
; i < HIDDEN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
infile >> hidden_layer[k][i]->weight[j];
; i < HIDDEN_NODE_NUM; i++)
; j < OUT_NODE_NUM; j++)
infile >> hidden_layer[HIDDEN_LAYER_NUM - ][i]->weight[j];
; k < HIDDEN_LAYER_NUM; k++)
; i < HIDDEN_NODE_NUM; i++)
infile >> hidden_layer[k][i]->bias;
; i < OUT_NODE_NUM; i++)
infile >> output_layer[i]->bias;
}
void write()
{
string file_name = "data\\data.txt";
ofstream outfile(file_name.c_str(), ios::out);
; i < IN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
outfile << input_layer[i]->weight[j] << ' ';
; k < HIDDEN_LAYER_NUM - ; k++)
; i < HIDDEN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
outfile << hidden_layer[k][i]->weight[j] << ' ';
; i < HIDDEN_NODE_NUM; i++)
; j < OUT_NODE_NUM; j++)
outfile << hidden_layer[HIDDEN_LAYER_NUM - ][i]->weight[j] << ' ';
; k < HIDDEN_LAYER_NUM; k++)
; i < HIDDEN_NODE_NUM; i++)
outfile << hidden_layer[k][i]->bias << ' ';
; i < OUT_NODE_NUM; i++)
outfile << output_layer[i]->bias << ' ';
}
BP()
{
srand((unsigned)time(NULL));
error = ;
//初始化输入层
; i < IN_NODE_NUM; i++)
{
input_layer[i] = new InputNode();
; j < HIDDEN_NODE_NUM; j++)
{
input_layer[i]->weight.push_back(xrand());
input_layer[i]->wdelta_sum.push_back();
}
}
//初始化隐藏层
; i < HIDDEN_LAYER_NUM; i++)
{
)
{
; j < HIDDEN_NODE_NUM;j++)
{
hidden_layer[i][j] = new HiddenNode();
hidden_layer[i][j]->bias = ;
; k < OUT_NODE_NUM; k++)
{
hidden_layer[i][j]->weight.push_back(xrand());
hidden_layer[i][j]->wdelta_sum.push_back();
}
}
}
else
{
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j] = new HiddenNode();
hidden_layer[i][j]->bias = ;
; k < HIDDEN_NODE_NUM; k++)
hidden_layer[i][j]->weight.push_back(xrand());
}
}
}
//初始化输出层
; i < OUT_NODE_NUM; i++)
{
output_layer[i] = new OutputNode();
output_layer[i]->bias = ;
}
}
void forwardPropagationEpoc() //单个样本 向前传播
{
//输入层->隐含层 隐含层->隐含层
; i < HIDDEN_LAYER_NUM; i++)
{
)
{
; j < HIDDEN_NODE_NUM; j++)
{
;
; k < IN_NODE_NUM; k++)
sum += input_layer[k]->value * input_layer[k]->weight[j];
sum += hidden_layer[i][j]->bias;
hidden_layer[i][j]->value = sigmoid(sum);
}
}
else
{
; j < HIDDEN_NODE_NUM; j++)
{
;
; k < HIDDEN_NODE_NUM; k++)
sum += hidden_layer[i - ][k]->value*hidden_layer[i - ][k]->weight[j];
sum += hidden_layer[i][j]->bias;
hidden_layer[i][j]->value = sigmoid(sum);
}
}
}
//隐含层->输出层
; i < OUT_NODE_NUM; i++)
{
;
; j < HIDDEN_NODE_NUM; j++)
sum += hidden_layer[HIDDEN_LAYER_NUM - ][j]->value * hidden_layer[HIDDEN_LAYER_NUM - ][j]->weight[i];
sum += output_layer[i]->bias;
output_layer[i]->value = sigmoid(sum);
}
//cout << "!!!" << ' ' << output_layer[0]->value << endl;
}
void backPropagationEpoc() //单个样本 向后传播
{
//输出层 计算delta
; i < OUT_NODE_NUM; i++)
{
double tmp = output_layer[i]->rightout - output_layer[i]->value;
error += tmp*tmp / ;
output_layer[i]->delta = tmp*( - output_layer[i]->value)*output_layer[i]->value;
}
//隐含层 计算delta
; i >= ; i--)
{
)
{
; j < HIDDEN_NODE_NUM; j++)
{
;
; k < OUT_NODE_NUM; k++)
sum += output_layer[k]->delta*hidden_layer[i][j]->weight[k];
hidden_layer[i][j]->delta = sum*( - hidden_layer[i][j]->value)*hidden_layer[i][j]->value;
}
}
else
{
; j < HIDDEN_LAYER_NUM; j++)
{
;
; k < HIDDEN_NODE_NUM; k++)
sum += hidden_layer[i + ][k]->delta*hidden_layer[i][j]->weight[k];
hidden_layer[i][j]->delta = sum*( - hidden_layer[i][j]->value)*hidden_layer[i][j]->value;
}
}
}
//输入层 更新 wdelta_sum
; i < IN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
input_layer[i]->wdelta_sum[j] += input_layer[i]->value*hidden_layer[][j]->delta;
//隐含层 更新 wdelta_sum 和 bdelta_sum
; i < HIDDEN_LAYER_NUM; i++)
{
)
{
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j]->bdelta_sum += hidden_layer[i][j]->delta;
; k < OUT_NODE_NUM; k++)
hidden_layer[i][j]->wdelta_sum[k] += hidden_layer[i][j]->value*output_layer[k]->delta;
}
}
else
{
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j]->bdelta_sum += hidden_layer[i][j]->delta;
; k < HIDDEN_NODE_NUM; k++)
hidden_layer[i][j]->wdelta_sum[k] += hidden_layer[i][j]->value*hidden_layer[i + ][k]->delta;
}
}
}
//输出层 更新 bdelta_sum
; i < OUT_NODE_NUM; i++)
output_layer[i]->bdelta_sum += output_layer[i]->delta;
}
void training(vector<Sample> sample_group, int cnt_bound) //更新weight,bias
{
int sample_num = sample_group.size();
; i < sample_num; i++)
rand_seg[i].id = i, rand_seg[i].val = rand();
sort(rand_seg, rand_seg + sample_num, cmpRandSeg);
// double error_bound;
// double last_error = -1;
;
int now_id;
while (cnt < cnt_bound)
{
// last_error = error;
error = ;
; i < IN_NODE_NUM; i++)
input_layer[i]->wdelta_sum.assign(input_layer[i]->wdelta_sum.size(), );
; i < HIDDEN_LAYER_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j]->wdelta_sum.assign(hidden_layer[i][j]->wdelta_sum.size(), );
hidden_layer[i][j]->bdelta_sum = ;
}
; i < OUT_NODE_NUM; i++)
output_layer[i]->bdelta_sum = ;
now_id = rand_seg[cnt%sample_group.size()].id;
setInput(sample_group[now_id].in);
setOutput(sample_group[now_id].out);
forwardPropagationEpoc();
backPropagationEpoc();
//输出层反向传递 更新 weight
; i < IN_NODE_NUM; i++)
; j < HIDDEN_NODE_NUM; j++)
input_layer[i]->weight[j] += LEARNING_RATE*input_layer[i]->wdelta_sum[j];
//隐含层反向传递 更新 weight 和 bias
; i < HIDDEN_LAYER_NUM; i++)
{
)
{
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j]->bias += LEARNING_RATE*hidden_layer[i][j]->bdelta_sum;
; k < OUT_NODE_NUM; k++)
hidden_layer[i][j]->weight[k] += LEARNING_RATE*hidden_layer[i][j]->wdelta_sum[k];
}
}
else
{
; j < HIDDEN_NODE_NUM; j++)
{
hidden_layer[i][j]->bias += LEARNING_RATE*hidden_layer[i][j]->bdelta_sum;
; k < HIDDEN_NODE_NUM; k++)
hidden_layer[i][j]->weight[k] += LEARNING_RATE*hidden_layer[i][j]->wdelta_sum[k];
}
}
}
//输出层反向传递 更新bias
; i < OUT_NODE_NUM; i++)
output_layer[i]->bias += LEARNING_RATE*output_layer[i]->bdelta_sum;
== )
{
printf("turn %d/%d finished \n", cnt, cnt_bound);
printf("training error: %lf\n", error);
}
}
}
void predict(vector<Sample>& test_group) //神经网络预测
{
int test_num = test_group.size();
; id < test_num; id++)
{
test_group[id].out.clear();
setInput(test_group[id].in);
//输入层->隐含层 隐含层->隐含层 正向传播
; i < HIDDEN_LAYER_NUM; i++)
{
)
{
; j < HIDDEN_NODE_NUM; j++)
{
;
; k < IN_NODE_NUM; k++)
sum += input_layer[k]->value*input_layer[k]->weight[j];
sum += hidden_layer[i][j]->bias;
hidden_layer[i][j]->value = sigmoid(sum);
}
}
else
{
; j < HIDDEN_NODE_NUM; j++)
{
;
; k < HIDDEN_NODE_NUM; k++)
sum += hidden_layer[i - ][k]->value*hidden_layer[i - ][k]->weight[j];
sum += hidden_layer[i][j]->bias;
hidden_layer[i][j]->value = sigmoid(sum);
}
}
}
; i < OUT_NODE_NUM; i++)
{
;
; j < HIDDEN_NODE_NUM; j++)
sum += hidden_layer[HIDDEN_LAYER_NUM - ][j]->value*hidden_layer[HIDDEN_LAYER_NUM - ][j]->weight[i];
sum += output_layer[i]->bias;
output_layer[i]->value = sigmoid(sum);
test_group[id].out.push_back(output_layer[i]->value);
}
}
}
void setInput(vector<double> sample_in) //设置学习样本输入
{
; i < IN_NODE_NUM; i++)
input_layer[i]->value = sample_in[i];
}
void setOutput(vector<double> sample_out) //设置学习样本输出
{
; i < OUT_NODE_NUM; i++)
output_layer[i]->rightout = sample_out[i];
}
};
}
using namespace BPnamespace;
BP bp;
vector<Sample> sample_group;
char ex_str[MX_STR];
int getRank(char num_str[])
{
;
; i < len; i++)
')
ret++;
// ret = ret * 10 + num_str[i] - '0';
return ret;
}
void part_train()
{
sample_group.clear();
char num_str[MX_STR];
int tol, num;
double tmp;
Sample now;
string infile_name = "training_data.txt";
ifstream infile(infile_name.c_str(), ios::in);
infile >> tol;
; i < tol; i++)
{
infile >> ex_str;
infile >> num;
now.in.clear(),now.out.clear();
; j < num; j++)
{
infile >> tmp;
now.in.push_back(tmp);
}
for(int j = num; j < VEC_NUM; j++)
now.in.push_back(BASE_SCORE);
infile >> num_str;
] == '-') continue;
num = getRank(num_str);
; j < OUT_NODE_NUM; j++)
if(j == num)
now.);
);
sample_group.push_back(now);
}
bp.training(sample_group,);
bp.write();
}
void part_predict()
{
sample_group.clear();
char num_str[MX_STR];
int tol, num;
double tmp;
Sample now;
string infile_name = "sample.txt";
ifstream infile(infile_name.c_str(), ios::in);
infile >> tol;
; i < tol; i++)
{
infile >> ex_str;
infile >> num;
now.in.clear(),now.out.clear();
; j < num; j++)
{
infile >> tmp;
now.in.push_back(tmp);
}
for(int j = num; j < VEC_NUM; j++)
now.in.push_back(BASE_SCORE);
infile >> num_str;
sample_group.push_back(now);
}
bp.predict(sample_group);
string outfile_name = "result.txt";
ofstream outfile(outfile_name.c_str(), ios::out);
; i < sample_group.size(); i++)
{
tmp = -INF;
now = sample_group[i];
; j < now.out.size(); j++)
if(now.out[j] > tmp)
tmp = now.out[j], num = j;
outfile << "id: " << i << " rank: " << num << endl;
cout << "id: " << i << " rank: " << num << endl;
}
}
int main()
{
int tp;
puts("input\n 0: load last trainning data\n 1: restart tranning\n 2: load last tranning data and continue trainning\n");
scanf("%d",&tp);
) bp.load();
) part_train();
) bp.load(), part_train();
;
part_predict();
system("pause");
;
}
基于steam的游戏销量预测 — PART 3 — 基于BP神经网络的机器学习与预测的更多相关文章
- 基于steam的游戏销量预测 — PART 1 — 爬取steam游戏相关数据的爬虫
语言:python 环境:ubuntu 爬取内容:steam游戏标签,评论,以及在 steamspy 爬取对应游戏的销量 使用相关:urllib,lxml,selenium,chrome 解释: 流程 ...
- Atitit 基于dom的游戏引擎
Atitit 基于dom的游戏引擎 1. 添加sprite控件(cocos,createjs,dom)1 1.1.1. Cocos1 1.1.2. createjs1 1.1.3. Dom模式2 1. ...
- 基于cocos2d-x的游戏框架设计——李成
视频:http://v.youku.com/v_show/id_XMzc5ODUyMTI4.html?f=17330006 网易科技讯 3月31日,第四届CocoaChina开发者大会暨Cocos2d ...
- 基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介
基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介 概述 Dorothy 是一个在 Cocos2d-x-lua 基础上发展起来的分支, 它去掉 Cocos2d-x-lua 那些过多 ...
- (14)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第二部分
引言 程序截图: 这篇教程是<如何使用Cocos2d-x 3.0制作基于tilemap的游戏>的第二部分.在上一个教程中,我们创建了一个简单的基于tiled地图的游戏,里面有一个忍者在沙漠 ...
- (13)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分
引言 程序截图: 本教程将会教大家如何使用Cocos2d-x来做一个基于tile地图的游戏,当然还有Tiled地图编辑器.(我们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦 ...
- BP神经网络算法预测销量高低
理论以前写过:https://www.cnblogs.com/fangxiaoqi/p/11306545.html,这里根据天气.是否周末.有无促销的情况,来预测销量情况. function [ ma ...
- R_Studio(神经网络)BP神经网络算法预测销量的高低
BP神经网络 百度百科:传送门 BP(back propagation)神经网络:一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络 #设置文件工作区间 setwd('D:\\ ...
- 基于Lua的游戏服务端框架简介
基于Lua的游戏服务端框架简介 [转]https://gameinstitute.qq.com/community/detail/106396 基于lua的游戏服务端框架简介 1. 引言 笔者目前在参 ...
随机推荐
- JVM —— 类文件结构(上)
一.概述 实现语言无关性的基础仍然是虚拟机和字节码存储格式.java虚拟机不和包括java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了java虚拟 ...
- GBK字符集
GBK字库 编辑 同义词 GBK一般指GBK字库 GBK全称<汉字内码扩展规范>(GBK即“国标”.“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Sp ...
- vmware安装win7*64位时,安装不成功的关键点是光驱接口类型选择为IDE模式
mware 安装win7*64时,找不到光盘,后来在xin7*64的虚拟机下的编辑虚拟机设置 找到光驱,点击高级,并选择IDE即可,这样就可以进入虚拟机找到光驱和硬盘到了.进入winpe后可以看到各种 ...
- Python学习5——抽象,涉及抽象和结构、函数的自定义、参数、作用域、递归
此处将抽象和结构.自定义函数.参数的使用.作用域.递归放在一起学习,看起来很怪是不是? 但实际上这几者之间是有紧密联系的,不然Python基础教程(第三版)的作者为什么会把它们放在一起哪?手动滑稽 好 ...
- JS 05 json
1.下载jar包: https://www.github.com/alibaba/fastjson/releases https://www.mvnrepository.com/artifact/co ...
- 深度剖析Kubernetes API Server三部曲 - part 3
在本系列的前两部分中我们介绍了API Server的总体流程,以及API对象如何存储到etcd中.在本文中我们将探讨如何扩展API资源. 在一开始的时候,扩展API资源的唯一方法是扩展相关API源代码 ...
- diverta 2019 Programming Contest
A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...
- raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
转自:http://www.cnblogs.com/xiaobinglife/articles/10716605.html 一.Django数据同步过程中遇到的问题: 1.raise Improper ...
- 音视频入门-01-认识RGB
* 音视频入门文章目录 * RGB 简介 RGB 色彩模式是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB 即是代表红 ...
- (一)Maven基础及第一个Maven工程
一.Maven介绍 ANT/Maven/gradle是一个项目管理工具,它包含了一项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecy ...