假设您有某个时期内每一天的分布记录。例如,某些分布取决于随时间演变的参数。假设我们有几十天或几百天。你如何想象这种分布的变化?我希望情节包含尽可能多的信息。
我能想到的一种方法是:代理密度函数并绘制这些曲线在 2D 中的演变。这将是某种形式的同伦:初始分布以一些平滑的步骤收敛到最终分布。当然,这里我假设平滑。
谢谢你的帮助。
这个问题本质上是理论上的,但我的目标是实现 python,因此也欢迎对库的实现或建议。
假设您有某个时期内每一天的分布记录。例如,某些分布取决于随时间演变的参数。假设我们有几十天或几百天。你如何想象这种分布的变化?我希望情节包含尽可能多的信息。
我能想到的一种方法是:代理密度函数并绘制这些曲线在 2D 中的演变。这将是某种形式的同伦:初始分布以一些平滑的步骤收敛到最终分布。当然,这里我假设平滑。
谢谢你的帮助。
这个问题本质上是理论上的,但我的目标是实现 python,因此也欢迎对库的实现或建议。
编辑 没有看到这是一个python问题。我认为这个想法成立,但不确定 python 实现是否现成。
您可能想使用R包ggridges(和gganimate动画)查看所谓的 ridge-plots 。下面是一个例子(显然不必是动画):
此要点中提供了代码。
始终考虑您的情况的性质:谁将成为这个情节的观众?我的目标是什么?我的数据是什么?
您声明您有一个“分布取决于随时间演变的参数”。如果您的受众相当复杂,并且这是一个已知的、研究过的分布(例如Weibull),那么您可以估计每天的变化参数,将其绘制在散点图上,并使用像 LOWESS 线这样简单的东西对其进行平滑处理。
这是一个例子。这些是用 R 编码的,但它们旨在让不使用 R 的人易于理解,并且应该可以翻译成 Python。
library(fitdistrplus) # we'll use this package
set.seed(9234) # this makes the example exactly reproducible
day = rep(1:16, each=100) # 1 through 16, each repeated 100x
y = c() # an empty vector to hold the data
for(i in 1:16){ # generates data from Weibull distributions w/ the
y = c(y, # shape parameter increasing (but decelerating) by day
rweibull(n=100, shape=(.5 + .1*i - .002*(i^2)), scale=1))
}
# estimate Weibull shape & scale parameters by MLE for each day
d = t(sapply(split(y, day), function(x){ fitdist(x, distr="weibull")$estimate }))
d = data.frame(day=1:16, d)
d
# day shape scale
# 1 1 0.6311143 0.9871380
# 2 2 0.7501392 1.0168905
# 3 3 0.7510426 0.8853516
# 4 4 0.8142484 0.8701132
# 5 5 0.9081937 1.1098466
# 6 6 0.9679144 1.0668120
# 7 7 1.0347746 1.0638731
# 8 8 1.1496184 0.9775989
# 9 9 1.1724681 1.0758072
# 10 10 1.2396152 0.9975250
# 11 11 1.2519313 0.8847656
# 12 12 1.4648643 1.0801915
# 13 13 1.3258313 0.9113326
# 14 14 1.4301392 0.9699252
# 15 15 1.5494493 1.0448072
# 16 16 1.5989056 1.0133831
windows()
plot(shape~day, d)
lines(lowess(d$day, d$shape), col="red")
如果数据不是来自已知分布,您可以绘制多条线随时间跟踪固定分位数。
dq = t(sapply(split(y, day), function(x){ quantile(x, probs=c(0.25, 0.5, 0.75, 0.95)) }))
dq = data.frame(day=1:16, dq)
names(dq) = c("day", "25%", "50%", "75%", "95%")
dq
# day 25% 50% 75%
# 1 1 0.1447001 0.5212207 1.628061
# 2 2 0.2318992 0.6657878 1.394435
# 3 3 0.1868559 0.5122787 1.618891
# 4 4 0.1665822 0.6402280 1.259112
# 5 5 0.3038764 0.6778831 1.418966
# 6 6 0.2508331 0.7469482 1.447055
# 7 7 0.2759569 0.7411599 1.527585
# 8 8 0.2774774 0.7496496 1.421123
# 9 9 0.3630679 0.9203537 1.343523
# 10 10 0.3788195 0.6613015 1.263599
# 11 11 0.3514467 0.6411170 1.110531
# 12 12 0.4697239 0.8562416 1.253663
# 13 13 0.3281270 0.6732758 1.113507
# 14 14 0.4498140 0.7440592 1.143489
# 15 15 0.4391240 0.8440031 1.371128
# 16 16 0.4726235 0.8386493 1.210914
windows()
plot(1,1, xlim=c(1,16), ylim=c(0, 7), xlab="day", ylab="value", type="n")
lines(dq$day, dq$`25%`, col="red", lty=2)
lines(dq$day, dq$`50%`, col="black", lty=1)
lines(dq$day, dq$`75%`, col="blue", lty=3)
lines(dq$day, dq$`95%`, col="purple", lty=4)
legend("topright", legend=c("95%", "75%", "50%", "25%"), lty=c(4,3,1,2),
col=c("purple", "blue", "black", "red"))
如果您的观众不那么老练,不知道“Weibull”是什么,或者因为试图遵循“75 th percentile”的想法而被甩掉,并且您想要一些更有活力的东西,那就做一个小组核密度图。(不可否认,阿迪宾德的情节比这更精彩。)
windows()
par(mfrow=c(4,4))
for(i in 1:16){
plot(density(y[day==i]), main=paste("day", i), xlab="", xlim=range(y),
ylim=c(0, .8), ylab="", axes=FALSE); box()
}
假设您每天都有一个经验分布,例如一家商店每天查看每个客户的总付款。您可以将其视为直方图的时间序列,并且可以以各种方式绘制,可能是一系列箱线图。如果您有一些示例数据,我们可以尝试各种选项!
在这里提出并回答了一个类似的问题: https ://stackoverflow.com/questions/11690194/time-series-histogram