Scipy.stats.pearsonr: примеры (PYTHON)

Использование функции pearsonr для оценки корреляции в Python
Раздел: SciPy, Статистика
scipy.stats.pearsonr(x: array_like, y: array_like): tuple (correlation coefficient, p-value)

Описание функции scipy.stats.pearsonr

Функция scipy.stats.pearsonr вычисляет коэффициент корреляции Пирсона и p-значение для проверки гипотезы о некореллированности двух наборов данных. Корреляция Пирсона измеряет линейную зависимость между переменными. Значение коэффициента находится в диапазоне от -1 до 1, где 1 означает полную положительную линейную зависимость, -1 – полную отрицательную, а 0 – отсутствие линейной зависимости.

Функция часто применяется в статистическом анализе, машинном обучении и научных исследованиях для оценки силы и направления линейной связи.

Аргументы функции

  • x, y (array_like): Два одномерных массива данных одинаковой длины. Массивы могут содержать числа (целые или с плавающей точкой).
  • alternative (str, optional): Определяет альтернативную гипотезу для расчета p-значения. Доступные варианты: 'two-sided' (двусторонняя, по умолчанию), 'greater' (положительная корреляция), 'less' (отрицательная корреляция). Параметр добавлен в SciPy версии 1.9.

Возвращаемые значения

  • statistic (float): Коэффициент корреляции Пирсона.
  • pvalue (float): p-значение для выбранной альтернативной гипотезы.

Если входные массивы имеют длину менее 2, функция вызывает исключение ValueError. Если дисперсия одного из массивов равна нулю (все элементы одинаковы), коэффициент корреляции не определяется и возвращается NaN.

Базовые примеры использования

Простой пример с положительной корреляцией:

import scipy.stats as stats
import numpy as np

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
corr, p_val = stats.pearsonr(x, y)
print(f'Коэффициент корреляции: {corr:.4f}')
print(f'p-значение: {p_val:.4f}')
Коэффициент корреляции: 1.0000
p-значение: 0.0000

Пример с отрицательной корреляцией и использованием параметра alternative:

x = [1, 2, 3, 4, 5]
y = [5, 4, 3, 2, 1]
corr, p_val = stats.pearsonr(x, y, alternative='less')
print(f'Коэффициент корреляции: {corr:.4f}')
print(f'p-значение: {p_val:.4f}')
Коэффициент корреляции: -1.0000
p-значение: 0.0000

Пример с отсутствием линейной связи:

np.random.seed(42)
x = np.random.randn(10)
y = np.random.randn(10)
corr, p_val = stats.pearsonr(x, y, alternative='two-sided')
print(f'Коэффициент корреляции: {corr:.4f}')
print(f'p-значение: {p_val:.4f}')
Коэффициент корреляции: -0.1034
p-значение: 0.7740

Альтернативные функции в Python

Для вычисления корреляций в Python существуют другие функции, которые могут быть полезны в различных сценариях.

  • numpy.corrcoef(x, y, rowvar=True) вычисляет матрицу корреляции. Возвращает матрицу коэффициентов для нескольких переменных. Не предоставляет p-значений.
  • pandas.DataFrame.corr(method='pearson') удобен при работе с таблицами данных. Вычисляет попарные корреляции между столбцами DataFrame. Также без p-значений.
  • scipy.stats.spearmanr вычисляет корреляцию Спирмена (непараметрическая мера монотонной связи). Устойчива к выбросам.
  • scipy.stats.kendalltau вычисляет коэффициент корреляции Кендалла, еще одна непараметрическая мера, часто используется для данных с малым объемом или с повторяющимися значениями.

Функцию pearsonr предпочтительнее использовать, когда требуется именно коэффициент Пирсона вместе с p-значением для проверки гипотезы. Для простого вычисления коэффициента без p-значения может подойти numpy.corrcoef. В контексте анализа табличных данных удобен метод pandas.

Аналоги функции в других языках

В других языках программирования существуют аналогичные функции для вычисления корреляции Пирсона.

JavaScript (библиотека mathjs):

const math = require('mathjs');
const x = [1, 2, 3, 4, 5];
const y = [2, 4, 6, 8, 10];
const corr = math.corr(x, y);
console.log(corr); // 1
1

Java (Apache Commons Math):

import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
double[] x = {1, 2, 3, 4, 5};
double[] y = {2, 4, 6, 8, 10};
PearsonsCorrelation pc = new PearsonsCorrelation();
double corr = pc.correlation(x, y);
System.out.println(corr); // 1.0
1.0

PHP:

$x = [1, 2, 3, 4, 5];
$y = [2, 4, 6, 8, 10];
$corr = stats_stat_correlation($x, $y);
echo $corr; // 1
1

SQL (в некоторых СУБД, например PostgreSQL):

SELECT corr(x, y) FROM table_name;
1

C# (MathNet.Numerics):

using MathNet.Numerics.Statistics;
var x = new double[] {1, 2, 3, 4, 5};
var y = new double[] {2, 4, 6, 8, 10};
var corr = Correlation.Pearson(x, y);
Console.WriteLine(corr); // 1
1

Golang (gonum):

package main
import "gonum.org/v1/gonum/stat"
func main() {
    x := []float64{1, 2, 3, 4, 5}
    y := []float64{2, 4, 6, 8, 10}
    corr := stat.Correlation(x, y, nil)
    println(corr) // 1
}
1

Отличия от Python-функции часто заключаются в отсутствии возврата p-значения в стандартных библиотеках, необходимости использования внешних пакетов и в синтаксисе. Функция в SciPy предоставляет более полную статистическую информацию (p-значение) и гибкость за счет параметра alternative.

Частые ошибки при использовании

Ошибка при передаче массивов разной длины:

import scipy.stats as stats
x = [1, 2, 3]
y = [4, 5]
try:
    corr, p_val = stats.pearsonr(x, y)
except ValueError as e:
    print(f'Ошибка: {e}')
Ошибка: x and y must have length at least 2.

Ошибка при передаче массивов длины менее 2:

x = [1]
y = [2]
try:
    corr, p_val = stats.pearsonr(x, y)
except ValueError as e:
    print(f'Ошибка: {e}')
Ошибка: x and y must have length at least 2.

Возврат NaN при отсутствии вариации в данных (все элементы одного массива одинаковы):

x = [5, 5, 5, 5]
y = [1, 2, 3, 4]
corr, p_val = stats.pearsonr(x, y)
print(f'Коэффициент: {corr}')
print(f'p-значение: {p_val}')
Коэффициент: nan
p-значение: nan

Некорректное значение параметра alternative:

x = [1, 2, 3]
y = [4, 5, 6]
try:
    corr, p_val = stats.pearsonr(x, y, alternative='invalid')
except ValueError as e:
    print(f'Ошибка: {e}')
Ошибка: alternative must be 'two-sided', 'greater' or 'less'

Изменения в последних версиях SciPy

Начиная с версии SciPy 1.9, в функцию pearsonr добавлен параметр alternative, позволяющий выбирать альтернативную гипотезу для расчета p-значения. Ранее p-значение вычислялось только для двусторонней гипотезы. Это изменение позволяет проводить односторонние тесты.

В версии SciPy 1.11 была улучшена обработка крайних случаев, таких как данные с нулевой дисперсией, хотя поведение (возврат NaN) осталось прежним.

Пользователям рекомендуется обновлять SciPy для доступа к новым функциям и улучшениям производительности.

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

Обработка данных с пропущенными значениями с использованием маскирования:

Пример python
import numpy as np
import scipy.stats as stats

x = np.array([1, 2, np.nan, 4, 5])
y = np.array([2, 4, 6, np.nan, 10])
mask = ~(np.isnan(x) | np.isnan(y))
corr, p_val = stats.pearsonr(x[mask], y[mask])
print(f'Коэффициент корреляции: {corr:.4f}')
print(f'p-значение: {p_val:.4f}')
Коэффициент корреляции: 1.0000
p-значение: 0.0000

Использование с большими массивами данных и оценка времени выполнения:

Пример python
import time
np.random.seed(123)
N = 1000000
x_large = np.random.randn(N)
y_large = x_large * 0.5 + np.random.randn(N) * 0.5
start = time.time()
corr, p_val = stats.pearsonr(x_large, y_large)
elapsed = time.time() - start
print(f'Коэффициент: {corr:.4f}, p-значение: {p_val:.4f}')
print(f'Время вычисления: {elapsed:.3f} сек')
Коэффициент: 0.7074, p-значение: 0.0000
Время вычисления: 0.022 сек

Сравнение корреляций для разных альтернативных гипотез на одних данных:

Пример python
x = np.array([10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5])
y = np.array([8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68])

corr_two, p_two = stats.pearsonr(x, y, alternative='two-sided')
corr_greater, p_greater = stats.pearsonr(x, y, alternative='greater')
corr_less, p_less = stats.pearsonr(x, y, alternative='less')

print(f'Двусторонний тест: r={corr_two:.4f}, p={p_two:.4f}')
print(f'Тест на положительную корреляцию: r={corr_greater:.4f}, p={p_greater:.4f}')
print(f'Тест на отрицательную корреляцию: r={corr_less:.4f}, p={p_less:.4f}')
Двусторонний тест: r=0.8164, p=0.0022
Тест на положительную корреляцию: r=0.8164, p=0.0011
Тест на отрицательную корреляцию: r=0.8164, p=0.9989

Использование в пользовательской функции для пакетной обработки:

Пример python
def batch_pearsonr(data_pairs):
    results = []
    for x, y in data_pairs:
        try:
            corr, p_val = stats.pearsonr(x, y)
            results.append((corr, p_val))
        except Exception as e:
            results.append((None, None))
            print(f'Ошибка для пары: {e}')
    return results

pairs = [
    ([1,2,3], [4,5,6]),
    ([1,1,1], [2,3,4]),
    ([5,6,7], [8,9,10])
]
print(batch_pearsonr(pairs))
[(1.0, 0.0), (nan, nan), (1.0, 0.0)]

питон scipy.stats.pearsonr function comments

En
Scipy.stats.pearsonr Calculate Pearson correlation coefficient