scipy.stats.

pearsonr#

scipy.stats.pearsonr(x, y, *, альтернатива='two-sided', метод=None, ось=0)[источник]#

Коэффициент корреляции Пирсона и p-значение для проверки отсутствия корреляции.

Коэффициент корреляции Пирсона [1] измеряет линейную зависимость между двумя наборами данных. Как и другие коэффициенты корреляции, этот варьируется от -1 до +1, где 0 означает отсутствие корреляции. Корреляции -1 или +1 означают точную линейную зависимость. Положительные корреляции означают, что при увеличении x увеличивается и y. Отрицательные корреляции означают, что при увеличении x, y уменьшается.

Эта функция также выполняет проверку нулевой гипотезы о том, что распределения, лежащие в основе выборок, некоррелированы и нормально распределены. (См. Kowalski [3] для обсуждения влияния ненормальности входных данных на распределение коэффициента корреляции.) P-значение приблизительно указывает вероятность того, что некоррелированная система произведёт наборы данных с корреляцией Пирсона, по крайней мере, столь же экстремальной, как вычисленная из этих наборов данных.

Параметры:
xarray_like

Входной массив.

yarray_like

Входной массив.

осьint или None, по умолчанию

Ось, вдоль которой выполняется вычисление. По умолчанию 0. Если None, массивы сглаживаются перед выполнением вычисления.

Добавлено в версии 1.14.0.

альтернатива{‘two-sided’, ‘greater’, ‘less’}, опционально

Определяет альтернативную гипотезу. По умолчанию 'two-sided'. Доступны следующие опции:

  • 'two-sided': корреляция ненулевая

  • 'less': корреляция отрицательная (меньше нуля)

  • 'greater': корреляция положительная (больше нуля)

Добавлено в версии 1.9.0.

методResamplingMethod, опционально

Определяет метод, используемый для вычисления p-значения. Если метод является экземпляром PermutationMethod/MonteCarloMethod, p-значение вычисляется с использованием scipy.stats.permutation_test/scipy.stats.monte_carlo_test с предоставленными параметрами конфигурации и другими соответствующими настройками. В противном случае p-значение вычисляется, как описано в примечаниях.

Добавлено в версии 1.11.0.

Возвращает:
результатPearsonRResult

Объект со следующими атрибутами:

статистикаfloat

Коэффициент корреляции Пирсона.

p-значениеfloat

P-значение, связанное с выбранной альтернативой.

Объект имеет следующий метод:

confidence_interval(confidence_level, method)

Это вычисляет доверительный интервал коэффициента корреляции статистика для заданного уровня доверия. Доверительный интервал возвращается в namedtuple с полями низкий и высокий. Если метод не предоставлен, доверительный интервал вычисляется с использованием преобразования Фишера [1]. Если метод является экземпляром BootstrapMethod, доверительный интервал вычисляется с использованием scipy.stats.bootstrap с предоставленными параметрами конфигурации и другими соответствующими настройками. В некоторых случаях доверительные пределы могут быть NaN из-за вырожденной повторной выборки, что типично для очень маленьких выборок (~6 наблюдений).

Вызывает:
ValueError

Если x и y не имеют длины как минимум 2.

Предупреждает:
ConstantInputWarning

Возникает, если входные данные являются постоянным массивом. Коэффициент корреляции не определен в этом случае, поэтому np.nan возвращается.

NearConstantInputWarning

Возникает, если входные данные «почти» постоянны. Массив x считается почти постоянной, если norm(x - mean(x)) < 1e-13 * abs(mean(x)). Численные ошибки в вычислении x - mean(x) в этом случае может привести к неточному вычислению r.

Смотрите также

spearmanr

Коэффициент корреляции Спирмена.

kendalltau

Тау Кендалла, мера корреляции для порядковых данных.

Корреляция Пирсона

Расширенный пример

Примечания

Коэффициент корреляции рассчитывается следующим образом:

\[r = \frac{\sum (x - m_x) (y - m_y)} {\sqrt{\sum (x - m_x)^2 \sum (y - m_y)^2}}\]

где \(m_x\) является средним вектора x и \(m_y\) является средним значением вектора y.

В предположении, что x и y взяты из независимых нормальных распределений (так что коэффициент корреляции генеральной совокупности равен 0), функция плотности вероятности выборочного коэффициента корреляции r равна ([1], [2]):

\[f(r) = \frac{{(1-r^2)}^{n/2-2}}{\mathrm{B}(\frac{1}{2},\frac{n}{2}-1)}\]

где n — количество выборок, а B — бета-функция. Это иногда называют точным распределением r. Это распределение, которое используется в pearsonr для вычисления p-значения, когда метод параметр оставлен со значением по умолчанию (None). Распределение является бета-распределением на интервале [-1, 1] с равными параметрами формы a = b = n/2 - 1. В терминах реализации бета-распределения в SciPy распределение r имеет вид:

dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)

Значение p по умолчанию, возвращаемое pearsonr является двусторонним p-значением. Для заданной выборки с коэффициентом корреляции r, p-значение - это вероятность того, что abs(r') случайной выборки x' и y', взятой из генеральной совокупности с нулевой корреляцией, будет больше или равна abs(r). В терминах объекта dist как показано выше, p-значение для заданных r и длины n может быть вычислено как:

p = 2*dist.cdf(-abs(r))

Когда n равно 2, указанное непрерывное распределение не определено корректно. Можно интерпретировать предел бета-распределения при стремлении параметров формы a и b к a = b = 0 как дискретное распределение с равными вероятностными массами при r = 1 и r = -1. Более непосредственно можно заметить, что при данных x = [x1, x2] и y = [y1, y2] и предположении x1 != x2 и y1 != y2 единственными возможными значениями для r являются 1 и -1. Поскольку abs(r') для любой выборки x' и y' длиной 2 будет равен 1, двустороннее p-значение для выборки длиной 2 всегда равно 1.

Для обратной совместимости возвращаемый объект также ведёт себя как кортеж длины два, содержащий статистику и p-значение.

pearsonr имеет экспериментальную поддержку совместимых с Python Array API Standard бэкендов в дополнение к NumPy. Пожалуйста, рассмотрите тестирование этих функций, установив переменную окружения SCIPY_ARRAY_API=1 и предоставление массивов CuPy, PyTorch, JAX или Dask в качестве аргументов массива. Поддерживаются следующие комбинации бэкенда и устройства (или других возможностей).

Библиотека

CPU

GPU

NumPy

н/д

CuPy

н/д

PyTorch

JAX

⚠️ нет JIT

Dask

⚠️ вычисляет граф

н/д

См. Поддержка стандарта array API для получения дополнительной информации.

Ссылки

[1] (1,2,3)

"Коэффициент корреляции Пирсона", Википедия, https://en.wikipedia.org/wiki/Pearson_correlation_coefficient

[2]

Student, «Probable error of a correlation coefficient», Biometrika, Том 6, Выпуск 2-3, 1 сентября 1908, стр. 302-310.

[3]

C. J. Kowalski, «On the Effects of Non-Normality on the Distribution of the Sample Product-Moment Correlation Coefficient» Journal of the Royal Statistical Society. Series C (Applied Statistics), Vol. 21, No. 1 (1972), pp. 1-12.

Примеры

>>> import numpy as np
>>> from scipy import stats
>>> x, y = [1, 2, 3, 4, 5, 6, 7], [10, 9, 2.5, 6, 4, 3, 2]
>>> res = stats.pearsonr(x, y)
>>> res
PearsonRResult(statistic=-0.828503883588428, pvalue=0.021280260007523286)

Для выполнения точной перестановочной версии теста:

>>> rng = np.random.default_rng()
>>> method = stats.PermutationMethod(n_resamples=np.inf, random_state=rng)
>>> stats.pearsonr(x, y, method=method)
PearsonRResult(statistic=-0.828503883588428, pvalue=0.028174603174603175)

Для выполнения теста при нулевой гипотезе, что данные были извлечены из uniform распределения:

>>> method = stats.MonteCarloMethod(rvs=(rng.uniform, rng.uniform))
>>> stats.pearsonr(x, y, method=method)
PearsonRResult(statistic=-0.828503883588428, pvalue=0.0188)

Для получения асимптотического 90% доверительного интервала:

>>> res.confidence_interval(confidence_level=0.9)
ConfidenceInterval(low=-0.9644331982722841, high=-0.3460237473272273)

И для доверительного интервала бутстрапа:

>>> method = stats.BootstrapMethod(method='BCa', rng=rng)
>>> res.confidence_interval(confidence_level=0.9, method=method)
ConfidenceInterval(low=-0.9983163756488651, high=-0.22771001702132443)  # may vary

Если предоставлены N-мерные массивы, несколько тестов выполняются в одном вызове в соответствии с теми же соглашениями, что и большинство scipy.stats функции:

>>> rng = np.random.default_rng()
>>> x = rng.standard_normal((8, 15))
>>> y = rng.standard_normal((8, 15))
>>> stats.pearsonr(x, y, axis=0).statistic.shape  # between corresponding columns
(15,)
>>> stats.pearsonr(x, y, axis=1).statistic.shape  # between corresponding rows
(8,)

Для выполнения всех попарных сравнений между срезами массивов используйте стандартные техники трансляции NumPy. Например, чтобы вычислить корреляцию между всеми парами строк:

>>> stats.pearsonr(x[:, np.newaxis, :], y, axis=-1).statistic.shape
(8, 8)

Существует линейная зависимость между x и y, если y = a + b*x + e, где a,b — константы, а e — случайная ошибка, предполагаемая независимой от x. Для простоты предположим, что x стандартно нормален, a=0, b=1, и пусть e следует нормальному распределению со средним нуль и стандартным отклонением s>0.

>>> rng = np.random.default_rng()
>>> s = 0.5
>>> x = stats.norm.rvs(size=500, random_state=rng)
>>> e = stats.norm.rvs(scale=s, size=500, random_state=rng)
>>> y = x + e
>>> stats.pearsonr(x, y).statistic
0.9001942438244763

Это должно быть близко к точному значению, заданному

>>> 1/np.sqrt(1 + s**2)
0.8944271909999159

Для s=0.5 мы наблюдаем высокий уровень корреляции. В целом, большая дисперсия шума уменьшает корреляцию, в то время как корреляция приближается к единице, когда дисперсия ошибки стремится к нулю.

Важно помнить, что отсутствие корреляции не подразумевает независимость, если (x, y) не является совместно нормальным. Корреляция может быть даже нулевой при очень простой структуре зависимости: если X следует стандартному нормальному распределению, пусть y = abs(x). Заметим, что корреляция между x и y равна нулю. Действительно, поскольку математическое ожидание x равно нулю, cov(x, y) = E[x*y]. По определению, это равно E[x*abs(x)], что равно нулю из-за симметрии. Следующие строки кода иллюстрируют это наблюдение:

>>> y = np.abs(x)
>>> stats.pearsonr(x, y)
PearsonRResult(statistic=-0.05444919272687482, pvalue=0.22422294836207743)

Ненулевой коэффициент корреляции может вводить в заблуждение. Например, если X имеет стандартное нормальное распределение, определим y = x, если x < 0, и y = 0 в противном случае. Простой расчёт показывает, что corr(x, y) = sqrt(2/Pi) = 0.797…, что подразумевает высокий уровень корреляции:

>>> y = np.where(x < 0, x, 0)
>>> stats.pearsonr(x, y)
PearsonRResult(statistic=0.861985781588, pvalue=4.813432002751103e-149)

Это неинтуитивно, поскольку нет зависимости x и y, если x больше нуля, что происходит примерно в половине случаев при выборке x и y.

Для более подробного примера см. Корреляция Пирсона.