В прошлой статье мы говорили о базовой статистике в Apache Spark. Сегодня рассмотрим проверку статистических гипотез с помощью Spark MLlib с примерами кода на Python. Читайте в этой статье: как провести критерий согласия хи-квадрат на соответствие и независимость для разных типов данных, критерий Колмогорова-Смирнова на соответствие нормальному распределению, а также как провести A/B-тестирование в Apache Spark.
Критерий согласия хи-квадрат в Spark MLlib
Проверка гипотез – это мощный инструмент в статистике, который позволяет определить, является ли результат статистически значимым, независимо от того, был ли этот результат случайным или нет. В настоящее время Spark MLlib поддерживает критерий согласия хи-квадрат (критерий согласия Пирсона) на соответствие и независимость. Для проверки Apache Spark принимает в качестве входного типа данных Vector, тогда как для проверки независимости принимает матрицу в качестве входных данных.
Spark MLlib также поддерживает входной тип RDD[LabeledPoint]
для дополнительного отбора признаков (feature selection) после проведения теста на независимость. О LabeledPoint
и матрицах говорили тут.
Для проведения критерия хи-квадрат используется метод chiSqTest
класса Statistics.
Критерий согласия хи-квадрат для одного признака
Пример кода на Python для проведения критерия хи-квадрат в Spark MLlib для одной выборки:
from pyspark.mllib.linalg import Matrices, Vectors from pyspark.mllib.regression import LabeledPoint from pyspark.mllib.stat import Statistics vec = Vectors.dense(0.1, 0.15, 0.2, 0.3, 0.25) # вычислить степень соответствия. # Если второй вектор для тестирования не указан в качестве # параметра, тест выполняется с равномерным распределением goodnessOfFitTestResult = Statistics.chiSqTest(vec) # сводка по теста, включая p-значение, степени свободы, # статистику теста, используемый метод и нулевую гипотезу. print("%s\n" % goodnessOfFitTestResult)
После вычислений можно взглянуть на получившуюся сводку с результатами, которые показывают, что нулевая гипотеза не может быть отклонена:
Chi squared test summary: method: pearson degrees of freedom = 4 statistic = 0.12499999999999999 pValue = 0.998126379239318 No presumption against null hypothesis: observed follows the same distribution as expected..
Критерий согласия хи-квадрат на независимость признаков матрицы
Для матриц точно также вызывается метод chiSqTest
. Код на Python для проведения хи-квадрат на независимость признаков матрицы Spark MLlib выглядят следующим образом:
mat = Matrices.dense(3, 2, [1.0, 3.0, 5.0, 2.0, 4.0, 6.0]) # критерий хи-квадрат на независимость признаков матрицы independenceTestResult = Statistics.chiSqTest(mat) # сводка по теста, включая p-значение, степени свободы, # статистику теста, используемый метод и нулевую гипотезу. print("%s\n" % independenceTestResult)
Сводка по критерию хи-квадрат после вычислений выше в Apache Spark говорит нам о том, что признаки – независимы:
Chi squared test summary: method: pearson degrees of freedom = 2 statistic = 0.14141414141414144 pValue = 0.931734784568187 No presumption against null hypothesis: the occurrence of the outcomes is statistically independent..
Критерий согласия хи-квадрат на независимость признаков маркированных векторов (LabeledPoint)
Структура LabeledPoint для каждого вектора определяет свою метку, т.е. это что-то вроде пары ключ-значение, где ключом является значение типа Double, а значением сам вектор. Критерий хи-квадрат проводится точно таким же способом как и выше – вызовом метода chiSqTest
. Для каждой метки составляется матрица признаков (столбцов) и проводится критерий на независимость.
# sc - экземпляр SparkContext obs = sc.parallelize([ LabeledPoint(1.0, [1.0, 0.0, 3.0]), LabeledPoint(1.0, [1.0, 2.0, 0.0]), LabeledPoint(1.0, [-1.0, 0.0, -0.5]) ]) # LabeledPoint(label, feature) # Сводка содержит массив объектов ChiSquaredTestResult # для каждого признака. featureTestResults = Statistics.chiSqTest(obs) for i, result in enumerate(featureTestResults): print("Column %d:\n%s" % (i + 1, result))
Критерий согласия Колмогорова и Критерий однородности Смирнова в Spark MLlib
Также в Spark MLlib можно провести критерий Колмогорова-Смирнова [1] на равенство распределений вероятностей. На основе этого критерия проверяется принадлежность выборки некоторому закону распределения (в настоящее время в Apache Spark поддерживается только проверка на нормальное распределение).
Чтобы провести критерий необходимо передать название желаемого распределения (пока только нормальное) с параметрами или функцию для вычисления кумулятивного распределения в соответствии с заданным теоретическим распределением. Происходит проверка нулевой гипотезы о том, что выборка взята из этого распределение. В случае, если проверяется соответствие нормальному распределению (distName="norm")
, но не предоставляются параметры распределения, критерий инициализируется с параметрами mean=0
, std=1
.
В Python API не доступно использование функции для вычисления кумулятивного распрделения в виде лямбда-выражений, только через прямую передачу данных. Код на Python для проведения критерия Колмогорова-Смирнова в Spark MLlib:
from pyspark.mllib.stat import Statistics parallelData = sc.parallelize([0.1, 0.15, 0.2, 0.3, 0.25]) # составление критерия. Первым параметром расределения является # среднее значение (0), а вторым - стандартное отклонение (1) testResult = Statistics.kolmogorovSmirnovTest(parallelData, "norm", 0, 1) # сводка, включая p-значение, статистику теста и нулевую гипотезу, # если p-значение указывает на значимость, мы можем отклонить # нулевую гипотезу. Обратите внимание, что функция Scala # с лямбда-выражением для вычисления CDF недоступна в API Python. print(testResult)
Результаты сводки показывают, что нулевая гипотеза не отклонена:
Kolmogorov-Smirnov test summary: degrees of freedom = 0 statistic = 0.539827837277029 pValue = 0.06821463111921133 Low presumption against null hypothesis: Sample follows theoretical distribution.
Потоковая проверка статистических гипотез с помощью Spark Streaming
В Spark MLlib есть онлайн-реализация некоторых тестов, например, А/B-тестирование [2]. Такие тесты могут быть вычислены с помощью Spark Streaming. Тесты выполняются на кортеже DStream[(Boolean, Double)]
, где первый элементом каждого такого кортежа является контрольная группа (при false) или тестовая группа (при true), а вторым элементом является само значение с наблюдением.
Потоковые критерии StreamingTest поддерживают следующие параметры:
peacePeriod
– количество точек начальных данных из потока, которые следует игнорировать, используется для смягчения эффектов новизны.windowSize
– количество прошлых пакетов для проверки гипотезы. При значении 0 кумулятивная обработка будет выполняться с использованием всех предыдущих пакетов.
Python API не поддерживает потоковые критерии, однако код на Scala мы оставим:
val data = ssc.textFileStream(dataDir) .map(line => line.split(",") match { case Array(label, value) => BinarySample(label.toBoolean, value.toDouble) }) val streamingTest = new StreamingTest() .setPeacePeriod(0) .setWindowSize(0) .setTestMethod("welch") val out = streamingTest.registerStream(data) out.print()
Еще больше подробностей о проверки статистических гипотез, а также о работе со Spark Streaming на примерах прикладных задач Data Sicence вы узнаете на специализированном курсе «Анализ данных с Apache Spark» в лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.