代码之家  ›  专栏  ›  技术社区  ›  David Pfeffer

用标准差法消除sqlserver中的异常值

  •  3
  • David Pfeffer  · 技术社区  · 14 年前

    我试图通过标准差消除SQLServer2008中的异常值。我只希望记录中包含一个特定列的值在+/-1标准偏差该列的平均值。

    我怎样才能做到这一点?

    3 回复  |  直到 10 年前
        1
  •  16
  •   amelvin    14 年前

    如果假设事件呈钟形曲线分布,则只有68%的值与平均值相差1个标准差(95%的值被2个标准差覆盖)。

    我将加载一个变量,其中包含范围的标准偏差(使用 stdev / stdevp sql函数),然后选择在适当的标准偏差数范围内的值。

    declare @stdtest table (colname varchar(20), colvalue int)
    
    insert into @stdtest (colname, colvalue) values ('a', 2)
    insert into @stdtest (colname, colvalue) values ('b', 4)
    insert into @stdtest (colname, colvalue) values ('c', 4)
    insert into @stdtest (colname, colvalue) values ('d', 4)
    insert into @stdtest (colname, colvalue) values ('e', 5)
    insert into @stdtest (colname, colvalue) values ('f', 5)
    insert into @stdtest (colname, colvalue) values ('g', 7)
    insert into @stdtest (colname, colvalue) values ('h', 9)
    
    declare @std decimal
    declare @mean decimal
    declare @lower decimal
    declare @higher decimal
    declare @noofstds int
    
    select @std = STDEV(colvalue), @mean = AVG(colvalue) from @stdtest
    
    --68%
    set @noofstds = 1
    select @lower = @mean - (@noofstds * @std)
    select @higher = @mean + (@noofstds * @std)
    
    select @lower, @higher, * from @stdtest where colvalue between @lower and @higher
    
    --returns rows with a colvalue between 3 and 7 inclusive
    
    --95%
    set @noofstds = 2
    select @lower = @mean - (@noofstds * @std)
    select @higher = @mean + (@noofstds * @std)
    
    select @lower, @higher, * from @stdtest where colvalue between @lower and @higher
    
    --returns rows with a colvalue between 1 and 9 inclusive
    
        2
  •  4
  •   Mike M.    14 年前

    SQL中有一个名为STDEV的聚合函数,它将为您提供标准偏差。这是困难的部分-然后只要找到平均值和+/-1标准偏差值之间的范围。

    这是你可以做的一种方法-

        create table #test
    (
       testNumber int
       )
    
       INSERT INTO #test (testNumber)
       SELECT  2
       UNION ALL 
       SELECT 4
       UNION ALL 
       SELECT 4
       UNION ALL 
       SELECT 4
       UNION ALL 
       SELECT 5
       UNION ALL 
       SELECT 5
       UNION ALL 
       SELECT 7
       UNION ALL 
       SELECT 9
    
       SELECT testNumber FROM #test t
       JOIN (
        SELECT STDEV (testnumber) as [STDEV], AVG(testnumber) as mean
        FROM #test
            ) X on t.testNumber >= X.mean - X.STDEV AND t.testNumber <= X.mean + X.STDEV
    
        3
  •  0
  •   duffymo    14 年前

    我会小心想想你在做什么。丢弃异常值可能意味着你正在丢弃那些可能不符合预先设想的世界观的信息,而这可能是非常错误的。这些异常值可能是罕见的“黑天鹅”,虽然不像你想象的那么罕见,但意义重大。