логическая статистика в Ruby - PullRequest
1 голос
/ 05 мая 2011

Так что это вопрос математики, рубина, статистики, и я просто не знаю, с чего начать, например, это может быть гораздо больше, чем я готов на момент, но, возможно, кто-то сможет пролить свет на то, как реализовать решение для такого рода вещей.

По сути, у меня есть набор целых чисел, скажем, мой хеш выглядит примерно так:

{ :count => 20, :timestamp => 1304566372 }
{ :count => 23, :timestamp => 1304566382 }
{ :count => 23, :timestamp => 1304566392 }
{ :count => 24, :timestamp => 1304566402 }
{ :count => 25, :timestamp => 1304566412 }
{ :count => 22, :timestamp => 1304566422 }
{ :count => 12, :timestamp => 1304566432 } # <= outlier 
{ :count => 21, :timestamp => 1304566442 }
{ :count => 20, :timestamp => 1304566452 }

И этот набор данных будет намного больше, но это может служить просто примером, поэтому я хочу найти результаты, которые больше всего отличаются от средних, однако целые числа будут следовать своего рода кривой, поэтому Вы не можете просто усреднить весь набор. Картинка как аналитика посетителей сайта.

Полагаю, мой вопрос, используя ruby, могу ли я использовать математику, чтобы как-то обобщить кривую и выяснить, какие элементы отличаются наиболее далеко от среднего значения в этом сегменте кривой?

Я не лучший математик, поэтому я могу использовать неверные термины, чтобы описать это. Большое спасибо за любую помощь или советы всем, ребята!

Ответы [ 2 ]

6 голосов
/ 05 мая 2011

Предполагая, что целочисленные значения попадают в нормальное распределение, вы могли бы применить правило 3-сигма (стандартное отклонение), чтобы найти выбросы.

Допустим, вы хотите быстро рассчитать среднее и стандартное отклонение списка целых чисел.Вы можете улучшить Enumerable следующим образом:

  module Enumerable

    def sum
      self.inject(0){|accum, i| accum + i }
    end

    def mean
      self.sum/self.length.to_f
    end

    def sample_variance
      m = self.mean
      sum = self.inject(0){|accum, i| accum +(i-m)**2 }
      (1/self.length.to_f*sum)
    end

    def standard_deviation
      return Math.sqrt(self.sample_variance)
    end

  end 

Затем вам нужно будет решить, каковы критерии для выбросов.Согласно правилу 3-сигма, 95% всех целочисленных значений попадают в два раза от значения стандартного отклонения (2 сигма) от среднего.Таким образом, вы могли бы сказать, что любое значение, отличие которого от среднего превышает 2 стандартных отклонения, является выбросом.

Например, если вы суммировали свои значения count в массив с именем a:

a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
m = a.mean  
# => 22.11111111111111
sd = a.standard_deviation  
# => 4.331908597692872

# assuming Ruby 1.9.2
a.keep_if { |n| (m-n).abs > (2*sd) } 
# => results in 12 remaining
1 голос
/ 05 мая 2011

Если вы просто ищете отправную точку, я бы предложил провести литературный поиск [1] ​​для «обнаружения выбросов в данных временных рядов». Если вы можете подобрать какое-либо уравнение к данным, вы можете посмотретькак далеко точки лежат от кривой.Если система более сложная и не может быть легко смоделирована, есть ряд стратегий, которым вы можете следовать, например ...

  • Просто посмотрите на дельту в countмежду точками данных.В вашей серии список дельт составляет [3,0,1,1,-3,-10,9,-1].Вы можете искать значения, которые превышают среднее значение этого списка более чем на несколько стандартных отклонений.По сути, вы ищете шипы, ища большие изменения в наклоне линии.

  • Посмотрите на меньшие окна с 3 или 5 точками, например, сначала посмотрите на точки1,2,3, затем точки 2,3,4, затем 3,4,5 и т. Д. Это похоже на первый подход, но алгоритм будет немного другим.

Имея больше информации о природе данных, можно, вероятно, выбрать какой-то оптимальный алгоритм, но быстрый и грязный может оказаться достаточно близким.

[1] Это термин старой школы, который простопричудливый способ сказать "Google"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...