Здравствуйте. Неуверен верный ли раздел. Пытаюсь разобраться с критерием Кхи-квадрата.
Есть практическая задача: известно, что в некоторой выборке данных часть набора была сгенерирована при помощи генератора псевдослучайных чисел, а часть введена вручную. Требуется разделить сгенерированные данные от введенных вручную
Для теста пробую сделать на строках. В 2-м томе кнута искусство программирования есть вот такая формула
- количество выборочных значений,
- количество байт в выборке,
- вероятность,
- сколько раз в данных встречается
-й байт
Основная проблема для меня тут в вероятности
. Если я верно понимаю, то результат работы ГСПЧ является равномерным распределением (uniform distribution, поправьте если русский вариант термина неверный), значит вероятность появления символа должна быть
где
- мощность алфавита
Но тогда не подходит по условию, что сумма всех вероятностей должна быть равна 1, т.к суммирование проводится по количеству выборочных значений (observations, как оно на русском?), по числу
из формулы выше.
Собственно вопрос, как верно посчитать вероятность появления символа?
Вот примерный код что я накидал, но он очевидно работает неверно, в частности из-за неверного подсчета вероятности. Возможно есть еще какие-то проблемы неизвестные мне.
Код:
def pearson(s):
alphabet_power = 27 * 2 + 10 # digits, uppercase with lowercase latin alphabet
probability_uniform = 1.0 / alphabet_power # probability of appearence of a single byte in discrete uniform distribution
observations = {}
for i in s:
if i in list(observations.keys()):
observations[i] += 1.0
else:
observations[i] = 1.0
chi_square = 0
for i in list(observations.keys()):
A = (observations[i] ** 2) / probability_uniform
chi_square += A
chi_square /= len(s)
chi_square -= len(s)
return (chi_square, len(observations.keys()))
Вот вывод кода, примеры строк и
Код:
qRJ4c - (251.0, 5)
1r3LjbA2 - (248.0, 8)
leonell - (541.5714285714286, 4)
leo mariocelli - (461.42857142857144, 9)
aaaaaaaaaaaaaaaaaaaa - (5100.0, 1)
aaaaaaa - (1785.0, 1)
hello world chi-square - (420.1818181818182, 15)
AaaA - (508.0, 2)
Programmer - (450.8, 7)
Computer - (248.0, 8)
user - (252.0, 4)
F7df7wtf7fg73rgrrg - (664.6666666666666, 9)
Первые два являются машинно сгенерированными, остальные введены руками.
Уважаемые математики, что я делаю неверно? И каким образом потом интерпретировать данные?
Спасибо.
P.S. У вас тут какой-то особенный стиль латеха что ли? Из моего редактора формулы некорректно парсятся тут без $ символа.