2011-07-21 15 views
3

私は、巨大なスパイクを含む可能性のある特定の値の集合に対して有用な平均を計算する方法を探しています。 (例えば、21,54,34,14,20,300,23または1,1,1,1,200,1,100)、スパイクは、標準平均計算を使用するときに物事を捨てることができる。正規化平均のT-SQL

私は中央値を調べましたが、これは実際には望ましい結果をもたらしません。

Iは、T-SQL

に任意のアイデアをこれを実装したいと思いますか?

+0

スパイクが欲しくない場合は、標準偏差を調べる必要があります。 –

答えて

1

この方法です。

declare @t table (col1 int) 

insert @t 
select 21 union all 
select 54 union all 
select 34 union all 
select 14 union all 
select 20 union all 
select 300 union all 
select 23 union all 
select 1 union all 
select 1 union all 
select 1 union all 
select 1 union all 
select 200 union all 
select 1 union all 
select 100 


select avg(col1) from (
select top 67 percent col1 from (
select top 75 percent col1 from @t order by col1 
) a order by col1 desc) b 
0
  1. 対数ルールによってGROUP BYを作成
  2. (例えば3未満の場合)非代表基で
  3. 作成フィルタリング(HAVINGを使用して)(例えば数との差が10倍またはログの任意の他の塩基を超えます)
0

これを行う際の危険性は、これらのスパイクがすべて重要ではなく、捨てる価値があるとは確信できないということです。ある人の騒音は、別の人のブラックスワンです。

大量のデータが不必要に表示されることが心配な場合は、異常値の影響を受けにくい中央値のような数値を使用する方がよいでしょう。平均よりも計算するのは難しいですが、スパイクのように振る舞わない中心性の指標を与えます。

1

使用メディアンフィルタ:あなたは結果を計算する前に、最高と最低の25%を奪うことができ

SELECT AVG(value) 
FROM (
     SELECT TOP 1 value AS median 
     FROM (
       SELECT TOP 50 PERCENT value 
       FROM mytable 
       ORDER BY 
         value 
       ) q 
     ORDER BY 
       value DESC 
     ) q 
JOIN mytable m 
ON  ABS(LOG10(value) - LOG10(median)) <= @filter_level 
+0

+1、良い解決策 –

+0

ゼロまたは負の値を扱うときのエラー – MakkyNZ

0

OVER/PARTITION BYのようなウィンドウ機能を使用することを検討してください。これにより、特定の行グループ(名前、日付、時間など)内の除外項目を微調整できます。この例では、t-clausen.dkの例から行を借りて、ウィンドウをデモンストレーションするために名前を追加して展開します。

 
-- Set boundaries, like the TOP PERCENT used in the afore mentioned example 
DECLARE @UBOUND FLOAT, @LBOUND FLOAT

SET @UBOUND = 0.8 --(80%) SET @LBOUND = 0.2 --(20%)

--Build a CTE table ;WITH tb_example AS ( select [Val]=21,[fname]='Bill' union all select 54,'Tom' union all select 34,'Tom' union all select 14,'Bill' union all select 20,'Bill' union all select 300,'Tom' union all select 23,'Bill' union all select 1,'Tom' union all select 1,'Tom' union all select 1,'Bill' union all select 1,'Tom' union all select 200,'Bill' union all select 1,'Tom' union all select 12,'Tom' union all select 8,'Tom' union all select 11,'Bill' union all select 100,'Bill' )

--Outer query applies criteria of your choice to remove spikes SELECT fname,AVG(Val) FROM ( -- Inner query applies windowed aggregate values for outer query processing SELECT * ,ROW_NUMBER() OVER (PARTITION BY fname order by Val) RowNum ,COUNT(*) OVER (PARTITION BY fname) RowCnt ,MAX(Val) OVER (PARTITION BY fname) MaxVal ,MIN(Val) OVER (PARTITION BY fname) MinVal FROM tb_example ) TB WHERE -- You can use the bounds to eliminate the top and bottom 20% RowNum BETWEEN (RowCnt*@LBOUND) and (RowCnt*@UBOUND) -- Limits window -- Or you may chose to simply eliminate the Max and MIN values OR (Val > MinVal AND Val < MaxVal) -- Removes Lowest and Highest values GROUP BY fname

この場合、基準とAVGの両方をfnameで使用します。しかし、このテクニックでスパイクを緩和する方法を選択すると、空が限界になります。