分析预测

所有的预测基本都会产生偏差,因为需求是一个随机变量,良好的预测应该不仅仅是一个数字,而是大概率会落入的一个区间范围

主观预测

  • 复合法 - 数据的集合,如:销售人员复合法、选举民意测验复合法
  • 客户调查 - 基于客户反馈做出的预测
  • 领导层集体预测法 - 由少量专家做出的预测
  • 德尔菲法 - 反复汇编并重新考虑个人意见,直到组织内达成共识

客观预测

使用之前的数据客观地进行预测

  • 因果模型 - 将需求设为“D”,根本原因设为“n”,因果模型是一个函数,将需求“D”表示为“n”个根本原因
  • 时间序列法 - 归纳过去、现在和未来的规律
    • 过去数据可能具有以下特征:
      • 趋势
      • 季节性/周期
      • 随机性

预测平稳序列

平稳序列的特点就是:未来和过去相拟

报童问题(不确定的环境中匹配需求与供应)就是平稳序列的典型案例

平稳时间序列具有以下形式:

Dt=μ+ϵtD_t = \mu + \epsilon_t

  • μ\mu 是常数,有时是样本平均值
  • ϵt\epsilon_t是随机变量,均值为0
  • 标准差为σt\sigma_t

预测平稳序列的方法有:移动平均法、指数平滑法

平均值、标准差

需求分布平均值:

D=p1D1+p2D2+p3D3++pnDn\overline D = p_1D_1 + p_2D_2 + p_3D_3 + \ldots + p_nD_n

p1+p2+p3++pn=1 p_1 + p_2 + p_3 + \ldots + p_n = 1

需求标准差:

SD=p1(D1D)2+p2(D2D)2+p3(D3D)2++pn(DnD)2SD = \sqrt{p_1 \ast (D_1 - \overline D)^2 + p_2 \ast (D_2 - \overline D)^2 + p_3 \ast (D_3 - \overline D)^2 + \ldots + p_n \ast (D_n - \overline D)^2}

p1+p2+p3++pn=1 p_1 + p_2 + p_3 + \ldots + p_n = 1

算术平均值公式如下:

μ=D1+D2+D3++Dnn\mu = \frac{D_1 + D_2 + D_3 + \ldots + D_n}{n}

算术标准差公式如下:

总体标准差(如果总体是一个完整的总体,分母也可以使用n):

σ=(Dtμ)2n1 \sigma = \sqrt{ \frac{ \sum (D_t - \mu)^2 }{ n-1 } } t = 1,...,n

样本标准差:

s=s2=i=1n(xix)2n1 s = \sqrt{s^2} = \sqrt{ \frac{ \sum_{i=1}^n (x_i - \overline x)^2 }{ n-1 } }

标准差修正

如果样本标准差与总体标准差差距较大,就要考虑样本选择是否正确

如果样本选择正确,直接使用样本标准差即可,也可以根据实际场景对样本标准差进行修正

s=s+sn s = s + \frac{s}{ \sqrt{n} }

随着n越来越大,校正项消失

σ=s \sigma = s

周期预测公式

从周期t预测未来的n个周期,可以使用如下表达式:

Ft+τF_{t + \tau}

如果只预测一个周期,可以简写为

Ft+1F_{t+1}

从周期t-1预测周期t

Ft1,tF_{t-1,t}

移动平均法

移动平均数是n个最新观测值的算术平均值

MA(n)表示n个数据点的移动平均数

简单点说就是,直接用最近n期的平均值作为下一期的预测值

因为预测值是一个范围值,我们可以使用标准差来预估范围区间

移动平均法的数据是等权的,如果我们想给最新的数据较高的权重,较早的数据较低的权重,可以使用指数平滑法

已知100期的销量,分别使用全部样本、最新20期样本、最新时期样本预算下一期的销量,示例如下:

import numpy as np

num = np.array([
    29, 43, 40, 55, 75, 65, 75, 47, 77, 61, 56, 53, 18, 42, 50, 36, 50, 65, 33, 66, 79, 38, 75, 53, 66, 45, 60, 35, 52,
    41, 67, 22, 76, 38, 62, 40, 51, 34, 70, 68, 64, 15, 45, 45, 36, 78, 81, 54, 47, 61, 58, 32, 54, 49, 29, 63, 44, 56,
    64, 49, 57, 47, 52, 52, 62, 62, 55, 50, 55, 60, 51, 61, 73, 52, 60, 49, 58, 70, 27, 57, 52, 50, 33, 53, 54, 60, 57,
    57, 63, 64, 62, 58, 42, 33, 50, 59, 48, 62, 41, 41
])

# 使用全部样本预测下一期
print(round(num.mean(), 2))
print(round(num.std(ddof=1), 2))

# 使用MA(20)预测下一期
print(round(num[-20:].mean(), 2))
print(round(num[-20:].std(ddof=1), 2))

# 使用MA(10)预测下一期
print(round(num[-10:].mean(), 2))
print(round(num[-10:].std(ddof=1), 2))

根据上面的示例,可以发现MA(20)的标准差较小,初步可以判断MA(20)较为准确

移动平均法的缺点:

如果把移动平均法应用于趋势序列,往往会产生滞后

  • 如果呈上升趋势,则移动平均预测值通常会低于需求量
  • 如果呈下降趋势,则移动平均预测值通常会高于需求量

无法解释为什么未来需求会以某种方式表现出来

预测误差

et=FtDte_t = F_t - D_t

  • e:error,误差
  • t:time,周期
  • F:forecast,预测
  • D:demand,需求

绝对平均离差(MAD):

MAD=etnMAD = \frac{\sum\vert e_t \vert}{n}

均方误差(MSE):

MSE=et2nMSE = \frac{\sum e_t^2}{n}

平均绝对百分比误差(MAPE)

MAPE=et÷Dtn×100MAPE = \frac{\sum\vert e_t \div D_t \vert}{n} \times 100

一个好的预测过程将具有较低的MAD值、MSE值、MAPE值

我们可以通过比对预测误差(后视镜方法)来调整样本范围,从而使得预测更为准确

import numpy as np

num = np.array([
    29, 43, 40, 55, 75, 65, 75, 47, 77, 61, 56, 53, 18, 42, 50, 36, 50, 65, 33, 66, 79, 38, 75, 53, 66, 45, 60, 35, 52,
    41, 67, 22, 76, 38, 62, 40, 51, 34, 70, 68, 64, 15, 45, 45, 36, 78, 81, 54, 47, 61, 58, 32, 54, 49, 29, 63, 44, 56,
    64, 49, 57, 47, 52, 52, 62, 62, 55, 50, 55, 60, 51, 61, 73, 52, 60, 49, 58, 70, 27, 57, 52, 50, 33, 53, 54, 60, 57,
    57, 63, 64, 62, 58, 42, 33, 50, 59, 48, 62, 41, 41
])

# 计算最新20期的预测误差、绝对平均离差(MAD)、均方误差(MSE)、百分比误差及其平均值
arr2 = []
for i in (range(-20, 0)):
    arr2.append(i)
arr1 = np.array(arr2) - 20

avg = []
for i in range(20):
    avg.append(round(num[arr1[i]:arr2[i]].mean(), 2))
# 预测误差 = 预测值 - 实际值
e_t = np.array(avg) - num[-20:]  # type:np.ndarray
print(e_t)
# 绝对平均离差(MAD)= 求和(预期误差的绝对值)/个数
mad = np.abs(e_t).sum() / 20
print(round(mad, 2))
# 均方误差(MSE)= 求和(预期误差的平方)/个数
mse = (e_t * e_t).sum() / 20
print(round(mse, 2))
# 平均绝对百分比误差(MAPE)=求和(预测值/实际值)/个数 * 100
mape = (np.abs(e_t / num[-20:])).sum() / 20 * 100
print(round(mape, 2))

A/F比有助于理解预测准确性

  • A:actual demand,实际需求
  • F:forecast,预测
  • A/F < 1,预测小于实际
  • A/F = 1,预测较为准确
  • A/F > 1,预测大于实际

预测趋势序列

简单的趋势序列,我们可以拟合一条趋势线来进行预测

线性回归法

Dt=a+bt D_t = a+ bt

  • Dt - 对周期t的需求做出的预测
  • t - 周期
  • b - 斜率
  • a - 截距

回归分析是一种统计学上分析数据的方法,目的在于了解两个或多个变量间是否相关、相关方向与强度,并建立数学模型以便观察特定变量来预测研究者感兴趣的变量

R2R^2是指自变量可以解释因变量的比例,用于判断回归线的优劣,即模型的拟合程度。介于0到1之间,越靠近1说明散点越靠近回归线,拟合的越好,通常达到0.8左右就很好了

普通最小二乘法(OLS)

  • 通过最小化均方误差来拟合趋势线
  • 直线 Dt=a+bt D_t = a + bt 是通过n个数据点拟合的趋势线
  • 选择不同的参数a和b,来最小化数据点离趋势线距离的平方的均值

黄石公园最近50年每年的游客访问数量折线图以及线性回归拟合

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager

my_font = font_manager.FontProperties(fname='/System/Library/Fonts/Supplemental/Songti.ttc')

x = [1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922,
     1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941,
     1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960,
     1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979,
     1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
     1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014]

y = [13727, 26188, 17182, 16414, 19542, 32545, 19575, 23054, 22970, 24929, 20250, 51895, 35849, 35400, 21275, 62261,
     79777, 81651, 98223, 138352, 144158, 154282, 187807, 200825, 230984, 260697, 227901, 221248, 157624, 161938,
     260775, 317998, 432570, 499242, 466185, 486936, 526437, 579696, 185746, 61696, 86593, 189264, 807917, 937776,
     1018279, 1131159, 1110524, 1163894, 1350295, 1326858, 1328900, 1368500, 1457800, 1595900, 1442400, 1408700,
     1443300, 1524100, 1925200, 1872500, 1929300, 2062500, 2130300, 2210000, 2229700, 2193700, 2297300, 2120500,
     2236888, 2061700, 1928900, 2239500, 2519200, 2481900, 2618380, 1892908, 2000269, 2521831, 2368897, 2347242,
     2222027, 2226159, 2363756, 2573194, 2182113, 2644442, 2823572, 2920537, 3144405, 2912193, 3046145, 3125285,
     3012171, 2889513, 3120830, 3131381, 2838233, 2758526, 2973677, 3019375, 2868317, 2835651, 2870295, 3151343,
     3066580, 3295187, 3640185, 3394326, 3447729, 3188030, 3513484]

plt.figure(figsize=(18, 8), dpi=80)

# 使用Matplotlib画近50年的折线图
plt.plot(x[-50:], y[-50:], color='orange', marker='o')

plt.xticks(range(1960, 2021, 10))
_y = range(0, 4000001, 500000)
_y_ticks = [str(i) for i in _y]
plt.yticks(_y, _y_ticks)
# y轴的作图范围
plt.ylim(0, 4000001)
plt.grid(alpha=0.4)

plt.xlabel("年", fontproperties=my_font)
plt.ylabel("访问数量", fontproperties=my_font)
plt.title("最近50年每年的游客访问数量", fontproperties=my_font)

# 一次多项式拟合,相当于线性拟合,默认使用最小二乘法
fit = np.polyfit(x[-50:], y[-50:], 1)
# 生成拟合函数
fit_fn = np.poly1d(fit)  # type: np.poly1d


def formatFnToStr(fit_fn):
    fit_fn = str(fit_fn)
    fit_fn = fit_fn.replace(" ", '')
    fit_fn = fit_fn.split("x-")
    return 'y={}x-{}'.format(format(float(fit_fn[0]), '.0f'), format(float(fit_fn[1]), '.0f'))


# 画拟合线
plt.plot(x[-50:], fit_fn(x[-50:]), label=formatFnToStr(fit_fn))
plt.figlegend(loc="center")
plt.show()

普通最小二乘法(多元)

Y=a+b1x1+b2x2+...+e Y = a + b_1x_1 + b_2x_2 + ... + e

  • Y是结果变量
  • XiX_i是预测变量
  • a是截距或常数
  • bib_i是系数或斜率
  • e是随机误差

OLS估算能最小化 Y(预测)- Y(实际)之和的a和b的值

当预测变量彼此之间的相关性较低时,OLS往往能更好地发挥作用

随着相关性变高,可能会出现共线性问题,从而导致

  • 估算的精确度降低,因为如果两个变量非常相似,我们不清楚是其中哪个变量产生了结果
  • 估算可能会更多地受到一些观察结果的影响

关于共线性问题没有明确的阈值,但是我们通常会将相关性设定为0.5-0.7,具体取决于数据集和变量的大小

如果存在高度相关的变量,可以考虑删除其中一些变量

只有数值数据可以用于回归分析,如果需要使用文本数据,首先应确定与员工流失密切相关的指标变量,然后再用该变量将文本数据转换为数值数据

相关性:

相关性是指两个变量之间的相关程度,通常用相关系数来衡量。在统计学中,有两种常用的相关系数:Pearson相关系数和Spearman秩相关系数。其中,Pearson相关系数是最常用的一种,它的值介于-1和1之间。当两个变量的线性关系增强时,相关系数趋于1或-1;当一个变量增大,另一个变量也增大时,表明它们之间是正相关的,相关系数大于0;如果一个变量增大,另一个变量却减小,表明它们之间是负相关的,相关系数小于0;如果相关系数等于0,表明它们之间不存在线性相关关系


import pandas as pd

df = pd.read_excel("/home/data/example.xlsx", sheet_name='员工属性概览')  # type: pd.DataFrame

df = df[
    ['流失代码', '年龄', '差旅代码', '日薪', '离家的距离', '教育程度', '环境满意度', '性别代码', '时薪', '工作投入', '职级', '工作满意度', '月收入', '月薪', '曾受雇的公司数',
     '加班代码', '加薪百分比', '绩效评级', '关系满意度', '股票期权级别', '总工龄', '去年接受培训的次数', '工作生活平衡', '司龄', '任现职年限', '距离上次晋升的年数',
     '与当前经理共事的年数']]

print(df.corr())

EXCEL回归示例:

  • R:线性回归系数是预测值和真实值Y之间的相关性
  • R方:拟合优度(线性回归系数的平方)是输出变量中方差的百分比,可以通过我们的预测变量进行解释。它的值在0到1之间。如果拟合优度为1,则意味着我们的预测变量可以完美地预测Y
  • 调整R方:修正后的拟合优度解释了分析中使用的预测因子数量
  • 标准误差:解释了估算中的干扰
  • 观察值:样本数量

EXCEL回归示例2:

  • 如果员工拥有学士学位(系数为0.05),离职概率会高5%(数据集已清洗为1或0)
  • 如果员工经验丰富(系数为-0.005),即工作时间每增加一年,离职的概率下降0.5%
  • 学士学位的p值约为0.478,即学士学位的系数值不等于0的可能性是48%,因此我们不太相信能够将学士学位作为人员流失预测因子
  • 根据经验法则,p值小于0.05的变量通常被视为具有统计显著性。因此,这些变量包括企业内的任期、工作时间、薪资,以及去年是否申请过内部工作

在Python中,有几个常用的库可以用来实现多元线性回归。以下是一些常见的库以及它们的优劣势:

statsmodels:

  • 优势:statsmodels是一个专注于统计模型的库,提供了丰富的统计分析工具,包括回归分析。它的回归分析结果摘要包含了详细的统计信息,如回归系数、P值、置信区间等。适合需要详细统计分析报告的情况。
  • 劣势:在大规模数据集上可能性能较低,不太适用于处理大数据。

scikit-learn:

  • 优势:scikit-learn是一个通用机器学习库,支持多元线性回归以及其他许多机器学习算法。它易于使用,适合处理中等规模的数据集。由于其广泛的机器学习功能,可以在同一库中进行多种分析。
  • 劣势:相对于statsmodels,scikit-learn在回归结果摘要的统计信息方面较为简化。

numpy和scipy:

  • 优势:numpy和scipy是科学计算的核心库,可以用于数值分析和优化问题,包括多元线性回归。可以根据自己的需求编写更加定制化的回归分析代码。
  • 劣势:需要更多手动操作来计算回归系数等参数,适用于对算法和计算细节有较高控制需求的用户。

TensorFlow和PyTorch:

  • 优势:这些库主要用于深度学习,但也可以用于回归问题。它们提供了强大的数值计算和自动求导功能,适用于处理复杂的回归任务,如神经网络模型。
  • 劣势:相对于前面提到的专门库,使用深度学习库进行回归分析可能会过于复杂,特别是对于简单的线性回归问题。

如果需要详细的统计分析报告,可以考虑使用statsmodels。如果需要更广泛的机器学习功能,并且对回归结果的详细统计信息不是主要关注点,那么scikit-learn可能更适合

对于定制化需求,可以使用numpy和scipy。如果想要探索更复杂的回归问题,甚至结合深度学习,可以考虑使用TensorFlow或PyTorch


import statsmodels.api as sm
import pandas as pd

df = pd.read_excel("/home/data/example.xlsx", sheet_name='员工属性概览')  # type: pd.DataFrame

# print(df.info())
# print(df.describe())
# print(df.head(5))
# print(df.tail(5))
# exit('s')

Y = df['流失代码']

X = df[['年龄', '差旅代码', '日薪', '离家的距离', '教育程度', '环境满意度', '性别代码', '时薪', '工作投入', '职级']]

# 执行最小二乘线性回归
model = sm.OLS(Y, sm.add_constant(X)).fit()

# 输出回归结果摘要
print(model.summary())

文件 提取码: e4id

季节性

季节性是数据的一种模式,指有些变化会定期重复,通过以下方式计算季节性因子

  1. 计算整个数据集的样本均值
  2. 计算每个季节的数据集的样本均值(如:春夏秋冬、1月到12月、春节、国庆等等)
  3. 计算每个季节的样本均值除以整个数据集的样本均值(如:春/整,夏/整...)
  4. 反季节序列(除去季节性因子),将数据中的每个观察值除以对应的季节因子即可
import numpy as np
import pandas as pd
from matplotlib import font_manager

my_font = font_manager.FontProperties(fname='/System/Library/Fonts/Supplemental/Songti.ttc')

df = pd.DataFrame({
    'January': [64.4, 65.28, 69.77, 72.68, 72.3, 72.95, 72.82, 74.89, 76.55, 78.02, 78.89],
    'February': [68.1, 68.6, 71.58, 76.07, 75.71, 75.91, 75.28, 77.35, 77.92, 78.9, 80.77],
    'March': [72.43, 75.13, 79.58, 81.31, 81.57, 82.19, 81.08, 83.39, 82.7, 84.43, 84.99],
    'April': [72.13, 76.17, 76.64, 81.34, 81.38, 80.09, 82.1, 82.55, 82.13, 83.61, 82.81],
    'May': [73.98, 74.41, 77.52, 80.39, 81.27, 81.34, 81.32, 82.51, 84.58, 84.45, 84.84],
    'June': [78.58, 80.72, 82.27, 84.56, 86.24, 84.24, 85.37, 86.32, 85.98, 86.62, 86.98],
    'July': [80.98, 82.2, 83.94, 84.95, 86.24, 84.11, 87.09, 86.9, 87.14, 86.83, 86.46],
    'August': [78.74, 78.74, 80.34, 80.9, 84.89, 83.35, 84.97, 85.2, 85.59, 86.61, 85.53],
    'September': [66.93, 70.39, 74.12, 73.78, 75.61, 76.07, 79.42, 79.81, 81.82, 80.64, 80.9],
    'October': [71.47, 74.23, 75.94, 77.5, 78.45, 79.76, 82.22, 83.32, 83.63, 84.23, 82.77],
    'November': [70.45, 73.21, 76.53, 77.98, 77.66, 75.89, 79.17, 81.19, 83.48, 82.78, np.nan],
    'December': [72.52, 72.74, 75.81, 76.57, 75.6, 79.17, 79.87, 80.85, 81.11, 81.54, np.nan],
}, index=[2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013])  # type: pd.DataFrame

# 1. 样本总体平均值
all = []
for i in df:
    all.append(df[i])

arr = np.array(all)
all_mean = arr[np.isnan(arr) == False].mean()
print(all_mean)
# 如果不在意细微误差的话,可以进行2次平均
all_mean_other = df.mean().mean()

# 2. 每月的平均值
month_mean = df.mean()
print(month_mean)

# 3. 季节性因子
month_factor = month_mean / all_mean
print(month_factor)

# 4. 反季节序列(除去季节性因子)
df_new = df / month_factor
print(df)
print(df_new)

RFM

  • R(recency)最近一次消费,权重最高
  • F(frequency)消费频率,权重中等
  • M(monetary value)消费金额,权重最低

BTYD

Buy Till You Die

用于预测长期"购买"和"死亡"的强有力工具

该模型使用3种输入信息:

  • 最近一次消费(R)
  • 消费频率(F)
  • 每种R/F组合的客户数量

边际收益

当边际收益等于边际成本时,利润最大化

换句话说,当你增加一单位产量时,你所获得的收益与你所付出的成本相等,这时你的利润最大

总结

  1. 对下1个周期做出预测
    • 未来和过去相拟,移动平均法等
    • 数据存在趋势,回归分析等
  2. 对多个周期之后的情况做出预测
    • 概率:BTYD模型等

results matching ""

    No results matching ""