Skip to content

Latest commit

 

History

History
177 lines (151 loc) · 16.8 KB

DS_01_ML_basic.md

File metadata and controls

177 lines (151 loc) · 16.8 KB

Data Scientist. ML. Начальный уровень

Дополнительные материалы

  • Статья с подробным разбором градиентного спуска и регуляризации - A Complete Tutorial on Ridge and Lasso Regression in Python в т.ч. разбирается математическая основа. Нужна для прохождения "Модуля 4 - Регрессия. Часть 2."

Module 1. Основные концепции Machine Learning

  • Где домашнее задание?
Многие его не замечают: Домашняя работа ML1.8

Module 4. Регрессия. Часть 2

Задание высокого уровня

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

MSE(Gradient Ridge Regression)

Module 5. Классификация. Часть 1

Проблемы

Может возникнуть проблема с graphviz. Это целый пакет утилит для визуализации графов. При работе через Anaconda можно использовать следующее решение:

  • Первая команда установить пакет утилит, из основного репозитория.
  • Вторая команда установить обёртку вокруг них, чтобы можно было работать из python
        conda install -c anaconda graphviz
        conda install -c conda-forge python-graphviz
  • Альтернативным вариантом может быть использование Google Colab
    • ❔Если у кого-то работает, подтвердите
  • Альтернативным вариантом может быть решение Михаила:
    • Поставить утилиты с офицального сайта graphviz
    • И после прописать путь в PATH к папке, где лежат утилиты.
    • Или прописать PATH в блокноте Юпитера (Только вместо D:/Program Files (x86)/Graphviz2.38/bin/ указать ваш путь)
        import os
        os.environ["PATH"] += os.pathsep + 'D:/Program Files (x86)/Graphviz2.38/bin/'
  • ❔Если у кого-то работает, подтвердите

Задание 3 - часть 4

В задании, где нужно указать max_features=2, также нужно указать random_state=17. Указывать данный параметр нужно в двух местах:

Указывать данный параметр нужно в двух местах, можете подумать сами где или заглянуть в спойлер:
  • `train_test_split(wine_dataframe_x, wine_dataframe_y, random_state=17)` - фиксируется разбиение датасета.
  • `DecisionTreeClassifier(random_state=17)` - фиксируется процесс обучения модели определённым образом
  • Результат обучения модели без `max_features=2` - 0.91
  • Результат обучения модели с `max_features=2` - 0.95

Текстовые описание алгоритмов

  • Для практики работы с python и чтобы лучше понять как устроены алгоритмы, написал текстовые пояснения об их устройстве и параллельно написал по ним свои 🚲
  • Если интересен код

Алгоритм KNN

  • Посчитать расстояние от каждой из 38 точек до 112 точек, по которым знаем тип цветка.
  • Расстояние рассчитывается по всем признакам ($\sqrt{(x_1 - x_2)^2...}$) - где индексы это тренировочные и тестовые данные, а $x$ - это фичи (первая фича x, вторая y, и т.д.).
  • Список с расстояниями - состоит из расстояния (положительное число) до цветка и типа цветка от которого считали расстояние.
  • Сделать сортировку в данном списке (нужна $\lambda$ т.к. сложная структура вложенные списки).
  • Взять $k$ значений из сортированного списка.
  • Посчитать сколько и каких типов среди выбранных значений, выбрать тот тип, что чаще других встречается.
  • Сделать предсказание и далеко идёщие выводы.
  • Метрика проверки - угадал к общему количеству классифицируемых объектов.

Алгоритм «Наивный Байес»

  1. Нужно посчитать данные по 3 классам цветов по фичам (в нашем случае 2 фичи).
  2. Нужно рассчитать математическое ожидание - средняя $\mu$ - для каждого класса.
  3. Нужно рассчитать дисперсию - вариацию $\sigma$ - для каждого класса.
    • Данные параметры задают форму нормального распределения (полностью её определяют).
  4. Реализовать формулу (рассчёт веротяности) $p(x_i|y) = \frac{1}{\sqrt{2\pi \sigma^2_y}}exp(-\frac{(x_i - \mu_y)^2}{2\sigma^2_y})$
    • Нужно зафиксировать параметры $\sigma$ и $\mu$ - по данным из обучающей выборки.
    • Значения фичей из обучающей выборки больше не понадабятся.
  5. Посчитать условную вероятность по формуле Байеса $P(Class\ A|Feature\ 1, Feature\ 2) = P(Feature\ 1|Class\ A)\cdot P(Feature\ 2|Class\ A)\cdot P(Class\ A)$
    • Умножение заменим на сложение логарифмов, чтобы не потерять в точности.
    • Не забыть также рассчитать (долю цветков определённого класса - в разбивке - вероятность отнесения к классу) - $P(Class\ A)$
  6. Повторить расчёт для каждого цветка по трём классам, из получившихся вероятностей выбрать наибольшую.

P.S. Реализация алгорита на классах и немного теории

Алгоритм «Дерево решений»

  1. Посчитать меру энтропии - $H(X) = - \sum_i P_x(x_i)log_b P_x(x_i)$
    • основание логарифма $2$ или $e$.
    • P - вероятность, можно использовать частотный подход.
    • $P_x(x_i)$ - вероятность класса (цветков класса к общему количеству)
    • Если Энтропия равна 0, или не очень большая остановить алгоритм.
    • Алгоритм рекурсивный, также для остановки можно использовать кол-во ветвей.
  2. Выбираем критерий (фичу) у объекта, и по этому критерию разделяем датасет на две части.
    • Например: Длина стебля - больше, чем 1.0?
    • Считаем для всех объектов в наборе данных, т.е. разеделяем очень много раз на две части.
  3. Считаем полученную энтропию при каждом разделении.
  4. Выбираем разделение, которое больше всего уменьшает энтропию.
  5. Данное разделение - формирует правило, которое нужно сохранить.
  6. Всё повторяем до точки остановки.
  7. Нужно сохранить полученные правила и использовать их для классификации тестовых данных.
  8. Правила можно хранить в объектах, которые будут содержать в себе правило по частям и ссылку на следующий объект-правило.

P.S. Видео объяснение

Module 6. Классификация. Часть 2

О нулевой гипотезе $H_0$ и метриках

Нулевая гипотеза $H_0$ - наиболее очевидная, что всё ОК или Истина (если задано условием - не ноль), нулевая гипотеза считается верной пока нельзя доказать обратное.

  • Precision (точность "поиска") – способность отличать один класс от другого. Какова доля правильных ответов модели, когда она предсказала TRUE?
    • Учитывает FP - ошибка первого рода - ошибочное отвержение
    • т.е. отвергли $H_0$ и приняли альтернативную гипотеза.
  • Recall (полнота "поиска") - отражает способность алгоритма определять нужный класс вообще т.е. сколько мы корректно классифицировали. Когда класс был TRUE, какова доля того, что модель показала True? Сколько случаев True из общего количества было выявлено моделью?
    • Учитывает FN - ошибка второго рода - ошибочное принятие
    • т.е. приняли $H_0$, хотя верна альтернативная гипотеза.

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

ДЗ-1

Библиотечный и самостоятельный расчёт recall должны полностью совпадать. Если не хотите поразмышлять почему у вас не совпадает см. подробности и не перепутайте Recall с Precision

Подробности:
Выдержка из документации - `confusion_matrix`  
Thus in binary classification, the count of:  
  * true negatives is :math:`C_{0,0}`,  
  * false negatives is :math:`C_{1,0}`,  
  * true positives is :math:`C_{1,1}`,  
  * false positives is :math:`C_{0,1}  
От Андрея Макарова: `tn, fp, fn, tp = confusion_matrix(y_test, knc_predictions).ravel()`

ДЗ-2 (2.3)

Работа с StratifiedKFold - не самая очевидная. Ключевое о чём следует понимать:

  • Создаём объект (генератор), который будет разделять данные на страты (части).
  • Документация говорит следующее:Generate test sets such that all contain the same distribution of classes, or as close as possible. Takes group information into account to avoid building folds with imbalanced class distributions (for binary or multiclass classification tasks). ... Be invariant to class label: relabelling y = ["Happy", "Sad"] to y = [1, 0] should not change the indices generated.
    • т.е. может применятся к не сбалансированным наборам данных, как в нашем случае в "Титанике"
    • а также не чувствителен к названиям признаков (у нас данные в первой части ДЗ были уже подготовлены и сейчас этот для нас не важно)
    • При желании можно сделать вот так: for train_index, test_index in skf.split(X, y)

LogisticRegressionCV - аналог GridSearchCV, важные параметры:

  • cv - параметр, который определяет, как будет происходит разделение переданных данных .fit(X, y). По умолчанию - передаёт данные в генератор k-folds т.е. если указать cs=5 - 5ка пападёт в kfolds как параметр, при этом random_state не попадёт (про random_state - это не 100%) и разделения данных будут различаться и не будет учитвать не сбалансированность данных.
  • verbose=True - показывать ход выполнения операции (актуально если много вариантов перебирает).
  • n_jobs = -1 - использовать все ядра процессора.
    • Cs - ... method includes a parameter Cs. If supplied a list, Cs is the candidate hyperparameter values to select from. If supplied a integer, Cs a list of that many candidate values will is drawn from a logarithmic scale between 0.0001 and and 10000 (a range of reasonable values for C).

Module 7. Кластеризация

Метод локтя - Elbow Method

Есть готовая реализация в библиотеке yellowbrick. Библиотека представляет из себя надстройку над sklearn и позволяет визуализировать данные для более удобного выбора модели и подбора гиперпарамептров.

Module 8. Дополнительные техники. Часть 1

Вычислить определить матрици U

  • В python 3.8.5 считается с ошибкой - выдёт результат 0.9999, правильный ответ -1.0000.
  • UPD: всё немного интереснее SVD decomposition is not unique and I'm thinking maybe your different installations refer to different versions of BLAS - подробности
Код с выводом:

Module 10. Знакомство с Kaggle

Где брать train.csv, test.csv ?

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

Чтобы он работал, можно скорректировать его (закоментированы строки, которые изменяются в блокноте):

# from sklearn.cross_validation import KFold
from sklearn.model_selection import KFold
...
# kf = KFold(ntrain, n_folds= NFOLDS, random_state=SEED)
kf = KFold(n_splits=NFOLDS, random_state=SEED)
...
# for i, (train_index, test_index) in enumerate(kf):
for i, (train_index, test_index) in enumerate(kf.split(np.arange(ntrain))):
...