说明
使用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只能做一些小规模的计算。