これは一種の厄介な質問です...
これの前に、ここで月次データの正規化について質問がありました: 引き伸ばされたグラフのX値を生成する方法は?
私は良い答えを得ました、そしてそれはうまくいきます、唯一の問題は今私が28で月のX値に対して31日で1ヶ月のX値をチェックする必要があるということです。
したがって、私の質問は次のようになります。次のような2つのパラメータセットがある場合:
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
ご覧のとおり、一般的な傾向はこれら2つのデータセットで同じです。ただし、これらの値を相互相関関数(一般的な目標)で実行すると、データセットのサイズが2つ異なるため、これを反映していないものが返されます。
これの実際の例は、たとえば、1日に何マイル走るかを追跡している場合です。
2月(28日)の最初の週は、毎日1マイル走ります。2週目は、毎日2マイル走ります。
3月(31日)も同じことをしますが、1マイルで8日間、2マイルで8日間、3マイルで8日間、4マイルで7日間走ります。
次の関数による相関係数は、ほぼ正確に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の値を取得した場合、グラフはまったく同じになるように見えます。関数は次のようになります。より正確な結果を生成します。
ただし、長さが同じではないため、ゆがんでいます。
12値データセットの整数の値を特定する方法はありますか?私はそれを行う簡単な方法を見つけていませんが、これは信じられないほど役に立ちます。
前もって感謝します、
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:nullオブジェクトでメソッドgetAt()を呼び出せません」が表示されます。
また、悪い習慣であるという理由だけでコードを直接コピーしないようにしています。そのため、変更した関数の1つは基本的に同じことを実行します。これは、私のバージョンです。最終的には残りのリファクタリングにも取り掛かります。しかし、それがわずかに異なる理由です。