# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] id="_thAKR27rZY5"
# # Семинар 2 - pandas, linear regression
# -

import numpy as np

# + [markdown] id="VQawW-URvaNx"
# ## 1. Pandas
# ![alt text](https://media0.giphy.com/media/fAaBpMgGuyf96/giphy.gif)
#
# - документация: http://pandas.pydata.org/pandas-docs/stable/
# - 10 minutes to pandas: https://pandas.pydata.org/pandas-docs/stable/10min.html
# - Pandas Tutorial: DataFrames in Python: https://www.datacamp.com/community/tutorials/pandas-tutorial-dataframe-python
# - Cheet Sheet: https://www.analyticsvidhya.com/blog/2015/07/11-steps-perform-data-analysis-pandas-python/
# - Visualization: http://pandas.pydata.org/pandas-docs/stable/visualization.html
#
# Будем работать с данными, собранными благодаря опросу студентов математического курса средней школы в Португалии (возраст - от 15 до 22 лет). Они находятся в файле ["math_students.csv"](https://raw.githubusercontent.com/AKuzina/ml_dpo/main/practicals/math_students.csv). 
#
#  Целевой переменной является итоговая оценка студента за курс.

# + id="7-qYDedovv6G"
import matplotlib.pyplot as plt
import pandas as pd

# магическая функция, позволяющая выводить графики прямо в ноутбук
# %matplotlib inline

# + colab={"base_uri": "https://localhost:8080/", "height": 223} id="fntOj3Bfv04j" outputId="2eb3c393-fe54-4260-99af-41ce1f9ef2c9"
# если данные и ноутбук находятся в разных папках, то для загрузки файла помимо названия необходимо также прописать путь к нему
# .csv - текстовый файл для представления табличных данных, разделенных каким-то символом. В данном случае - запятой
data = pd.read_csv('math_students.csv', delimiter=',')

# функция .head(n) выводит первые n строк таблицы (по умолчанию n=5)
data.head()

# + [markdown] id="FP5GcluiwYgq"
# Итак, всего объектов 395, а признаков - 32 (учитываем, что один из столбцов - это целевая переменная). Все признаки имеют разную природу. Вот их более подробная расшифровка:
#
#  - school - тип школы ("GP" - Gabriel Pereira или "MS" - Mousinho da Silveira)
#  - sex - пол ("F" - female или "M" - male)
#  - age - возраст (от 15 до 22)
#  - address - откуда студент ("U" - urban или "R" - rural)
#  - famsize - размер семьи ("LE3" - меньше или равно 3 или "GT3" - больше 3)
#  - Pstatus - в каких отношениях родители ("T" - живут вместе "A" - раздельно)
#  - Medu - образование матери (0 - никакого,  1 - начальное образование (4 класса), 2 – от 5 до 9 классов, 3 – среднеспециальное или 4 – высшее)
#  - Fedu - образование отца (0 - никакого,  1 - начальное образование (4 класса), 2 – от 5 до 9 классов, 3 – среднеспециальное или 4 – высшее)
#  - Mjob - работа матери ("teacher", "health" care related, civil "services" (e.g. administrative or police), "at_home" or "other")
#  - Fjob - работа отца ("teacher", "health" care related, civil "services" (e.g. administrative or police), "at_home" or "other")
#  - reason - причина выбора школы (близко к дому — "home", репутация школы — "reputation", предпочтение некоторым предметам - "course" или "other")
#  - guardian - опекун ("mother", "father" или "other")
#  - traveltime - время от дома до школы (1 - меньше 15 мин., 2 - 15 до 30 мин., 3 - 30 мин. до 1 часа, или 4 - больше 1 часа)
#  - studytime - количество часов обучения в неделю (1 - меньше 2 часов, 2 - от 2 до 5 часов, 3 - от 5 до 10 часов, или 4 - больше 10 часов)
#  - failures - количество ранее не сданных предметов (n if 1 <= n < 3, else 4)
#  - schoolsup - дополнительные занятия (yes or no)
#  - famsup - помощь от семьи при выполнении заданий (yes or no)
#  - paid - дополнительные платные занятия (yes or no)
#  - activities - внеклассная деятельность (yes or no)
#  - nursery - посещал детский сад (yes or no)
#  - higher - желание высшего образования (yes or no)
#  - internet - домашний интернет (yes or no)
#  - romantic - состоит в романтических отношениях (yes or no)
#  - famrel - насколько хороши отношения в семье (от 1 - очень плохие до 5 - превосходные)
#  - freetime - наличие свободного времени после школы (от 1 - очень мало до 5 - очень много)
#  - goout - гуляет с друзьями (от 1 - редко до 5 - очень часто)
#  - Dalc - употребление алкоголя в будние дни (от 1 - очень редко до 5 - очень часто)
#  - Walc - употребление алкоголя в выходные (от 1 - очень редко до 5 - очень часто)
#  - health - текущее состояние здоровья (от 1 - очень плохое до 5 - очень хорошее)
#  - absences - количество школьных пропусков (от 0 до 93)
#  - G1 - оценка за первый семестр (от 0 до 20)
#  - G2 - оценка за второй семестр (от 0 до 20)
#  - G3 - итоговая оценка (от 0 до 20)
#
#  ---
#
#  Для вывода названий всех признаков есть специальная функция:

# + colab={"base_uri": "https://localhost:8080/"} id="MhSvxiE8wTdA" outputId="75fd2f1e-2ce8-40bf-dca8-4d8b147d2b99"
data.columns

# + [markdown] id="lKr1ovmow4Oi"
#  Как обращаться к колонкам?
# * "dot" `data.G3` 
# * "brackets" `data['G3']`. 
# * "list in the bracket" `data[['G3', 'G2']]` 
# * "index" `data.iloc[:, -1]`
#

# + colab={"base_uri": "https://localhost:8080/"} id="DgPVCFzPxUlO" outputId="dbbe86d0-6497-4f95-ba1d-58de95561835"
data.G3 

# + colab={"base_uri": "https://localhost:8080/"} id="2t-EcqAFw2Bn" outputId="5bec1184-fe4a-4f50-8d7b-388fe0c503a2"
data['G3']

# + colab={"base_uri": "https://localhost:8080/", "height": 417} id="o5-FkXjvxYmE" outputId="ae0ba69b-7ba5-46b8-d02b-9999c6ce223c"
data[['G3']]

# + colab={"base_uri": "https://localhost:8080/"} id="fMANF_rWxa9z" outputId="39e093e1-e380-4a4c-931a-7bee6499ebe6"
data.iloc[:10, 10]

# + [markdown] id="XslY65_yxmi4"
# ---
# **Задание 1**  Отделить от признаков целевую переменную. Создать вектор `y` и таблицу `X`

# + colab={"base_uri": "https://localhost:8080/"} id="vzKqb7W0yDi4" outputId="c951fe04-265e-4fb2-a3a8-0777d4ee11ef"
data.columns[:-1]

# + id="-jF8GAa5xjsL"
X = data[data.columns[:-1]]
X.shape
# -

y=data.G3
y.shape

# + [markdown] id="3TkRdmrWyG69"
# А теперь тоже самое, используя функцию `drop`:
#
# ```data.drop([col_1, col_2], axis=1)```

# + id="pD9NIxzLyYNO"
X = data.drop(['G3'], axis=1)
X.shape

# + [markdown] id="3qQKAHD2ycwF"
# Посмотрим, есть ли в данных пропуски:

# + colab={"base_uri": "https://localhost:8080/"} id="22BPVfc1ydIK" outputId="946b9f7f-b313-49b1-9ba1-88562fcc683f"
data.isna().sum()

# + [markdown] id="OwfUgnrjyjGb"
# По любой функции можно получить информацию из документации следующим образом:

# + id="CJGc4nPiyeqv"
# ?pd.isna

# + [markdown] id="7W0YW9Riysr6"
# Можно вывести статистику по значениям признаков:

# + colab={"base_uri": "https://localhost:8080/", "height": 317} id="iY65hSxPymi6" outputId="e11e78a5-1cfc-49e4-979d-fab1b7d46949"
data.describe()

# + [markdown] id="cLpEWKXuyxYo"
# ---
# **Задание 2**  Прочитайте документацию и выведите статистику по значениям **всех** признаков

# + id="8ZtxVFqvzC-y"
# ?data.describe 

# + colab={"base_uri": "https://localhost:8080/", "height": 410} id="V5UUN0O5yua1" outputId="a0b5006b-c33c-4f7e-9d4d-75a8340b23c4"
data.describe(include="all")

# + [markdown] id="L1BHTv-EzsGA"
# Какие значения принимает признак `guardian`?

# + colab={"base_uri": "https://localhost:8080/"} id="BTleoolZy_lK" outputId="38bf1fb3-a86d-4978-d206-4f496c4e6b80"
data['guardian'].unique()

# + colab={"base_uri": "https://localhost:8080/"} id="vWQ4ftRxzuPq" outputId="07991640-c164-489d-c765-71068d38d5eb"
data['guardian'].value_counts()

# + [markdown] id="KcSi-lLCzzJr"
# Чтобы получить все строки, которые удовлетворяют условию 
#
# ```table[condition]```

# + colab={"base_uri": "https://localhost:8080/", "height": 224} id="md3FCosK0EkI" outputId="8260db26-8d44-49a7-b20b-724790e939fc"
data[data.guardian == 'mother'].head()

# + [markdown] id="fRVa6wWE0EwV"
#
# Чтобы комбинировать условия:
#
# * `&` --- and
# * `|` --- or
# * `~` --- not

# + colab={"base_uri": "https://localhost:8080/", "height": 224} id="ymqDJSdtzwJ1" outputId="0ddc2ded-8e14-4193-ad17-16cb1176b974"
data[(data.guardian == 'mother') | (data.guardian == 'father')].head()

# + [markdown] id="x1jjU6_H0Uhw"
# ---
# **Задание 3**  
# 1. Выделим студентов младще 16 лет у которых опекуном является не мать

# + colab={"base_uri": "https://localhost:8080/", "height": 224} id="IzZ3rqt60SJc" outputId="9cff7ef6-4f5c-4247-c5c8-87079f9d50f2"
data[(data.guardian != 'mother') & (data.age <16)].head()

# + [markdown] id="uG6ONBu70hdA"
# 2. Выделим только тех студентов, у которых опекуном является мать и которая работает учителем или на дому:

# + id="Gc8L2-Di0dGg"
data[(data.guardian == 'mother') & ((data.Mjob == 'teacher') | (data.Mjob == 'at_home'))].head()
# -

data[(data.guardian == 'mother') & data.Mjob.isin(['teacher','at_home'])].head()

data.Mjob.value_counts()

# + [markdown] id="E_ZHPF5t1OHD"
# ---
# Проанализируем взаимосвязь количества пропусков и успехов в учебе. Посмотрим на распределение количества пропусков у студентов:

# + colab={"base_uri": "https://localhost:8080/", "height": 458} id="Y4pj6a9N1OfL" outputId="ae7f51ab-9377-4ea7-838e-253f85f636c6"
plt.figure(figsize=(10,7))
plt.title('Absences distribution')

data['absences'].hist()
plt.xlabel('absences')
plt.ylabel('number of students')
plt.show()

# + [markdown] id="VCQd66101vxc"
# Мы можем считать разные статистки

# + colab={"base_uri": "https://localhost:8080/"} id="TLxCFdpY1jL-" outputId="4f7e7837-c2fd-481b-d27f-582a27a0ff83"
data['absences'].mean()

# + colab={"base_uri": "https://localhost:8080/"} id="vf9hHDGF11ao" outputId="a765073a-2f2e-497b-f519-391353c764e7"
data['absences'].std()

# + colab={"base_uri": "https://localhost:8080/"} id="YDdyRahD13Gq" outputId="8bae91c2-2f96-4073-a1ff-2f509889c4c6"
data['absences'].max()

# + [markdown] id="avTmDdit1_57"
# ---
# **Задание 4** Разделите студентов на две части: те, у кого количество пропусков меньше среднего, и те, у кого оно **не** меньше среднего.

# + id="1f0E-8Cj14rS"
mean_absences = data['absences'].mean()
missers = data[data['absences'] < mean_absences]
non_missers = data[data['absences'] >= mean_absences]

# + [markdown] id="3H-oa5oT2Oqw"
# ---
# **Задание 5**  Посчитайте среднее значение целевой переменной для каждой части.

# + colab={"base_uri": "https://localhost:8080/"} id="4-v0aawW2RcV" outputId="95b01dc3-2e24-4787-a451-955b2504ed89"

stud_few_absences_g3 = missers.G3.mean()
stud_many_absences_g3 = non_missers.G3.mean()

print('Students with few absences, mean G3: ', stud_few_absences_g3)
print('Students with many absences, mean G3:', stud_many_absences_g3)

# + [markdown] id="JD0_zfHe2h8U"
# Итак, средние оценки примерно одинаковы - у тех, кто пропускал меньше занятий, она чуть хуже. Возможно, студенты, пропускавшие много занятий, знали материал очень хорошо :)
#
# Также данные можно исследовать с помощью диаграммы рассеивания (scatter plot)

# + colab={"base_uri": "https://localhost:8080/", "height": 297} id="86MuItuc2UlT" outputId="<PASSWORD>"
plt.figure(figsize=(10,7))

data.plot.scatter(x = 'absences', y='G3')
plt.xlabel('absences')
plt.ylabel('Grade')
plt.show()
# -

# ## 2. Линейная Регрессия
#
# Поработаем с линейной регрессией на практике с помощью библиотеки [scikit-learn](https://scikit-learn.org/stable/). Эта библиотека включает в себя множество алгоритмов, разные тестовые наборов данных, функции для подсчета метрик и подбора параметров, а также многое другое.

StarcoderdataJupyterScriptsDedupFiltered