Рассматриваем реализацию закона Бенфорда на языке программирования Julia с использованием последовательности Фибоначчи.
Закон Бенфорда – это эмпирический закон, описывающий распределение первых цифр в наборах числовых данных из реальной жизни. Согласно этому закону, цифра 1 встречается в качестве первой значительно чаще, чем другие цифры (около 30%), а цифра 9 – реже всего (менее 5%). Закон имеет широкое применение в области аудита данных, выявления фальсификаций и экономических анализов.
В данном примере мы реализуем закон Бенфорда на языке программирования Julia. Также мы создадим последовательность чисел Фибоначчи, применим к ней закон, а затем построим график и выведем сравнение между эмпирическими данными и теоретическим распределением.
Правило Бенфорда задается формулой:
где - первая цифра от 1 до 9, а - вероятность этой цифры быть первой.
benford(numbers)
-- вычисляет частоты первых цифр в наборе чисел.
Возвращает массив из 9 элементов, где i-й элемент показывает, какая доля чисел начинается с цифры i.
Определяем итератор для генерации последовательности чисел Фибоначчи. Base.iterate
реализуется таким образом, чтобы можно было работать с бесконечным потоком, используя big.Int
для предотвращения переполнения.
Реализация протокола итерации для типа Fibonacci
Генерируем первые 1000 чисел из последовательности Фибоначчи
Base.Iterators.Take{Fibonacci}(Fibonacci(), 1000)
Рассчитываем наблюдаемые частоты первых цифр и переводим их в проценты
9-element Vector{Float64}:
30.099999999999998
17.7
12.5
9.6
8.0
6.7
5.6000000000000005
5.3
4.5
Вычисляем теоретические значения согласно закону Бенфорда и переводим в проценты
9-element Vector{Float64}:
30.10299956639812
17.609125905568124
12.493873660829994
9.691001300805642
7.918124604762482
6.694678963061322
5.799194697768673
5.115252244738129
4.575749056067514
Формируем таблицу для удобного сравнения данных
9×3 Matrix{Real}:
1 30.1 30.103
2 17.7 17.6091
3 12.5 12.4939
4 9.6 9.691
5 8.0 7.91812
6 6.7 6.69468
7 5.6 5.79919
8 5.3 5.11525
9 4.5 4.57575
Строим график баров для наблюдаемых данных и линии для ожидаемых
Выводим результаты на консоль в хорошо отформатированном виде
Benford's Law
Frequency of first digit
in 1000 Fibonacci numbers
digit observed expected
1 30.10% 30.10%
2 17.70% 17.61%
3 12.50% 12.49%
4 9.60% 9.69%
5 8.00% 7.92%
6 6.70% 6.69%
7 5.60% 5.80%
8 5.30% 5.12%
9 4.50% 4.58%
Мы рассмотрели реализацию закона Бенфорда на языке Julia. Написали функцию для вычисления распределения первых цифр, применили её к выборке из первых 1000 чисел Фибоначчи и сравнили полученные данные с теоретическими значениями закона. Также были построены наглядные графики, демонстрирующие совпадение наблюдаемой статистики с математическим законом. Такие методы могут использоваться для проверки естественности данных или для выявления возможных искажений и мошенничества.
{"id": "307f110b_ed74_4dbd_8821_b3ef000db9be", "data": [{"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [0.6, 0.6, 1.4, 1.4, 0.6, 0.6], "showlegend": true, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [30.099999999999998, 0, 0, 30.099999999999998, 30.099999999999998, 30.099999999999998], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [1.6, 1.6, 2.4, 2.4, 1.6, 1.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [17.7, 0, 0, 17.7, 17.7, 17.7], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [2.6, 2.6, 3.4, 3.4, 2.6, 2.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [12.5, 0, 0, 12.5, 12.5, 12.5], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [3.6, 3.6, 4.4, 4.4, 3.6, 3.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [9.6, 0, 0, 9.6, 9.6, 9.6], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [4.6, 4.6, 5.4, 5.4, 4.6, 4.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [8, 0, 0, 8, 8, 8], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [5.6, 5.6, 6.4, 6.4, 5.6, 5.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [6.7, 0, 0, 6.7, 6.7, 6.7], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [6.6, 6.6, 7.4, 7.4, 6.6, 6.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [5.6000000000000005, 0, 0, 5.6000000000000005, 5.6000000000000005, 5.6000000000000005], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [7.6, 7.6, 8.4, 8.4, 7.6, 7.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [5.3, 0, 0, 5.3, 5.3, 5.3], "type": "scatter"}, {"xaxis": "x", "fill": "tozeroy", "yaxis": "y", "x": [8.6, 8.6, 9.4, 9.4, 8.6, 8.6], "showlegend": false, "mode": "lines", "fillcolor": "rgba(0, 154, 250, 1.000)", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "line": {"color": "rgba(0, 0, 0, 1)", "dash": "solid", "width": 0}, "y": [4.5, 0, 0, 4.5, 4.5, 4.5], "type": "scatter"}, {"xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9934383202099737}, "yaxis": "y", "x": [1, 2, 3, 4, 5, 6, 7, 8, 9], "showlegend": false, "mode": "markers", "name": "1000 Fibonacci numbers", "legendgroup": "1000 Fibonacci numbers", "marker": {"symbol": "circle", "color": "rgba(0, 154, 250, 0.000)", "line": {"color": "rgba(0, 0, 0, 0)", "width": 1}, "size": 0}, "y": [30.099999999999998, 17.7, 12.5, 9.6, 8, 6.7, 5.6000000000000005, 5.3, 4.5], "type": "scatter"}, {"xaxis": "x", "colorbar": {"y": 0.5086805555555556, "title": {"text": ""}, "len": 0.8657316272965879, "x": 0.9934383202099737}, "yaxis": "y", "x": [1, 2, 3, 4, 5, 6, 7, 8, 9], "showlegend": true, "mode": "lines", "name": "P(d)=log10(1+1/d)", "legendgroup": "P(d)=log10(1+1/d)", "line": {"color": "rgba(227, 111, 71, 1.000)", "shape": "linear", "dash": "solid", "width": 5}, "y": [30.10299956639812, 17.609125905568124, 12.493873660829994, 9.691001300805642, 7.918124604762482, 6.694678963061322, 5.799194697768673, 5.115252244738129, 4.575749056067514], "type": "scatter"}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [1, 2, 3, 4, 5, 6, 7, 8, 9], "range": [0.05615999999999843, 9.943840000000002], "domain": [0.061654272382618835, 0.9934383202099737], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["1", "2", "3", "4", "5", "6", "7", "8", "9"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "first digit", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [{"yanchor": "top", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "paper", "showarrow": false, "text": "Benford's Law", "xref": "paper", "x": 0.5275462962962963}], "height": 400, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 10, 20, 30], "range": [0, 30.10299956639812], "domain": [0.07581474190726165, 0.9415463692038496], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0", "10", "20", "30"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "frequency %", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "auto", "xanchor": "auto", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 1}, "width": 1414.316650390625}}