基于马尔科夫链的产品评估预测
马尔可夫链
1、建立转移概率矩阵:
马尔可夫链是一种时间离散、状态离散、带有记忆功能情况的随机过程,是预测中常用到的一种数学模型。如果数据的本身的每一时刻的状态仅仅取决于紧接在他前面的随机变量的所处状态,而与这之前的状态无关,这就是马尔可夫链的“无后效性”。
经过了解本文的销量对于时间序列敏感性不高,具有“无后效性”的特点,因此可以根据唯品历史以来的销量进行其预测,可以得到下一次档期每个商品的销售状态。
为了准确的计算整个目标系统的转移概率矩阵是马尔可夫链预测方法最常用到也是最基础的内容,一般是经常是使用统计估算法,将其方法总结如下:
假设我们所关注的序列片段存在状态的个数为m个,即状态空间 I = {1,2,,,,m},将f_{ij} i,j inI看作为转移频数生成的概率矩阵。第i行,第j行元素在这个转移频数矩阵的值f_{ij} 除以全部元素和得到的值定义为“转移概率”,用字母P_{ij} {i,jin I}来表示,既有:P_{ij}=(f_{ij})/{sum_{j=1}^m f_{ij}qquad}由状态i经一步转到状态j也可以用此公式来表示。因为稳定性好是频率的一个特点,所以如果m很大的时候,我们可以把频率等价的看成是概率,因而可以用它来估算转移概率。实际写法上为了方便转移频率用符号P_{ij}
来表示,并称之为“转移概率”,一步转移概率也相应的表示为:P=(P_{ij})i,jin I
2、对离散型数列进行“马氏性”检验:
通常情况下选用离散型序列的马尔可夫链来对变量具有随机性的序列进行“马氏性”检验,检验常用x^2统计量。
设研究的序列状态个数为m,用(f_{ij})i,jin I 表示转移频数概率矩阵,把(f_{ij})i,jin I 的各个列之和去除以(f_{ij})i,jin I 的全部元素之和,就会得到“边际概率”,用字母P_j 表示,其中:P_{ij}=({sum_{i=1}^m f_{ij}})/({sum_{i=1}^m}{sum_{j=1}^m f_{ij}})
当m很大时x^2统计量:
它将服从自由度为(m-1)^2的x^2分布,现在给定显著性水平为alpha ,经查表可得到的值chi_a^2((m-1)^2)
(或者在excel表里面利用公式chiinv(alpha , (m-1)^2))计算得到)。如果
,则拒绝零假设,可以认为序列具备“马氏性”,反之,则这个序列不能当作马尔可夫链来对待。
假设某一款商品的销量是如下所示:
825058101 |
66 |
39 |
50 |
45 |
96 |
38 |
15 |
14 |
22 |
63 |
---|---|---|---|---|---|---|---|---|---|---|
22 |
63 |
80 |
42 |
43 |
104 |
45 |
20 |
7 |
3 |
本文设定不同的销售量有不同的状态,即:
范围 |
状态 |
---|---|
<20 |
滞销 |
20<=and<40 |
平销 |
40<=and<60 |
热销 |
>60 |
畅销 |
由此可以得到上述商品的转移过程的:
滞销 |
平销 |
热销 |
畅销 |
|
---|---|---|---|---|
滞销 |
2 |
1 |
0 |
0 |
平销 |
2 |
0 |
1 |
1 |
热销 |
0 |
1 |
2 |
2 |
畅销 |
0 |
2 |
2 |
1 |
则该商品的 P_{j}\为:
滞销 |
平销 |
热销 |
畅销 |
---|---|---|---|
4/18 |
4/18 |
5/18 |
5/18 |
则该商品的P_{ij}\ 为:
滞销 |
平销 |
热销 |
畅销 |
|
---|---|---|---|---|
滞销 |
0.67 |
0.33 |
0.00 |
0.00 |
平销 |
0.50 |
0.00 |
0.25 |
0.25 |
热销 |
0.00 |
0.20 |
0.40 |
0.40 |
畅销 |
0.00 |
0.40 |
0.40 |
0.20 |
将上述结果代入公式:
根据卡方分布的数据比较大小:
该商品的卡方值为:大于0.1显著水平下的
,所以该商品是通过“马氏性”检验的,因此该商品的转移概率矩阵为:
滞销 |
平销 |
热销 |
畅销 |
|
---|---|---|---|---|
滞销 |
0.6139 |
0.2211 |
0.0825 |
0.0825 |
平销 |
0.335 |
0.315 |
0.2 |
0.15 |
热销 |
0.1 |
0.24 |
0.37 |
0.29 |
畅销 |
0.2 |
0.16 |
0.34 |
0.3 |
该表格表示为:
(1)原来产品为滞销状态,下一次则有61.39%的概率还是滞销状态,有22.11%的概率变为平销,有8.25%的概率变为热销,有8.25%的概率变为畅销;
(2) 原来产品为平销状态,下一次则有33.50%的概率还是滞销状态,有31.50%的概率变为平销,有20.00%的概率变为热销,有15.00%的概率变为畅销;
(3) 原来产品为热销状态,下一次则有10.00%的概率还是滞销状态,有24.00%的概率变为平销,有37.00%的概率变为热销,有29.00%的概率变为畅销;
(4) 原来产品为热销状态,下一次则有20.00%的概率还是滞销状态,有16.00%的概率变为平销,有34.00%的概率变为热销,有30.00%的概率变为畅销。
-----------------------------------我是分割线-------------------------------
但是但是,这只是其中一个商品的预估
本店商品的其中一个
本店差不多有1700商品
怎么办怎么办?
首先将数据储存出来
本文用python读取数据
步骤1:excel表格的数据插入进去啊,这里是读取表格
from openpyxl import load_workbook
if __name__ == '__main__':
##这里是打开excel将数据储存到数组里面
wb = load_workbook(filename=r'C:UsersAdministratorDesktopdata.xlsx') ##读取路径
ws = wb.get_sheet_by_name("Sheet1") ##读取名字为Sheet1的sheet表
info_data_id = []
info_data_sales = []
步骤2:表格读取:
for row_A in range(2, 1693): ## 遍历第2行到1692行
id = ws.cell(row=row_A, column=1).value ## 遍历第2行到1692行,第1列
info_data_id.append(id)
for row_num_BtoU in range(2, len(info_data_id) + 2): ## 遍历第2行到1692行
row_empty = [] ##建立一个空数组作为临时储存地,每次换行就被清空
for i in range(2, 22): ## 遍历第2行到1692行,第2到21列
data = ws.cell(row=row_num_BtoU, column=i).value
if data == None:
pass
else:
info_data_sales.append(row_empty) ##row_empty每次储存完2到21列后压给info_data_sales,然后row_empty被清空
重点是建立了一个空的row_empty = []可以临时储存每一行的数据,等到下一次循环就被清空
表格数据样式如下:
一共1692行22列应该,反正没数
步骤3:计算p.j
##这里是计算pj的
info_pj = []
for j in range(0, len(info_data_sales)):
pj_zhixiao = 0
pj_pingxiao = 0
pj_rexiao = 0
number = 0
pj_empty = []
for k in range(0, len(info_data_sales[j])):
number = number + 1
if info_data_sales[j][k] < 10:
pj_zhixiao = pj_zhixiao + 1
elif info_data_sales[j][k] >= 10 and info_data_sales[j][k] < 30:
pj_pingxiao = pj_pingxiao + 1
elif info_data_sales[j][k] >= 30:
pj_rexiao = pj_rexiao + 1
chance_zhixiao = pj_zhixiao / number
chance_pingxiao = pj_pingxiao / number
chance_rexiao = pj_rexiao / number
pj_empty.append(chance_zhixiao)
pj_empty.append(chance_pingxiao)
pj_empty.append(chance_rexiao)
info_pj.append(pj_empty) ##得到了pj初始概率
遍历数组info_data_sales的每一个元素,根据我审定的判断来计算各个状态的出现概率:
范围 |
状态 |
---|---|
<10 |
滞销 |
10<=and<30 |
平销 |
>30 |
热销 |
步骤4:计算P_{ij}和F_{ij}:
先是统计各个状态出现的概率
再压入数组里面
步骤5:判断马氏性
什么数据又有了,那么就可以用公式计算了:
代码如下:
不要忘记了
import math
由于我的显著性非常不明显
所以用了0.2的显著性判断:
步骤6:压回excel表格就行了
这里用到的是
import xlsxwriter
步骤7:记得利用矩阵计算啊,python自带的矩阵运算是:
import numpy as np
最后做个好学生,不要忘记关掉excel表格
workbook.close()
得到效果图如下啊啊啊啊:
- hihoCoder #1142 : 三分求极值
- 容斥原理
- TensorFlow:TensorBoard可视化
- Codeforces 768B Code For 1
- 【干货】深入理解自编码器(附代码实现)
- SlopOne推荐算法(附Python源码)
- 后缀数组(一堆干货)
- POJ 1741 Tree(树的点分治,入门题)
- hihoCoder 1039:字符消除(字符串处理)
- 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
- hihoCoder 1051 补提交卡(贪心,枚举)
- LCA 最近公共祖先
- RMQ问题(线段树算法,ST算法优化)
- 统计0到n之间1的个数[数学,动态规划dp](经典,详解)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法