这是一个数学问题...
在此之前我有一个关于标准化每月数据的问题: 如何生成拉伸图的 X 值?
我得到了一个很好的答案,而且效果很好,唯一的问题是现在我需要检查一个月的 X 值,其中 31 天与一个月的 X 值,其中 28 天。
所以我的问题是:如果我有两组这样的参数:
x | y x2 | y2
1 | 10 1.0 | 10
2 | 9 1.81 | 9.2
3 | 8 2.63 | 8.6
4 | 7 3.45 | 7.8
5 | 6 4.27 | 7
6 | 5 5.09 | 6.2
7 | 4 5.91 | 5.4
8 | 3 6.73 | 4.2
9 | 2 7.55 | 3.4
10 | 1 8.36 | 2.6
9.18 | 1.8
10.0 | 1.0
如您所见,这两个数据集的总体趋势是相同的。但是,如果我通过互相关函数(一般目标)运行这些值,我会得到一些不反映这一点的东西,因为数据集有两种不同的大小。
例如,如果您正在跟踪您每天跑了多少英里,那么现实世界的例子是:
在二月(28 天)的第一周,你每天跑一英里。在第二周,你每天跑两英里,等等。
在 3 月(31 天),你做同样的事情,但是跑一英里八天,跑两英里八天,跑三英里八天,跑四英里七天。
根据以下函数,相关系数应该几乎正好为 1:
class CrossCorrelator {
def variance = { x->
def v = 0
x.each{ v += it**2}
v/(x.size()) - (mean(x)**2)
}
def covariance = {x, y->
def z = 0
[x, y].transpose().each{ z += it[0] * it[1] }
(z / (x.size())) - (mean(x) * mean(y))
}
def coefficient = {x, y->
covariance(x,y) / (Math.sqrt(variance(x) * variance(y)))
}
}
def i = new CrossCorrelator()
i.coefficient(y values, y2 values)
仅查看数据集,如果我要获取 1、2、3、4、5、6、7、8、9 和 10 的值,图表似乎完全相同,并且函数将产生更准确的结果。
但是,由于长度不同,因此它是倾斜的。
有没有办法定位十二值数据集中整数的值是什么?我还没有找到一种简单的方法来做到这一点,但这将非常有帮助。
提前致谢,
5
编辑:根据请求,这里是生成图形 X 值的代码:
def x = (1..12)
def y = 10
change = {l, size ->
v = [1]
l.each{
v << ((((size-1)/(x.size() - 1)) * it) + 1)
}
v -= v.last()
return v
}
change(x, y)
编辑:根据另一个请求不工作代码:
def normalize( xylist, days ) {
xylist.collect { x, y -> [ x * ( days / xylist.size() ), y ] }
}
def change = {l, size ->
def v = [1]
l.each{
v << ((((size-1)/(l.size() - 1)) * it) + 1)
}
v -= v.last()
return v
}
def resample( list, min, max ) {
// We want a graph with integer points from min to max on the x axis
(min..max).collect { i ->
// find the values above and below this point
bounds = list.inject( [ a:null, b:null ] ) { r, p ->
// if the value is less than i, set it in r.a
if( p[ 0 ] < i )
r.a = p
// if it's bigger (and we don't already have a bigger point)
// then set it into r.b
if( !r.b && p[ 0 ] >= i )
r.b = p
r
}
// so now, bounds.a is the point below our required point, and bounds.b
// Deal with the first case (where a is null, because we are at the start)
if( !bounds.a )
[ i, list[ 0 ][ 1 ] ]
else {
// so work out the distance from bounds.a to bounds.b
dist = ( bounds.b[0] - bounds.a[0] )
// And how far the point i is along this line
r = ( i - bounds.a[0] ) / dist
// and recalculate the y figure for this point
y = ( ( bounds.b[1] - bounds.a[1] ) * r ) + bounds.a[1]
[ i, y ]
}
}
}
def feb = [9, 3, 7, 23, 15, 16, 17, 18, 19, 13, 14, 8, 13, 12, 15, 6, 7, 13, 19, 12, 7, 3, 4, 15, 6, 17, 8, 19]
def march = [8, 12, 4, 17, 11, 15, 12, 8, 9, 13, 12, 7, 3, 4, 8, 2, 17, 19, 21, 12, 12, 13, 14, 15, 16, 7, 8, 19, 21, 14, 16]
//X and Y Values for February
z = [(1..28), change(feb, 28)].transpose()
//X and Y Values for March stretched to 28 entries
o = [(1..31), change(march, 28)].transpose()
o1 = normalize(o, 28)
resample(o1, 1, 28)
如果我将 o 变量声明中的“march”切换为 (1..31),则脚本运行成功。当我尝试使用“march”时,我得到“java.lang.NullPointerException: Cannot invoke method getAt() on null object”
另外:我尽量不直接复制代码,因为这是不好的做法,所以我更改的功能之一基本上做同样的事情,它只是我的版本。我最终也会着手重构其余部分。但这就是为什么它略有不同。