建模杂谈系列253 序列突变点的判定

说明

使用pycm3进行推断。

内容

1 环境搭建

使用conda创建对应的包环境,然后再通过jupyter运行

conda create -c conda-forge -n pymc_env "pymc>=5"
conda activate pymc_env

pip3 install  ipython -i https://mirrors.cloud.tencent.com/pypi/simple
pip3 install  jupyter -i https://mirrors.cloud.tencent.com/pypi/simple

nohup jupyter lab --allow-root --ip='*' --port=8888 > /dev/null 2>&1 &

嗯,我发现启动jupyter后竟然没有pymc,又重装了一下。最近阿里的镜像慢的不行了,腾讯快。
!pip3 install pymc -i https://mirrors.cloud.tencent.com/pypi/simple

2 实验

判定一个时间序列,产生突变点的位置

主要算是重启一下之前的记忆,确保新的环境搭建成功

%matplotlib inline
from IPython.core.pylabtools import figsize
import numpy as np
from matplotlib import pyplot as plt
import matplotlib as mpl
mpl.style.use("ggplot")
# figsize(11, 9)

figsize(12.5, 3.5)
count_data = np.loadtxt("txtdata.csv")
n_count_data = len(count_data)
plt.bar(np.arange(n_count_data), count_data, color="#348ABD")
plt.xlabel("Time (days)")
plt.ylabel("count of text-msgs received")
plt.title("Did the user's texting habits change over time?")
plt.xlim(0, n_count_data);

说的是作者自己发短信的数据,有一天发生了变化,但是从图上看不出来。
在这里插入图片描述

然后构建了一个模型框架,假设有两种不同的模式

import pymc as pm

with pm.Model() as model:
    alpha = 1.0/count_data.mean()  # Recall count_data is the
                                   # variable that holds our txt counts
    lambda_1 = pm.Exponential("lambda_1", alpha)
    lambda_2 = pm.Exponential("lambda_2", alpha)
    
    tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data - 1)

with model:
    idx = np.arange(n_count_data) # Index
    lambda_ = pm.math.switch(tau > idx, lambda_1, lambda_2)

with model:
    observation = pm.Poisson("obs", lambda_, observed=count_data)

然后将观察数据给到模型,执行mcmc,然后画图

### Mysterious code to be explained in Chapter 3.
with model:
    step = pm.Metropolis()
    trace = pm.sample(10000, tune=5000, step=step, return_inferencedata=False)

lambda_1_samples = trace['lambda_1']
lambda_2_samples = trace['lambda_2']
tau_samples = trace['tau']

figsize(12.5, 10)
#histogram of the samples:

ax = plt.subplot(311)
ax.set_autoscaley_on(False)

plt.hist(lambda_1_samples, histtype='stepfilled', bins=30, alpha=0.85,
         label="posterior of $\lambda_1$", color="#A60628", density=True)
plt.legend(loc="upper left")
plt.title(r"""Posterior distributions of the variables
    $\lambda_1,\;\lambda_2,\;\tau$""")
plt.xlim([15, 30])
plt.xlabel("$\lambda_1$ value")

ax = plt.subplot(312)
ax.set_autoscaley_on(False)
plt.hist(lambda_2_samples, histtype='stepfilled', bins=30, alpha=0.85,
         label="posterior of $\lambda_2$", color="#7A68A6", density=True)
plt.legend(loc="upper left")
plt.xlim([15, 30])
plt.xlabel("$\lambda_2$ value")

plt.subplot(313)
w = 1.0 / tau_samples.shape[0] * np.ones_like(tau_samples)
plt.hist(tau_samples, bins=n_count_data, alpha=1,
         label=r"posterior of $\tau$",
         color="#467821", weights=w, rwidth=2.)
plt.xticks(np.arange(n_count_data))

plt.legend(loc="upper left")
plt.ylim([0, .75])
plt.xlim([35, len(count_data)-20])
plt.xlabel(r"$\tau$ (in days)")
plt.ylabel("probability");

最后可以推断在45天的时候发生跳变(作者自己承认了这一点)
在这里插入图片描述

3 总结

  • 1 这种模型可以推断看不见的事实
  • 2 matplotlib用好了也可以画出很好看的图

注意:理论上,pymc是可以借用显卡计算的。只不过之前它的后端比较奇葩,现在可能失传了。然后我不太清楚的是现在怎么和显卡挂上,单靠cpu只能做一些小规模的计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值