Закон Бенфорда в Java - как сделать математическую функцию в Java - PullRequest
5 голосов
/ 19 октября 2011

У меня быстрый вопрос. Я пытаюсь создать приложение для обнаружения мошенничества в Java, которое будет основано в первую очередь на законе Бенфорда. Закон Бенфорда очень крутой, его можно интерпретировать так, что в реальной финансовой транзакции первая цифра обычно равна 1, 2 или 3 и очень редко 8, 9. Я не смог получить формулу Бенфорда переведено в код, который может быть запущен на Java.

http://www.mathpages.com/home/kmath302/kmath302.htm Эта ссылка содержит больше информации о том, что такое закон Бенфорда и как его можно использовать.

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

Большое спасибо !!

Ответы [ 3 ]

5 голосов
/ 19 октября 2011

@ Руи упомянул, как вычислить функцию распределения вероятностей, но это не сильно вам поможет.

То, что вы хотите использовать, это либо критерий Колмогорова-Смирнова , либо критерий хи-квадрат . Оба предназначены для сравнения данных с известным распределением вероятностей, чтобы определить, вероятно ли / вероятно, что набор данных имеет такое распределение вероятностей.

Хи-квадрат для дискретных распределений, а K-S для непрерывного.


Для использования хи-квадрат с законом Бенфорда вы просто создадите гистограмму H [N], например, с 9 ячейками N = 1,2, ... 9, выполните итерацию по набору данных, чтобы проверить первую цифру для подсчета количества выборок для каждой из 9 ненулевых цифр (или первых двух цифр с 90 ячейками). Затем выполните тест хи-квадрат, чтобы сравнить гистограмму с ожидаемым числом E [N].

Например, допустим, у вас есть 100 частей данных. E [N] может быть вычислено из закона Бенфорда:

E[1] = 30.1030 (=100*log(1+1))
E[2] = 17.6091 (=100*log(1+1/2))
E[3] = 12.4939 (=100*log(1+1/3))
E[4] =  9.6910
E[5] =  7.9181
E[6] =  6.6946
E[7] =  5.7992
E[8] =  5.1152
E[9] =  4.5757

Затем вычислите & Chi; 2 = sum ((H [k] -E [k]) ^ 2 / E [k]) и сравните с пороговым значением, указанным в тесте. (Здесь мы имеем фиксированное распределение без параметров, поэтому число параметров s = 0 и p = s + 1 = 1, а количество бинов n равно 9, поэтому количество степеней свободы = np = 8 *. Затем вы идете к своему удобному хи-квадрату хи-квадрат и смотрите, выглядят ли числа в порядке. Для 8 степеней свободы уровни уверенности выглядят так:

& Chi; 2 > 13.362: 10% вероятность того, что набор данных по-прежнему соответствует закону Бенфорда

& Chi; 2 > 15.507: 5% вероятность того, что набор данных по-прежнему соответствует закону Бенфорда

& Chi; 2 > 17.535: 2,5% вероятность того, что набор данных по-прежнему соответствует закону Бенфорда

& Chi; 2 > 20.090: 1% вероятность того, что набор данных по-прежнему соответствует закону Бенфорда

& Chi; 2 > 26,125: 0,1% вероятность того, что набор данных по-прежнему соответствует закону Бенфорда

Предположим, ваша гистограмма дала H = [29,17,12,10,8,7,6,5,6] для & Chi; 2 = 0,5585. Это очень близко к ожидаемому распределению. (может быть, даже слишком близко!)

Теперь предположим, что ваша гистограмма дала H = [27,16,10,9,5,11,6,5,11] для a & Chi; 2 = 13,89. Вероятность того, что эта гистограмма получена из распределения, соответствующего закону Бенфорда, составляет менее 10%. Поэтому я бы назвал набор данных сомнительным, но не слишком.

Обратите внимание, что вы должны выбрать уровень значимости (например, 10% / 5% / и т. Д.). Если вы используете 10%, ожидайте, что примерно 1 из каждых 10 наборов данных, которые действительно из дистрибутива Benford, потерпят неудачу, даже если они в порядке. Это решение суда.

Похоже, что Apache Commons Math имеет Java-реализацию теста хи-квадрат:

ChiSquareTestImpl.chiSquare(double[] expected, long[] observed)


* примечание о степенях свободы = 8: это имеет смысл; у вас есть 9 чисел, но у них есть 1 ограничение, а именно все они должны складываться в размер набора данных, поэтому, когда вы знаете первые 8 чисел гистограммы, вы можете вычислить девятое.


Колмогоров-Смирнов на самом деле проще (чего я не понял, пока не нашел достаточно простое утверждение о том, как это работает), но работает для непрерывных распределений. Метод работает так:

  • Вы вычисляете интегральную функцию распределения (CDF) для своего распределения вероятности.
  • Вы вычисляете эмпирическую функцию кумулятивного распределения (ECDF), которую легко получить, упорядочив набор данных в отсортированном порядке.
  • Вы найдете D = (приблизительно) максимальное вертикальное расстояние между двумя кривыми.

enter image description here

Давайте разберемся с ними более подробно для закона Бенфорда.

  1. CDF для закона Бенфорда: это просто C = log 10 x, где x находится в интервале [1,10), то есть включает 1, но исключает 10. Это можно легко увидеть если вы посмотрите на обобщенную форму закона Бенфорда , и вместо записи в нее log (1 + 1 / n), запишите ее как log (n + 1) -log (n) - другими словами , чтобы получить вероятность каждого бина, они вычитают последовательные различия log (n), поэтому log (n) должен быть CDF

  2. ECDF: возьмите свой набор данных, и для каждого числа сделайте знак положительным, напишите его в научной записи и установите показатель степени в 0. (Не уверен, что делать, если у вас число 0; это, кажется, не поддается анализу закона Бенфорда.) Затем сортируйте числа в порядке возрастания. ECDF - это число точек данных <= x для любого действительного x. </p>

  3. Рассчитать максимальную разницу D = max (d [k]) для каждого d [k] = max (CDF (y [k]) - (k-1) / N, k / N - CDF (y [к]).

Вот пример: предположим, наш набор данных = [3.02, 1.99, 28.3, 47, 0.61]. Тогда ECDF представляется отсортированным массивом [1.99, 2.83, 3.02, 4.7, 6.1], и вы вычисляете D следующим образом:

D = max(
  log10(1.99) - 0/5, 1/5 - log10(1.99),
  log10(2.83) - 1/5, 2/5 - log10(2.83),
  log10(3.02) - 2/5, 3/5 - log10(3.02),
  log10(4.70) - 3/5, 4/5 - log10(4.70),
  log10(6.10) - 4/5, 5/5 - log10(6.10)
)

, что = 0,2988 (= log10 (1,99) - 0).

Наконец, вам нужно использовать статистику D - мне кажется, я не могу найти в Интернете никаких авторитетных таблиц, но Apache Commons Math имеет KolmogorovSmirnovDistributionImpl.cdf () функцию, которая принимает рассчитанное значение D в качестве входных данных и сообщает вам вероятность того, что D будет меньше, чем это. Вероятно, проще взять 1-cdf (D), который сообщает вам вероятность того, что D будет больше или равно вычисляемому вами значению: если это 1% или 0,1%, это, вероятно, означает, что данные не соответствуют закону Бенфорда. , но если это 25% или 50%, это, вероятно, хороший матч.

4 голосов
/ 19 октября 2011

Если я правильно понимаю, вам нужна формула Бенфорда в синтаксисе Java?

public static double probability(int i) {   
    return Math.log(1+(1/(double) i))/Math.log(10);
}

Не забудьте вставить

import java.lang.Math;

после объявления пакета.

Я нахожу это подозрительным, пока никто не ответил на этот вопрос ....> _>

1 голос
/ 22 октября 2011

Я думаю, что вы ищете что-то вроде этого:

for(int i = (int)Math.pow(10, position-1); i <= (Math.pow(10, position)-1); i++)
        {
           answer +=  Math.log(1+(1/(i*10+(double) digit)));
        }

answer *= (1/Math.log(10)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...