VariationValidator

Выкладываем свои наработки
Ответить
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

VariationValidator

Сообщение pirrat »

Тут написал валидатор под свой проект, вот теперь думаю, стоит ли его реализовывать как отдельный валидатор и выкладывать в расширениях, будет ли он интересен сообществу?

В любом случае надеюсь будет кому нибудь полезно=)

Смысл: проверить значение на валидность путем расчета коэффициента вариации и сравнения его с максимальным значением.
Простыми словами на примере: есть заведение, для заведения устанавливается "средний счет" каждым пользователем.
Соответственно при добавлении нового значения, оно должно не сильно отличаться от тех что уже добавлены, т.е. отклонение не должно превышать определённой величины от средней уже существующий выборки.

допустим если у нас уже существует выборка со значениями 100,200,300, то при разрешенном коэффициенте 60%, значения превышающие
480 или меньше 80 не пройдут, поскольку имеют большой коэффициент отклонения.

калькулятор - http://financial-analysis.ru/calculator/javFKStat.html

Реализация под конкретный проект, выглядит так:

Код: Выделить всё

    public function validateExpense($attribute, $params) {

        $sql = "SELECT expense
                FROM opinion WHERE place_id=:PlaceId";
        $command=$this->getDbConnection()->createCommand($sql);
        $command->bindValue(":PlaceId", $this->place_id);
        $listE = $command->queryColumn();

        //добавляем в список текущее значение счета
        array_push($listE, $this->expense);

        $n = count($listE);
        if($n < 2) return true;
        
        $a = array_sum($listE) / $n; // cреднее арифметическое

        $summ = 0;
        for($i=0;$i<$n;$i++) {
            $summ += pow($listE[$i]-$a, 2);
        }
        
        if($n > 1)  $n -= 1;

        $q2 = $summ/$n; //дисперсия
        $q = sqrt($q2); //среднеквадратичное отклонение
        $v = abs($q/$a)*100; //коэффициент вариации

        if($v > self::EXPENSE_MAX_V)
            $this->addError('expense','Коэффициент вариации по счету превышает максимальное значение');

    } 
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: VariationValidator

Сообщение Ekstazi »

По-моему mysql все таки поддерживает фу-ю AVG , а с ней не нужно тянуть все даные из БД
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: VariationValidator

Сообщение pirrat »

Я прекрасно знаю об агрегирующих функциях SQL, но в данный ситуации нужно тянуть все значения, чтоб добавить в выборку то значение которое валидируем и уже работать с этой выборкой...

Можно было бы просто сравнивать значение со средней по выборке и рассчитывать коэффициент, но более верно(ну насколько я знаком со статистикой) это именно расчитывать коэффициент вариации по всей выборки, поправте меня если не так, могу и ошибаться!
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: VariationValidator

Сообщение Ekstazi »

select sum(expense) as sum,count(expense) as count from FROM opinion WHERE place_id=:PlaceId
А если так ? А потом:
ср.ар.=(sum+val)/(count+1)
и уже после
select sum((expense-ср.ар)*(expense-ср.ар)) as summ FROM opinion WHERE place_id=:PlaceId
summ+=pow($val-ср.ар)
Ну и потом по алгоритму. Итого выходит два запроса, но, тянется меньше даных, и все операции перекладываются на mysql.
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: VariationValidator

Сообщение pirrat »

ну можно так, я не спорю, здесь мне кажется больше важен сам алгоритм...
Но, за замечание спасибо - как будет время, оптимизирую запрос!
Ответить