Занятие 6

Лабораторная работа 6

1. Seaborn

Seaborn - это библиотека, в основном используемая для построения графиков в Python. Он построен на основе Matplotlib и предоставляет красивые стили и цветовые палитры по умолчанию, чтобы сделать графики более "наглядными".

In [133]:
import seaborn as sns # импортируем библиотеку

Рассмотрим датасет Ирисы Фишера - это многомерный набор данных, используемый британским статистиком и биологом Рональдом Фишером в его статье 1936 года «Использование множественных измерений в таксономических задачах как пример линейного дискриминантного анализа».

In [134]:
data = sns.load_dataset("iris") # скачаем данный датасет
In [135]:
data.head(5)
Out[135]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

Рассмотрим данный датасет внимательнее. Он содержит 5 столбцов:

  • Sepal - наружный лепесток околоцветника
  • Petal - внутренний лепесток околоцветника
  • Length - длина
  • Width - ширина
  • Species - вид цветка(всего три вида)

Датасет небольшой содержит 150 цветков.

1.1 Использование Seaborn с Matplotlib

In [136]:
import matplotlib.pyplot as plt # импортируем библиотеку
  
sns.lineplot(x="petal_length", y="petal_width", data=data) # построим график с помощью seaborn  
plt.title('Seaborn with matplotlib') # установим заголовок с помощью matplotlib
plt.show()

1.2 сюжеты в Seaborn

В seaborn есть несколько сюжетов, которые позволяют сделать графики более "привлекательными". Метод set_style() задаёт один из пяти тем(сюжетов) графика:

  • darkgrid
  • whitegrid
  • dark
  • white
  • ticks
In [137]:
plt.figure(figsize=(18, 16))
for i, style in enumerate(['darkgrid', 'whitegrid', 
                           'dark', 'white', 'ticks']):
    sns.set_style(style)  # Устанавливаем стиль
    plt.subplot(3, 2, i+1)
    sns.lineplot(x="petal_length", y="petal_width", data=data)
    plt.title(style)

1.3 set_context

set_context(context=None, font_scale=1, rc=None) управляет масштабированием элементов графика.

  • context — параметры контекста, влияющие на размер меток, линий и других элементов, но не на общий стиль(notebook, paper, talk, poster)

  • font_scale - коэффициент масштабирования

In [138]:
import matplotlib.pyplot as plt # импортируем библиотеку
plt.figure(figsize = (4, 2)) # размер картинки
sns.set_context("notebook", font_scale=1.25) # увеличим шрифт элементов графика
sns.lineplot(x="petal_length", y="petal_width", data=data) # построим график с помощью seaborn  
sns.set_style("whitegrid") # установим тему "whitegrid"
plt.title('ticks') # установим заголовок с помощью matplotlib
plt.show()
In [139]:
plt.figure(figsize=(18, 15))
for i, context in enumerate(['notebook', 'paper', 
                             'talk', 'poster']):
    sns.set_context(context=context)  # Устанавливаем стиль
    plt.subplot(2, 2, i+1)
    sns.lineplot(x="petal_length", y="petal_width", data=data)
    plt.title(context)

1.4 Цветовая палитра

Здесь нам могут быть полезны два метода:

  • color_palette() задаёт цвет графику
  • palplot() создаёт цветовую палитру в виде горизонтального массива
In [140]:
import seaborn as sns  
import matplotlib.pyplot as plt 
palette = sns.color_palette('Spectral', 15) 
sns.palplot(palette) 
plt.show()
In [141]:
import seaborn as sns  
import matplotlib.pyplot as plt 

plt.figure(figsize=(7, 6))

sns.set_palette('vlag') 
sns.set_context("notebook", font_scale=0.75)
plt.subplot(211) 
sns.lineplot(x="petal_length", y="petal_width", data=data)
  
sns.set_palette('Accent') 
sns.set_context("notebook", font_scale=0.75)
plt.subplot(212) 
sns.lineplot(x="petal_length", y="petal_width", data=data)
  
plt.show()

1.5 Создание различных типов графиков

Точечная диаграмма

In [142]:
plt.figure(figsize=(6, 3))
sns.scatterplot(x="petal_length", y="petal_width", data=data) 
plt.title("Точечная диаграмма")
plt.show()

Линейный график

In [143]:
plt.figure(figsize=(6, 3))
sns.lineplot(x="petal_length", y="petal_width", data=data) 
plt.title("Линейный график")
plt.show()

Столбчатая диаграмма

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

In [144]:
plt.figure(figsize=(6, 3))
sns.barplot(x="species", y="petal_width", data=data) 
plt.title("Столбчатая диаграмма")
plt.show()

Ящичковая диаграмма

Показывает диапазон значений определённой категории.

In [145]:
# Ящичковая диаграмма
plt.figure(figsize=(6, 3))
sns.boxplot(x="species", y="petal_width", data=data) 
plt.title("Ящичковая диаграмма")
plt.show()

Полосовой график

По сути это точечная диаграмма по категориям.

In [146]:
plt.figure(figsize=(6, 3))
sns.stripplot(x="species", y="petal_width", data=data) 
plt.title("Полосовой график")
plt.show()

1.6 Distplot

Distplot позволяет отображать гистограмму.

In [147]:
plt.figure(figsize=(6, 3))
sns.distplot(data['sepal_width']) 
plt.title("Распределение ширины наружного лепестка околоцветника")
plt.show()
C:\Users\79826\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).
  warnings.warn(msg, FutureWarning)

Мы видим, что распределение ширины наружного лепестка околоцветника близко к нормальному распределению.

1.7 Парный график

С помощью sns.pairplot мы можем создать точечные графики, между различными значениями признаков.

Здесь в целом лучше один раз увидеть, чем читать какие-то объяснения.

In [148]:
sns.pairplot(data=data, hue='species') 
sns.set_context("notebook", font_scale=1)
plt.show()

1.8 Тепловая карта

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

In [149]:
tc = data.corr() 
sns.heatmap(tc) 
plt.show()

Сравните с обычной матрицей корелляции.

In [150]:
data.corr()
Out[150]:
sepal_length sepal_width petal_length petal_width
sepal_length 1.000000 -0.117570 0.871754 0.817941
sepal_width -0.117570 1.000000 -0.428440 -0.366126
petal_length 0.871754 -0.428440 1.000000 0.962865
petal_width 0.817941 -0.366126 0.962865 1.000000

Задача 1 (2 балла)

In [151]:
tit = sns.load_dataset('titanic') # загрузим датасет 
tit
Out[151]:
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
886 0 2 male 27.0 0 0 13.0000 S Second man True NaN Southampton no True
887 1 1 female 19.0 0 0 30.0000 S First woman False B Southampton yes True
888 0 3 female NaN 1 2 23.4500 S Third woman False NaN Southampton no False
889 1 1 male 26.0 0 0 30.0000 C First man True C Cherbourg yes True
890 0 3 male 32.0 0 0 7.7500 Q Third man True NaN Queenstown no True

891 rows × 15 columns

Рассмотрим популярный датасет, связанный с пассажирами Титаника.

  • Survived: Признак, показывающий был ли спасен данный пассажир или нет. 1 означает, что удалось выжить, и 0 - не удалось спастись.
  • Pclass: Класс билета. 1 - означает Первый класс билета. 2 - означает Второй класс билета. 3 - означает Третий класс билета.
  • Name: Имя пассажира. Имя также может содержать титулы и обращения. "Mr" для мужчин. "Mrs" для женщин. "Miss" для девушек (тут имеется в виду что для тех, кто не замужем, так было принято, да и сейчас тоже, говорить в западном обществе). "Master" для юношей.
  • Sex: Пол пассажира. Либо мужчины (=Male) оибо женщины (=Female).
  • Age: Возраст пассажира. "NaN" значения в этой колонке означают, что возраст данного пассажира отсутствует/неизвестен/или не был записанv в датасет.
  • SibSp: Количество братьев/сестер или супругов, путешествующих с каждым пассажиром.
  • Parch: Количество родителей детей (Number of parents of children travelling with each passenger).
  • Embark_town Город отправления
  • Fare: Сумма, которую заплатил пассажир за путешествие.

Постройте:

  1. Точечную диаграмму
  2. Линейный график
  3. Столбчатую диаграмму
  4. Ящичковую диаграмму
  5. Полосовой график
  6. Парный график
  7. Тепловую карту

В качестве признаков можете выбрать те признаки, которые вам понравятся.

Pandas(часть 2)

2.1 Работа с пропусками

Так как данные бывают разных форм и видов и даже с пропусками, то необходимо уметь обрабатывать их.

In [152]:
import pandas as pd
import numpy as np

Создадим тренировочную таблицу с пропусками.

In [153]:
df = pd.DataFrame({
'ord_no':[70001,np.nan,70002,70004,np.nan,70005,np.nan,70010,70003,70012,np.nan,70013],
'purch_amt':[150.5,np.nan,65.26,110.5,948.5,np.nan,5760,1983.43,np.nan,250.45, 75.29,3045.6],
'sale_amt':[10.5,20.65,np.nan,11.5,98.5,np.nan,57,19.43,np.nan,25.45, 75.29,35.6],
'customer_id':[3002,3001,3001,3003,3002,3001,3001,3004,3003,3002,3001,3001],
'salesman_id':[5002,5003,5001,np.nan,5002,5001,5001,np.nan,5003,5002,5003,np.nan]})
In [154]:
df
Out[154]:
ord_no purch_amt sale_amt customer_id salesman_id
0 70001.0 150.50 10.50 3002 5002.0
1 NaN NaN 20.65 3001 5003.0
2 70002.0 65.26 NaN 3001 5001.0
3 70004.0 110.50 11.50 3003 NaN
4 NaN 948.50 98.50 3002 5002.0
5 70005.0 NaN NaN 3001 5001.0
6 NaN 5760.00 57.00 3001 5001.0
7 70010.0 1983.43 19.43 3004 NaN
8 70003.0 NaN NaN 3003 5003.0
9 70012.0 250.45 25.45 3002 5002.0
10 NaN 75.29 75.29 3001 5003.0
11 70013.0 3045.60 35.60 3001 NaN

Отсутствующие данные объектов можно заменить на конкретные числовые значения, для этого можно использовать метод fillna(). Для экспериментов будем использовать структуру df, созданную в предыдущем разделе.

Этот метод не изменяет текущую структуру, он возвращает структуру DataFrame, созданную на базе существующей, с заменой NaN значений на те, что переданы в метод в качестве аргумента.

К примеру, данные можно заполнить средним значением по столбцу.

In [155]:
df.fillna(df.mean())
Out[155]:
ord_no purch_amt sale_amt customer_id salesman_id
0 70001.00 150.500000 10.500000 3002 5002.0
1 70006.25 1376.614444 20.650000 3001 5003.0
2 70002.00 65.260000 39.324444 3001 5001.0
3 70004.00 110.500000 11.500000 3003 5002.0
4 70006.25 948.500000 98.500000 3002 5002.0
5 70005.00 1376.614444 39.324444 3001 5001.0
6 70006.25 5760.000000 57.000000 3001 5001.0
7 70010.00 1983.430000 19.430000 3004 5002.0
8 70003.00 1376.614444 39.324444 3003 5003.0
9 70012.00 250.450000 25.450000 3002 5002.0
10 70006.25 75.290000 75.290000 3001 5003.0
11 70013.00 3045.600000 35.600000 3001 5002.0

Задача 2(3 балла)

Заполните пропущеные значения таблицы следующими способами:

  • Медианными значениями
  • Нулями
  • Наиболее часто встречающимися
  • Линейной интерполяцией

Читайте документацию: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html

In [ ]:

2.2 Удаление столбцов и строк с пропусками

Довольно часто используемый подход при работе с отсутствующими данными – это удаление записей (строк) или полей (столбцов), в которых встречаются пропуски. Для того, чтобы удалить все объекты, которые содержат значения NaN используется метод dropna() без аргументов.

In [156]:
df = pd.DataFrame({
'ord_no':[70001,np.nan,70002,70004,np.nan,70005,np.nan,70010,70003,70012,np.nan,70013],
'purch_amt':[150.5,np.nan,65.26,110.5,948.5,np.nan,5760,1983.43,np.nan,250.45, 75.29,3045.6],
'sale_amt':[10.5,20.65,np.nan,11.5,98.5,np.nan,57,19.43,np.nan,25.45, 75.29,35.6],
'customer_id':[3002,3001,3001,3003,3002,3001,3001,3004,3003,3002,3001,3001],
'salesman_id':[5002,5003,5001,np.nan,5002,5001,5001,np.nan,5003,5002,5003,np.nan]})
In [157]:
df.dropna()
Out[157]:
ord_no purch_amt sale_amt customer_id salesman_id
0 70001.0 150.50 10.50 3002 5002.0
9 70012.0 250.45 25.45 3002 5002.0

Однако, как кажется, мы потеряли с вами слишком много данных. Метод dropna() имеет множество аргументов о которых можно подробно почитать в документации: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html

Задача 3(2 балла)

In [158]:
df = pd.DataFrame({
'ord_no':[70001,np.nan,70002,70004,np.nan,70005,np.nan,70010,70003,70012,np.nan,70013],
'purch_amt':[150.5,np.nan,65.26,110.5,948.5,np.nan,5760,1983.43,np.nan,250.45, 75.29,3045.6],
'sale_amt':[10.5,20.65,np.nan,11.5,98.5,np.nan,57,19.43,np.nan,25.45, 75.29,35.6],
'customer_id':[3002,3001,3001,3003,3002,3001,3001,3004,3003,3002,3001,3001],
'salesman_id':[5002,5003,5001,np.nan,5002,5001,5001,np.nan,5003,5002,5003,np.nan]})

Удалите все столбцы, в которых:

  • количество не-NaN элементов меньше трех.
  • в которых все элементы NaN.
  • в которых хотя бы один элемент NaN.

Удалите все строки, в которых:

  • количество не-NaN элементов меньше трех.
  • в которых все элементы NaN.
  • в которых хотя бы один элемент NaN.
In [ ]:

Задача 4(5 баллов)

Рассмотрим популярный датасет, связанный с пассажирами Титаника.

In [159]:
tit = sns.load_dataset('titanic') # загрузим датасет 
tit
Out[159]:
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
886 0 2 male 27.0 0 0 13.0000 S Second man True NaN Southampton no True
887 1 1 female 19.0 0 0 30.0000 S First woman False B Southampton yes True
888 0 3 female NaN 1 2 23.4500 S Third woman False NaN Southampton no False
889 1 1 male 26.0 0 0 30.0000 C First man True C Cherbourg yes True
890 0 3 male 32.0 0 0 7.7500 Q Third man True NaN Queenstown no True

891 rows × 15 columns

  • Survived: Признак, показывающий был ли спасен данный пассажир или нет. 1 означает, что удалось выжить, и 0 - не удалось спастись.
  • Pclass: Класс билета. 1 - означает Первый класс билета. 2 - означает Второй класс билета. 3 - означает Третий класс билета.
  • Name: Имя пассажира. Имя также может содержать титулы и обращения. "Mr" для мужчин. "Mrs" для женщин. "Miss" для девушек (тут имеется в виду что для тех, кто не замужем, так было принято, да и сейчас тоже, говорить в западном обществе). "Master" для юношей.
  • Sex: Пол пассажира. Либо мужчины (=Male) оибо женщины (=Female).
  • Age: Возраст пассажира. "NaN" значения в этой колонке означают, что возраст данного пассажира отсутствует/неизвестен/или не был записанv в датасет.
  • SibSp: Количество братьев/сестер или супругов, путешествующих с каждым пассажиром.
  • Parch: Количество родителей детей (Number of parents of children travelling with each passenger).
  • Embark_town Город отправления
  • Fare: Сумма, которую заплатил пассажир за путешествие.
  1. Удалите все строки, содержащие строчки с пропусками.
  2. Постройте гистограммы количество выживших от возраста для женщин, мужчин и общую.
  3. Найдите средние цены для каждого из классов билета.
  4. Выясните, какие значения признаков pclass, sex, sibsp, parch соответствуют максимальной выживаемости.
  5. Заполните все пропуски, средними значениями в таблице и проделайте пункты 2-4 для данной таблице.
  6. Выясните, какой признак имеет максимальную линейную зависимость с выживаемостью(survived, alive)
  7. Выведите 25% пассажиров, потративших на билеты больше всех.
In [ ]:

Задача 5(немного творческая 2 балла)

Подумайте и напишите, какие признаки влияют на выживаемость сильно, а какие не очень. Обоснуйте свою точку зрения.

In [ ]:

Задача 6 (3 балла)

Рассмотрим датасет car_crashes

  • total – Количество водителей, участвующих в ДТП со смертельным исходом, на миллиард миль
  • speeding – количество водителей, участвовавших в столкновениях со смертельным исходом, которые превысили скорость.
  • alchol – количество водителей, участвовавших в авариях со смертельным исходом, которые находились в состоянии алкогольного опьянения
  • not_distracted – Количество водителей, попавших в ДТП со смертельным исходом, которые не были отвлечены
  • no_previous – Количество водителей, попавших в ДТП со смертельным исходом, которые ранее не попадали в аварии
  • ins_premium – Страховые взносы по автострахованию
  • ins_loses – Убытки, понесенные страховыми компаниями при ДТП на одного застрахованного водителя
  • abbrev – Штат
In [160]:
car = sns.load_dataset('car_crashes') # загрузим датасет
In [161]:
car
Out[161]:
total speeding alcohol not_distracted no_previous ins_premium ins_losses abbrev
0 18.8 7.332 5.640 18.048 15.040 784.55 145.08 AL
1 18.1 7.421 4.525 16.290 17.014 1053.48 133.93 AK
2 18.6 6.510 5.208 15.624 17.856 899.47 110.35 AZ
3 22.4 4.032 5.824 21.056 21.280 827.34 142.39 AR
4 12.0 4.200 3.360 10.920 10.680 878.41 165.63 CA
5 13.6 5.032 3.808 10.744 12.920 835.50 139.91 CO
6 10.8 4.968 3.888 9.396 8.856 1068.73 167.02 CT
7 16.2 6.156 4.860 14.094 16.038 1137.87 151.48 DE
8 5.9 2.006 1.593 5.900 5.900 1273.89 136.05 DC
9 17.9 3.759 5.191 16.468 16.826 1160.13 144.18 FL
10 15.6 2.964 3.900 14.820 14.508 913.15 142.80 GA
11 17.5 9.450 7.175 14.350 15.225 861.18 120.92 HI
12 15.3 5.508 4.437 13.005 14.994 641.96 82.75 ID
13 12.8 4.608 4.352 12.032 12.288 803.11 139.15 IL
14 14.5 3.625 4.205 13.775 13.775 710.46 108.92 IN
15 15.7 2.669 3.925 15.229 13.659 649.06 114.47 IA
16 17.8 4.806 4.272 13.706 15.130 780.45 133.80 KS
17 21.4 4.066 4.922 16.692 16.264 872.51 137.13 KY
18 20.5 7.175 6.765 14.965 20.090 1281.55 194.78 LA
19 15.1 5.738 4.530 13.137 12.684 661.88 96.57 ME
20 12.5 4.250 4.000 8.875 12.375 1048.78 192.70 MD
21 8.2 1.886 2.870 7.134 6.560 1011.14 135.63 MA
22 14.1 3.384 3.948 13.395 10.857 1110.61 152.26 MI
23 9.6 2.208 2.784 8.448 8.448 777.18 133.35 MN
24 17.6 2.640 5.456 1.760 17.600 896.07 155.77 MS
25 16.1 6.923 5.474 14.812 13.524 790.32 144.45 MO
26 21.4 8.346 9.416 17.976 18.190 816.21 85.15 MT
27 14.9 1.937 5.215 13.857 13.410 732.28 114.82 NE
28 14.7 5.439 4.704 13.965 14.553 1029.87 138.71 NV
29 11.6 4.060 3.480 10.092 9.628 746.54 120.21 NH
30 11.2 1.792 3.136 9.632 8.736 1301.52 159.85 NJ
31 18.4 3.496 4.968 12.328 18.032 869.85 120.75 NM
32 12.3 3.936 3.567 10.824 9.840 1234.31 150.01 NY
33 16.8 6.552 5.208 15.792 13.608 708.24 127.82 NC
34 23.9 5.497 10.038 23.661 20.554 688.75 109.72 ND
35 14.1 3.948 4.794 13.959 11.562 697.73 133.52 OH
36 19.9 6.368 5.771 18.308 18.706 881.51 178.86 OK
37 12.8 4.224 3.328 8.576 11.520 804.71 104.61 OR
38 18.2 9.100 5.642 17.472 16.016 905.99 153.86 PA
39 11.1 3.774 4.218 10.212 8.769 1148.99 148.58 RI
40 23.9 9.082 9.799 22.944 19.359 858.97 116.29 SC
41 19.4 6.014 6.402 19.012 16.684 669.31 96.87 SD
42 19.5 4.095 5.655 15.990 15.795 767.91 155.57 TN
43 19.4 7.760 7.372 17.654 16.878 1004.75 156.83 TX
44 11.3 4.859 1.808 9.944 10.848 809.38 109.48 UT
45 13.6 4.080 4.080 13.056 12.920 716.20 109.61 VT
46 12.7 2.413 3.429 11.049 11.176 768.95 153.72 VA
47 10.6 4.452 3.498 8.692 9.116 890.03 111.62 WA
48 23.8 8.092 6.664 23.086 20.706 992.61 152.56 WV
49 13.8 4.968 4.554 5.382 11.592 670.31 106.62 WI
50 17.4 7.308 5.568 14.094 15.660 791.14 122.04 WY
  1. Найдите топ 5 штатов с наибольшим числом аварий на пройденную милю.
  2. Какой признак больше всего влияет на аварию. Обоснуйте ваш выбор, используя pandas и seaborn.