2

異常値を定義して除外するために(統計/分析の使用のために)、このデータセット内のすべてのエントリを考慮するアルゴリズムが必要です。ただし、これはメモリにロードするにはデータが多すぎて、システムがチョークします。現在、これを使用してデータを収集および処理しています。

@scoreInnerFences = innerFence Post.where( :source => 1 ).
                                    order( :score ).
                                    pluck( :score )

外れ値の計算を正確に保つには、すべてのエントリを考慮する必要があるため、典型的な分割統治法を使用してもうまくいきません。どうすればこれを効率的に達成できますか?

innerFenceデータセットの下位四分位数と上位四分位数を特定し、それらの調査結果を使用して外れ値を計算します。このための (まだリファクタリングされていない、非 DRY の) コードは次のとおりです。

def q1(s)
  q = s.length / 4

  if s.length % 2 == 0
    return ( s[ q ] + s[ q - 1 ] ) / 2
  else
    return s[ q ]
  end
end

def q2(s)
  q = s.length / 4

  if s.length % 2 == 0
    return ( s[ q * 3 ] + s[ (q * 3) - 1 ] ) / 2
  else
    return s[ q * 3 ]
  end
end

def innerFence(s)
  q1 = q1(s)
  q2 = q2(s)

  iq = (q2 - q1) * 3

  if1 = q1 - iq
  if2 = q2 + iq

  return [if1, if2]
end
4

2 に答える 2

1

これは最善の方法ではありませんが、簡単な方法です。

いくつかのクエリを実行します。まず、スコアの数を数えます。

q = Post.where( :source => 1 ).count

次に、計算を行い、スコアを取得します

q1 = Post.where( :ソース => 1 ). 逆順(:スコア)。select("avg(score) as score"). offset(q).limit((q%2)+1)

q2 = Post.where( :source => 1 ). 逆順(:スコア)。select("avg(score) as score"). offset(q*3).limit((q%2)+1)

コードはおそらく間違っていますが、あなたはその考えを理解していると確信しています.

于 2012-04-09T23:09:19.677 に答える
0

大規模なデータセットの場合、ActiveRecord の下にドロップダウンすることがあります。私が想像するに、pluck を使用するのはメモリー ホグです。もちろん、移植性は低くなりますが、時にはそれだけの価値があります。

スコア = Post.connection.execute('スコア > 1 スコア順の投稿からスコアを選択').map(&:first)

それが400万の記録に十分役立つかどうかはわかりません. そうでない場合は、ストアド プロシージャを見てください。

于 2012-04-09T23:00:52.930 に答える