Физтех.Статистика
Скачать ipynb
Phystech@DataScience¶
Домашнее задание 1¶
Правила, прочитайте внимательно:
- Выполненную работу нужно отправить телеграм-боту
@miptstats_pds_bot
. Для начала работы с ботом каждый раз отправляйте/start
. Работы, присланные иным способом, не принимаются. - Дедлайн см. в боте. После дедлайна работы не принимаются кроме случаев наличия уважительной причины.
- Прислать нужно ноутбук в формате
ipynb
. - Выполнять задание необходимо полностью самостоятельно. При обнаружении списывания все участники списывания будут сдавать устный зачет.
- Решения, размещенные на каких-либо интернет-ресурсах, не принимаются. Кроме того, публикация решения в открытом доступе может быть приравнена к предоставлении возможности списать.
- Для выполнения задания используйте этот ноутбук в качестве основы, ничего не удаляя из него. Можно добавлять необходимое количество ячеек.
- Комментарии к решению пишите в markdown-ячейках.
- Выполнение задания (ход решения, выводы и пр.) должно быть осуществлено на русском языке.
- Если код будет не понятен проверяющему, оценка может быть снижена.
- Никакой код из данного задания при проверке запускаться не будет. Если код студента не выполнен, недописан и т.д., то он не оценивается.
- Код из рассказанных на занятиях ноутбуков можно использовать без ограничений.
Правила оформления теоретических задач:
- Решения необходимо прислать одним из следующих способов:
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- отправив ее как файл боту вместе с ноутбуком или
- вставив ее в ноутбук посредством
Edit -> Insert Image
(фото, вставленные ссылкой, не принимаются);
- в виде $\LaTeX$ в markdown-ячейках.
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- Решения не проверяются, если какое-то требование не выполнено. Особенно внимательно все проверьте в случае выбора второго пункта (вставки фото в ноутбук). Неправильно вставленные фотографии могут не передаться при отправке. Для проверки попробуйте переместить
ipynb
в другую папку и открыть его там. - В решениях поясняйте, чем вы пользуетесь, хотя бы кратко. Например, если пользуетесь независимостью, то достаточно подписи вида "X и Y незав."
- Решение, в котором есть только ответ, и отсутствуют вычисления, оценивается в 0 баллов.
Баллы за задание:
Легкая часть:
- Задача 1 (20 баллов)
- Задача 2 (40 баллов)
- Задача 3 (40 баллов)
Сложная часть:
- Задача 4 (30 баллов)
- Задача 5 (40 баллов)
# Bot check
# HW_ID: phds_hw1
# Бот проверит этот ID и предупредит, если случайно сдать что-то не то.
# Status: not final
# Перед отправкой в финальном решении удали "not" в строчке выше.
# Так бот проверит, что ты отправляешь финальную версию, а не промежуточную.
# Никакие значения в этой ячейке не влияют на факт сдачи работы.
import pandas as pd
import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='white')
%matplotlib inline
Для выполнения задания вы можете установить свою палитру цветов при отрисовке графиков с помощью кода ниже. Если введете несуществующее имя, то вам напечатается список возможных палитр. Также вы можете устанавливать свои цвета конкретным объектам на графиках, обычно это делается с помощью аргумента color
.
sns.set_palette('Set2')
Легкая часть
Задача 1¶
Изобразите график параметрически заданной функции. Переменные необходимо задавать с помощью Numpy.
$$ x=\alpha\times\left(\cos t+\frac{cos(\beta t)}{\beta}\right)$$
$$y=\alpha\times\left(\sin t−\frac{sin(\beta t)}{\beta}\right)$$
$$t∈[0;20π]$$
- Реализуйте функции $x(t, \alpha, \beta)$ и $y(t, \alpha, \beta)$
# Ваш код здесь
- Постройте график в осях $x$ и $y$ при $\alpha=4$ и $\beta=1.1$. Подпишите оси.
# Ваш код здесь
- Постройте графики для различных значений $\alpha$ и $\beta$.
- $\alpha$ : [2, 4, 6, 8, 10]
- $\beta$ : [1.2, 1.8, 2, 5, 10]
У вас должна получиться сетка 5х5 графиков. На каждом графике укажите параметры $\alpha$ и $\beta$.
# Ваш код здесь
Задача 2¶
Для выполнения задания выберите любой профиль, в течении 1-2 недель его можно поменять.
Профиль биология
Скачайте датасет с данными об экспрессии белков у белых мышей. Данный датасет состоит из таблицы значений уровней экспрессии 77 различных белков в мозге у мышей. Каждая строка соответствует одной особи, каждый столбец соответствует одному белку. На столбцы Genotype, Treatment и подобные пока не обращаем внимания.
Для исследования рекомендуется выбрать столбцы 'ITSN1_N', 'DYRK1A_N', 'pBRAF_N', 'pCREB_N', но можно взять и другие.
Профиль физика
Скачайте датасет с данными о столкновении электронов на Большом Адронном Коллайдере.
Данный датасет содержит информацию о событиях столкновения двух электронов. Он состоит из таблицы различных параметров столкновений. Каждая строка соответствует одному столкновению, каждый столбец соответствует одному параметру. Например, в столбцах E1, E2 записаны значения энергии сталкивающихся электронов, в столбцах px1, py1, pz1, px2, py2, pz2 — значения моментов импульса, в столбцах Q1, Q2 $-$ заряды электронов.
Для исследования рекомендуется выбрать столбцы 'E2', 'px2', 'eta2', 'phi2'. Все эти столбцы — некоторые параметры второго электрона. Можно взять и другие столбцы.
Чтобы скачать данные, зарегистрируйтесь на сайте, после нажмите download на странице датасета и распакуйте скачанный архив. Вы получите файл формата csv
.
Если вы работаете в Google Colab, можно загрузить полученный файл в разделе "Файлы" (значок папки) на левой панели.
# эта функция читает данные, в кавычках укажите путь к файлу на вашем компьютере или в Colab
#df = pd.read_csv("./Data_Cortex_Nuclear.csv")
#df = pd.read_csv("./dielectron.csv")
Посмотрим на первые строки этой таблицы.
df.head()
Выберите несколько (3-6) столбцов для анализа значений в них.
# укажите столбцы данных
# Пример: columns = ['ITSN1_N', ...]
columns = [...]
df_chosen_columns = df[columns]
#Одномерный массив значений одного признака (например, 'math score') можно получить так:
#df_chosen_columns['math score']
Гистограммы¶
Для каждого из выбранных признаков нарисуйте гистограмму распределения. Для этого воспользуйтесь функцией matplotlib.pyplot.hist
.
Примечание. В анализе данных обычно используется слово "признак" для обозначения исследуемого свойства объекта. Например, для биологического датасета признаком является белок.
for i, column in enumerate(columns):
plt.figure(figsize=(15, 6))
plt.hist(<...>, bins=20)
plt.title(column + ' distribution');
Выбросы — значения, которые сильно отличаются от большинства значений выборки. Они могут возникать из-за ошибки измерения, из-за необычной природы входных данных, но также могут быть и частью распределения.
По гистограммам предположите, в каких из исследуемых признаков могут быть выбросы?
Ответ:
Выбросы могут сильно портить внешний вид графика.
Продемонстрируем это на примере. Сгенерируем выборку размера 1000 из стандартного нормального распределения и построим по ней гистограмму. В библиотеке scipy
это можно сделать с помощью метода rvs
sample = sps.norm.rvs(size=1000)
plt.figure(figsize=(15, 6))
plt.hist(sample, bins=20, range=(-3, 4));
Как видим, большая часть значений находятся в промежутке от -3 до 3.
Теперь добавим выброс — очень большое значение, которое могло появиться, например, в результате ошибок измерения. Допустим, что выброс — первое измерение.
outlier = 50
sample[0] = outlier
plt.figure(figsize=(15, 6))
plt.hist(sample, bins=20);
По такому графику уже нельзя сделать предположение о распределении выборки. Также обратите внимание, что большая часть графика пустая, что говорит о неинформативности данного графика.
Эту проблему с графиками можно решить с помощью параметра range
, который определяет, в каких границах строится гистограмма.
plt.figure(figsize=(15, 6))
plt.hist(sample, bins=20, range=(-3, 4));
Проделайте то же самое с теми столбцам, в которых, как вы считаете, есть выбросы.
В словаре ranges_without_outliers
укажите, в каких пределах, по вашему мнению, стоит нарисовать гистограмму распределения для каждого признака.
Пример заполнения словаря на ячейке ниже.
Здесь мы считаем, что для признака column1
большая часть значений находится в промежутке от -1 до 5, а все значения за пределами этого промежутка — выбросы.
Мы хотим нарисовать информативный график для гистограммы значений признака column1
, поэтому гистограмму будем строить только на основе значений из промежутка (-1, 5)
Аналогично для признака column2
ranges_without_outliers_example = {
'column1' : (-1, 5),
'column2' : (0, 3)
}
Аналогично определите интервалы для исследуемых признаков
ranges_without_outliers = {
'column1' : (-1, 5),
'column2' : (0, 3)
}
for column, column_range in ranges_without_outliers.items():
plt.figure(figsize=(15, 6))
plt.hist(<...>, range=column_range, bins=20)
plt.title(column + ' distribution')
Сделайте выводы
Изменилась ли форма распределений, стали ли графики информативнее?
Ответ:
Ядерные оценки плотности¶
Иногда гистограммы недостаточно, чтобы понять, какое у распределение у элементов выборки. В таких случаях можно использовать ядерные оценки плотности.
В библиотеке seaborn
они представлены функциями distplot
(в версиях до 0.11.1
), kdeplot
(начиная с версии 0.11.1
)
sns.__version__
Пример для нормального распределения с выбросом.
plt.figure(figsize=(15, 6))
sns.distplot(sample, bins=20);
Видно, что, даже несмотря на "хвост", плотность основной части данных довольно похожа на плотность нормального распределения. Теперь нарисуем этот же график для выборки без выброса.
Для наглядности на этом же графике нарисуем плотность стандартного нормального распределения. В библиотеке scipy
плотность распределения называется pdf
.
# уберем выброс
sample_wo_ourliers = sample[1:]
# сетка от -4 до 4 из 1000 значений
grid = np.linspace(-4, 4, 1000)
# считаем значения функции в выборке
norm_pdf_values = sps.norm.pdf(grid)
# отрисовка графика
plt.figure(figsize=(15, 6))
sns.distplot(sample_wo_ourliers, bins=20, kde_kws={"label": "KDE", "linewidth": 2})
plt.plot(grid, norm_pdf_values, label='Плотность $\\mathcal{N}(0,1)$', lw=2)
plt.title('Сравнение оценки плотности с истинной')
plt.legend();
Однако ядерные оценки плотности тоже не универсальны. Рассмотрим пример экспоненциального распределения.
Сгенерируйте выборку размера 100 из экспоненциального распределения $\textit{Exp(1)}$. Для этого воспользуйтесь функцией sps.expon.rvs
.
Посчитайте значения плотности этого распределения на промежутке от 0 до 6.
Нарисуйте гистограмму и ядерную оценку плотности для выборки из сгененированного экспоненциального распределения.
Как вы думаете, почему ядерная оценка плотности так плохо приближает реальную плотность распределения?
Ответ:
Нарисуйте гистограммы и ядерные оценки плотности для исследуемых признаков
for column, column_range in ranges_without_outliers.items():
plt.figure(figsize=(15, 6))
# для каждого признака оставьте значения внутри ранее заданного промежутка column_range
<...>
sns.distplot(<...>, bins=20);
plt.title('Оценка распределения ' + column)
Сделайте выводы. Какой из двух видов графиков более нагляден для данных выборки? Какими свойствами должно обладать распределение признака, чтобы ядерная оценка плотности, полученная по выборке, была похожа на настоящую плотность?
Вывод:
Здесь мы "избавились" от выбросов для того, чтобы понять, как распределена бОльшая часть выборки.
Но нужно понимать, что избавляться от выбросов при анализе данных стоит не всегда. Прежде, чем удалять выбросы из выборки, хорошо бы понимать:
- Какая цель исследования. Например, если мы хотим узнать, как хорошо "средний" студент МФТИ решает задачи по теории вероятностей, результаты лучших студентов на потоке не сильно проясняют ситуацию и затрудняют анализ. Такие результаты нужно выкинуть. Если же надо отобрать студентов на стажировку для аналитиков данных, хорошие результаты не только не нужно отсеивать, но и нужно анализировать дополнительно.
- Почему отличающееся значение могло появиться в выборке. Это случайность / ошибка в измерениях / следствие какого-то еще фактора? Возможно, удаление отличающегося элемента лишит нас важных знаний о природе исследуемых данных.
Приведите примеры исследований, в которых нужно/не нужно удалять выбросы в данных:
...
Сделайте выводы по всей задаче:
...
Задача 3¶
В этой задаче нужно визуализировать центральную предельную теорему.
a). Пусть $\xi_1, ..., \xi_n$ — независимые случайные величины из распределения $Exp(\lambda)$. Согласно центральной предельной теореме выполнена сходимость $Z_n = \frac{X_n - \mathsf{E}X_n}{\sqrt{\mathsf{D}X_n}} \stackrel{d}{\to} \mathcal{N}(0, 1)$, где $X_n = \sum\limits_{i=1}^n \xi_i$. Вам нужно убедиться в этом, сгенерировав множество наборов случайных величин и посчитав по каждому из наборов величину $Z_n$ в зависимости от размера набора.
Сгенерируйте 500 наборов случайных величин $\xi_1^j, ..., \xi_{300}^j$ из распределения $Exp(1)$.
size = <...> # размер выборки
samples_count = <...> # количество выборок
sample = <...>
По каждому из них посчитайте сумму $X_{jn} = \sum\limits_{i=1}^n \xi_i^j$ для $1 \leqslant n \leqslant 300$, то есть сумма первых $n$ величин $j$-го набора.
sums = <...>
Для этого среднего посчитайте величину $Z_{jn} = \frac{X_{jn} - \mathsf{E}X_{jn}}{\sqrt{\mathsf{D}X_{jn}}}$.
Подсказка: можно воспользоваться возможностями библиотеки numpy
.
<...>
Для каждого $j$ нанесите на один график зависимость $Z_{jn}$ от $n$ с помощью plt.plot
. Каждая кривая должна быть нарисована одним цветом с прозрачностью alpha=0.05
. Сходятся ли значения $Z_{jn}$ к какой-либо константе?
<...>
Для $n=300$ по набору случайных величин $Z_{1,300}, ..., Z_{500,300}$ постройте гистограмму. Похожа ли она на плотность распределения $\mathcal{N}(0, 1)$, которую тоже постройте на том же графике? Не забудьте сделать легенду (подписи на графиках, см. семинар и туториалы).
<...>
b). Выполните те же действия для распределения $Pois(1)$.
Сделайте вывод о смысле центральной предельной теоремы. Подтверждают ли сделанные эксперименты теоретические свойства?
Задача 5:¶
Ссылка на контест в боте.