Давно известно, что солнечная активность и, как ее следствие, геомагнитные бури на Земле, оказывают влияние на здоровье и самочувствие людей. И раз так, то возникает закономерный вопрос: может быть солнечная активность как-то влияет и на количество совершаемых преступлений? Типа взяла геомагнитная буря повоздействовала на человека и сподвигла/не сподвигла его совершить противоправные действия.

По ходу повествования поищем связь между двумя количественными переменными (солнечная активность и количество преступлений), определим, какие статистические методы (параметрические или непараметрические) нужно использовать, применим коэффициент корреляции и интерпретируем результаты.

Для начала немного теории по предмету исследования. Геомагнитная буря - это сильные и быстрые изменения в магнитном поле Земли, возникающие в периоды повышенной солнечной активности. Солнечная активность – это процессы в солнечной атмосфере, связанные с образованием и распадом сильных магнитных полей. Для оценки солнечной активности принято использовать два индикатора - число и параметры солнечных пятен и уровень радиоизлучения на длине волны 10.7 см. При этом мощность потока радиоизлучения Солнца на длине волны 10.7 см хорошо коррелирует с суммарной площадью солнечных пятен и уровнем ультрафиолетового излучения. Поэтому для анализа влияния солнечной активности на уровень криминала для целей данной статьи используется этот второй параметр – мощность потока радиоизлучения.

Данные измерений потока радиоизлучения публикуются на сервере сервиса космической погоды Канады , где и был взят набор данных для текущего анализа. Загруженные данные о среднемесячных по годам значениях солнечного потока на длине волны 10,7 см содержат значения наблюдаемого (observed) потока, скорректированного (adjusted) к расстоянию от Земли до Солнца в 1 А.Е. потока, абсолютного (приведенного к абсолютной радиоастрономической шкале URSI, равное 0.9xF10.7) потока.

Набор данных о количестве преступлений за 2003-2020 гг. в России взят на Kaggle здесь.

Анализ проводится на Python в Jupyter Notebook.

1. Загрузка и предобработка данных

Импортируем необходимые библиотеки:

import pandas as pd
from datetime import date
import numpy as np
from scipy import stats
import scipy
import seaborn as sns
import matplotlib.pyplot as plt   
%matplotlib inline
import statsmodels.api as sm
from scipy.stats import norm
import pylab

Считываем набор данных о солнечной активности, который был предварительно сохранен в xls-файл и немного приведен в порядок (запятые в числах заменены на точки, поправлены названия колонок):

sun_ac = pd.read_excel('Sun.xlsx')
sun_ac.head()

Год и месяц в датафрейме (далее df) имеют целочисленный тип данных, но нам нужен формат даты, чтобы потом объединить по этому столбцу со вторым df. Создаем новую колонку с датой из двух имеющихся:

sun_ac['full_date'] = pd.to_datetime(sun_ac.Год.astype(str) + '/' + sun_ac.Месяц.astype(str) + '/01')
sun_ac.head(10)

Считываем набор данных о криминале, указывая в параметрах, что столбец «month» нужно считывать, как дату:

crime_df = pd.read_csv('crime.csv', parse_dates=['month'],  dayfirst=True)
crime_df.tail()

Поскольку оба набора содержат неодинаковый интервал дат, отбираем только тот, который содержится и в том и в другом df. Заодно, проверяем df.shape-ом, что не ошиблись и количество строк одинаковое:

sun_1 = sun_ac.query('full_date >= "2005-01-01" & full_date <= "2019-12-01"')
sun_1.shape
crime_1 = crime_df.query('month >= "2005-01-01" & month <= "2019-12-01"')\
        .rename(columns={'month' : 'full_date'})
crime_1.shape

Объединяем два df, заодно переименовывая колонки на всем понятный язык:

full_df = pd.merge( crime_1, sun_1, on = 'full_date')\
    .rename(columns={'Total_crimes': 'Всего_преступлений',
                     'Serious': 'Тяжкие',
                     'Huge_damage': 'Причинение_ущерба',
                     'Ecological': 'Экологические',
                     'Terrorism': 'Терроризм',
                     'Extremism' : 'Экстремизм',
                     'Murder': 'Убийство',
                     'Harm_to_health': 'Вред_здоровью',
                     'Rape': 'Насилие',
                     'Theft': 'Кражи',
                     'Vehicle_theft': 'Угон_авто',
                     'Fraud_scam': 'Мошенничество',
                     'Hooligan': 'Хулиганство',
                     'Drugs': 'Наркотики',
                     'Weapons': 'Оружие'})
full_df.head()

2. Анализ данных

Собственно, в ходе анализа нам нужно выяснить, имеют ли какую-либо взаимосвязь переменные «Всего_преступлений» и «Абсолютный_поток», и, если имеют, то насколько она сильная. При этом «Всего_преступлений» является зависимой переменной, а «Абсолютный поток» - независимой.

Построим пару графиков, чтобы присмотреться к данным. Это будет лайнплот для переменных «Всего_преступлений» и «Абсолютный_поток» и скаттерплот:

sns.lineplot(data=full_df, x="full_date", y='Всего_преступлений')
sns.lineplot(data=full_df, x="full_date", y='Абсолютный_поток')
plt.scatter(x =full_df.Всего_преступлений, y=full_df.Абсолютный_поток)
plt.show()

Также сгруппируем средние значения этих двух переменных по годам для сопоставления этих средних:

full_df.groupby('Год')\
	.agg({'Всего_преступлений': 'mean', 'Абсолютный_поток': 'mean'})\
	.sort_values('Всего_преступлений', ascending=False)

В принципе, глядя на полученные результаты, на этом можно было бы и завершить анализ, сделав вывод, что количество преступлений не зависит от солнечной активности, но не для того это всё затевалось, поэтому продолжим и исследуем взаимосвязь между двумя переменными, используя статистические методы.

Обе наши переменные – количественные, значит можно задействовать метод корреляции - метод измерения взаимосвязи между двумя количественными переменными, и нахождение коэффициента корреляции. Но для начала следует выяснить, какими данными мы оперируем, потому что   важным моментом принятия решения при работе с выборкой данных является использование параметрических или непараметрических статистических методов. Параметрические статистические методы предполагают, что данные имеют известное и специфическое распределение, часто распределение Гаусса. Если выборка данных не является гауссовой, то предположения о параметрических статистических тестах нарушаются, и должны использоваться непараметрические статистические методы.

Существует несколько методов проверки того, соответствует ли переменная нормальному распределению. Мы задействуем построение гистограмм, график QQ Plot и тест Шапиро-Уилка.

Гистограммы:

plt.hist(full_df.Всего_преступлений)
plt.show()

plt.hist(full_df.Абсолютный_поток)
plt.show()
/
/

Распределение на гистограммах как-то совсем не походит на нормальное.

График QQ Plot:

sm.qqplot(full_df.Всего_преступлений)
pylab.show()

sm.qqplot(full_df.Абсолютный_поток)
pylab.show()

Имеем равномерное распределение, так как в отличие от нормального, точки не следуют по одной прямой. Равномерное распределение имеет много наблюдений в обоих концах. По результатам на графике распределение можно «подтянуть» к нормальному.

Ну и сам тест Шапиро-Уилка. В основе проверки на «нормальность» также лежит
проверка гипотез. Нулевая гипотеза – данные распределены нормально,
альтернативная гипотеза – данные не имеют нормального распределения. Результат
теста Шапиро-Уилка возвращает значение вычисленной статистики и p-значение. В
качестве критического значения в большинстве случаев берется 0.05. При
p-значении меньше 0.05 мы вынуждены отклонить нулевую гипотезу.

w, pvalue = stats.shapiro(full_df.Всего_преступлений)
w, pvalue

w, pvalue = stats.shapiro(full_df.Абсолютный_поток)
w, pvalue

Полученные р-значения для обеих переменных получились больше 0,05, следовательно, мы не можем отклонить нулевую гипотезу и принимаем предположение о нормальном распределении данных.

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

Сформулируем нулевую и альтернативную гипотезы:

- Н0 – две переменные независимы (нет никакой связи между переменными);

- Н1 – существует зависимость между переменными (существует связь).

Вычисляем:

from scipy.stats import pearsonr
corr, p = pearsonr(full_df.Всего_преступлений, full_df.Абсолютный_поток)
corr, p

Полученное р-значение больше 0,05, следовательно, мы не можем отклонить нулевую гипотезу и делаем вывод, что корреляция статистически незначима и связи между переменными нет. Или другими словами: уровень солнечной активности никак не влияет на уровень преступности.

Однако, это еще не всё. Выше было исследовано влияние солнечной активности на общее количество преступлений, но исследуемые данные также содержат сведения по видам преступлений. «За кадром», дабы не делать статью излишне длинной, был проведен анализ влияния солнечной активности на каждый вид криминала. Так вот, статистически значимый результат показали: «Угон_автомобилей» (corr = 0,2 , р = 0,006), «Наркотики»  (corr = 0,246 , р = 0,0008), «Оружие» (corr = -0,22 , р = 0,002). Что тут можно сказать? Периоды повышенной солнечной активности своеобразным образом сказываются на некоторых людях, которым в такие моменты хочется «закинуться» и свалить в закат на автомобиле, за неимением своего – на угнанном )) Причем без оружия.

Комментарии (2)


  1. Frenology
    05.04.2022 14:59

    Немного напоминает анализ влияния количества пиратов на среднюю температуру по планете. Не очень понятно применение коэффициента корреляции Пирсона на усреднённых данных по годам. Вся полезная информация уже потеряна при усреднении. Солнечные бури имеют период появления около 2 недель. Длительность - часы. Максимум - дни. Если и есть влияние на поведение человека, то и заметить его можно на выборках с дискретизацией по дням и окном анализа в пару недель .


  1. adeshere
    05.04.2022 15:18

    Поставил статье минус за низкий технический уровень. Дело в том, что для корректного применения статистических методов, кроме умения написать программный код, очень важно еще и иметь понимание этих методов. Какие идеи туда заложены, какие есть требования к данным, какие ограничения имеет метод. И это гораздо важнее, чем технология вычислений. Вот только несколько, хм, спорных утверждений и интерпретаций, которые вызывают вопросы:

    Имеем равномерное распределение, так как в отличие от нормального, точки не следуют по одной прямой.

    Если Вы доказали, что распределение не нормальное, то отсюда совершенно не следует, что оно равномерное. По секрету, есть еще очень много других возможностей...

    Равномерное распределение имеет много наблюдений в обоих концах. 

    Я не совсем понял цель этой фразы - что она должна доказать? Из того, что у распределения "тяжелые" хвосты", совершенно не следует, что оно равномерное. И наоборот, равномерное распределение потому так и называется, что его плотность вероятности везде одинаковая. Есть куча случаев, когда "хвосты" намного тяжелее. Например, посмотрите функцию распределения для переменной, которая меняется по синусу или косинусу.

    удивительно, но факт

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

    Далее пройдусь по видам преступлений. Дело в том, что статистическая значимость - это вовсе не доказательство причинной связи, а всего лишь вероятность, что две переменные не являются независимыми. Если переменные действительно независимы, то при уровне значимости 96% мы в 4% случаев получим, что связь статистически значима. Поэтому очень упорный исследователь, который не поленится взять ваш код и подставить туда много разных комбинаций переменных, обязательно найдет "статистически значимую" связь между какими-то из них. К примеру, если мы возьмем 13 совершенно случайных и никак не связанных переменных, то из них можно построить 13*12=156 пар (на самом деле 78 из-за симметрии). Даже если эти переменные идеально случайны (распределение - нормальное и т.д.), то в среднем примерно в 3 случаях (для 3 пар) пороговый уровень значимости будет превышен. Всего-то надо взять 13 случайных и независимых переменных, и можно написать три статьи! Я, конечно, немного утрирую, но если действительно заниматься анализом корреляций, то очень важно понимать, что такое уровень значимости и как его надо интерпретировать, если рассматривается несколько переменных и их комбинаций друг с другом.

    А наиболее существенное замечание по методике состоит в том, что корреляционный критерий наличия связи между переменными требует, чтобы это были именно случайные величины. То есть, чтобы все пары значений выбирались из одной и той же генеральной совокупности (Извините, страница по ссылке содержит рекламу, но вопрос там уж очень понятно изложен). А в случае использованных в статье переменных это совершенно точно не так, потому что все эти переменные существенно зависят от времени. То есть, это не случайные величины, а случайные процессы. Для которых оценивать значимость связи описанным способом нельзя. Вот тут есть очень подробный разбор. А кому лень лазить по ссылке,

    поясню в двух словах

    Логика очень простая: если среднее значение некоторого процесса закономерно меняется во времени, то это значит, что мы имеем дело с разными случайными величинами в разное время. Матожидание солнечной активности на пике цикла и на его минимуме совершенно разное. Но это значит, что в двух этих случаях мы извлекаем наше выборочное значение из разных генеральных совокупностей. И их категорически нельзя считать реализациями одной и той же случайной величины. И это вовсе не мелочь. Практически вся статистика на этом построена (что мы имеем генеральную совокупность и извлекаем из нее выборочные значения). Поэтому при практическом анализе данных проверка этого требования (что у нас не случайный процесс!) - это обязательное условие аккуратного применения большинства статистических методов. А не только корреляционного.