Python中时间序列的方差分析,我在做什么?

1 投票
1 回答
2495 浏览
提问于 2025-04-16 09:39

我非常喜欢统计学,但已经有超过6年没上过相关课程了。现在我在弄清楚我需要什么样的测试,以及在这些问题上使用最好的numpy/scipy/R函数时遇到了困难。

我有一个访客及其对应属性的表格(例如:“浏览器 = Mozilla,来源 = Google”),还有每个访客的变量值(例如,$5),这些数据按时间分组。

我的目标是:

A) 找到最重要的属性类别,并给出一个“重要性”评分。

我想得出的结论示例*:

Referrer has 10x larger effect size upon value-per-visitor than Browser
=> PropertyFamily('browser').significance = 1
=> PropertyFamily('referrer').significance = 10

还有

B) 找到每个类别中最重要的属性,并给出重要性评分。

我想得出的结论示例:

GIVEN THAT Value:Baseline => $5/hit
5 hits from IE @ $5/hit (equal to baseline) => no significance
1 hit from Netscape @ $0 => little significance (not enough data)
10 hits from FF @ $10/hit => HIGH significance (hits and delta_value both high)

我有以下问题:

1) 有没有numpy/scipy/R函数可以让我轻松处理这些问题?

2) 有没有人能对ANOVA(方差分析)和时间上的ANOVA提供一些反馈?我不太确定自己是否做对了,可能遗漏了一些简单的东西。确认或纠正都非常感谢。

请注意,这些是过去30天的数组(点击量、值、天数)。例如,如果在周一“Mozilla的价值”有一个大峰值(相对于基线),而在周二“Mozilla的价值”下降(低于基线),我希望Mozilla能被视为一个“重要”的属性(而不是峰值和下降互相抵消)。

这是我输入数据的示例,在进行映射/归约之前:

data = {
'baseline': [(hits, value, day) for hits, value, day in last_thirty_days('baseline')],
'browser': {
  'mozilla': [(hits, value, day) for hits, value, day in last_thirty_days('browser', 'mozilla')],
  ... etc ...
  }
}
... etc ...

这是我当前的代码——它在Dumbo/Hadoop上运行,并提供一个“重要性”的数字,这个公式基本上是我自己发明的。虽然我的公式有效,并且提供了有意义的数据,但我的“重要性”值并没有很好地定义(一个“重要”的属性通常会有一个大于等于100的评分,但这会随着数据集的大小而变化),我知道可能有一个“真实的公式”可以用来计算这个。

# Runs after each (hits, value, date) tuple has been grouped
# into corresponding "plot points", as they would appear on a graph
pp = PlotPoint(property, date, hits, value)
pp.epc = float(pp.value/pp.hits) if pp.hits else 0

# Finds PlotPoint('baseline', date)
# if pp = PlotPoint('firefox', '1-1-10')
#  then pp.baseline == PlotPoint('baseline', '1-1-10')
baseline = pp.baseline()
if baseline.hits == 0:
    volume_ratio = 0 
else:
    volume_ratio = round(100*pp.hits/baseline.hits)
value_ratio = baseline.epc - pp.epc

# Make up a significance value --
# e.g. (10% of visitors * ($1 delta from baseline))^2
pp.significance = math.sqrt(volume_ratio * value_ratio **2)

# OK, we have values for each plotpoint, now sum them up
# to get values for the whole property (over a 30day period) 
pps = property.plotpoint_set.all()
property.hits = sum([p.hits for p in pps])
property.value = sum([p.value for p in pps])
property.epc = property.value/property.hits
value_delta = baseline.epc - property.epc

# Make up a significance for the Property, based on each point's significance
property.significance = math.log(sum(
                [sss.significance**2 for sss in pps]
                )*abs(value_delta)+1)

提前谢谢大家!

1 个回答

3

据我所知,numpy和scipy里提供的统计测试功能比较基础。如果你想做更复杂的统计分析,可以考虑使用R语言,这是一种专门用于统计的编程语言,里面有很多高级功能。

另外,我觉得你可能不需要用到MANOVA。MANOVA是用来处理多个相互影响的因变量的,而你这里其实只需要用ANOVA就可以了。

在R中你可以做的一些事情的例子:

bybrowser = lm(value ~ browser, data=visitors)
anova(bybrowser)
byreferrer = lm(value ~ referrer, data=visitors)
anova(byreferrer)
byreferrerandbrowser = lm(value ~ browser * referrer, data=visitors)
anova(byreferrerandbrowser)

需要注意的是,这些都假设你的数据是符合正态分布的。你应该检查一下这个假设(可以用hist(visitors$value)来开始)。如果数据不符合正态分布,可以尝试对数据进行归一化处理(比如取对数),或者使用合适的非参数检验。

最后,如果你想要关于统计方面的建议,有一个专门的网站可以提供帮助:https://stats.stackexchange.com/

撰写回答