Целите днес:
Трябват ви jupyter, scikit-learn и няколко други технологии. Имате два начина да ги подкарате:
pip install
Ние предпочитаме първия подход, понеже сме относително уверени в Python и ни е по-прозрачно така. Бихме ви предложили да направите същото. Разбира се, може да пробвате и Anaconda. Няма голямо значение кое от двете ще изберете, стига да ви е комфортно.
pip install
¶За да начало са ви нужни следните неща:
pip install numpy scipy matplotlib ipython scikit-learn pandas pillow mglearn jupyter
Конкретно:
Веднъж като сте качили всичко това, просто изпълнете в терминала:
jupyter notebook
Това ще ви отвори браузър, където може да започнете работа.
За начало, нека разгледаме Jupyter.
Demo!
Jupyter е интерактивна среда, която ви позволява да изпълявате код и да чертаете диаграми в notebook формат. Тя е много подходяща за експериментиране с модели. Допълнително, може да споделите изследванията с някой като му пратите готов notebook. Например, тази лекция е един голям jupyter notebook, който ползваме едновремено за примери и слайдове. Части от нея (като този параграф) няма да бъдат достъпни в слайдовете, но ще може да разгледате впоследствие.
Python е относително прост език за програмиране. Ще ви го разкажем в по-късна лекция – засега примерите ще бъдат частично разбираеми, частично черна магия. Не се притеснявайте ако нещо не ви е ясно. Избрали сме го, защото той има най-добрите библиотеки за machine learning. Авторите на тези библиотеки пък са го избрали, защото е много лесен за научаване.
Стефан го мрази със страст. Може да го разпитате в някое междучасие. Нека това да не ви обезсърчава – обективно погледнато е добър език, особено за този тип проблеми.
Долното парче код ще ви е нужно в повечето jupyter notebooks
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
from IPython.display import display
%matplotlib notebook
Проблемите, подходящи за "машинно самообучение", имат следните качества:
Някои интересности:
Каква математика ще ви е нужна? Кратката версия:
$$ y = ax + b $$
(където $y$ и $b$ са вектори, а $a$ и $x$ са матрици)
Дългата версия е по-сложна.
Малко по-детайлно:
Задължително ще ви трябва да разбирате от поне малко линейна алгебра. Като начало, трябва да разбирате от умножение на матрици и да ви е относително комфортно да го правите. Това е едно добро начало.
В подробности – всеки алгоритъм си има особеностите и математиката, свързана с него. Линейната регресия е напълно разбираема с познания от първи семестър, първи курс. Други алгоритмни като Support Vector Machines или Principal Component Analysis са по-сложни и искат повече познания. На практика, може да стигнете доста далеч с повърхностно разбиране на тези алгоритми. На теория, колкото повече математика знаете, толкова по-добре ще се оправите.
За целите на курса ще се нуждаем единствено от уравнението по-горе.
Обикновено работим с таблица от входни данни:
Възраст | Коли | Къща | Деца | Женен? | Куче? | Купува лодка? |
---|---|---|---|---|---|---|
66 | 1 | да | 2 | вдовец | не | да |
52 | 2 | не | 3 | женен | не | да |
22 | 0 | не | 0 | женен | да | не |
25 | 1 | не | 1 | неженен | не | не |
44 | 0 | не | 2 | разведен | не | не |
39 | 1 | да | 2 | женен | да | не |
26 | 1 | не | 2 | неженен | не | не |
40 | 3 | да | 1 | женен | да | не |
53 | 2 | да | 2 | разведен | не | да |
64 | 2 | да | 3 | разведен | не | да |
58 | 2 | да | 2 | женен | да | да |
33 | 1 | не | 1 | неженен | не | не |
На първите 6 колони от предната таблица може да гледате като матрицата $X$, докато на последната колона като вектора $y$.
Булевите данни могат да се кодират като числата 0 и 1, а енумерациите (женен?) като серия от числа. Различни репрезентации може да са подходящи за различни алгоритми.
Конвенцията $X$ и $y$ ще се ползва постоянно, така че е добре да свикнете с нея. Когато се опитваме да отговаряме на въпроси (тези хора биха ли си купили лодка?), ще подаваме хората като матрица $X$ и ще очакваме да получим вектор $y$, където всеки елемент от вектора ще съдържа отговор дали този човек би си купил лодка.
Работата с текст обикновено се свежда до извличане на скаларни feature-и от данните (например колоните могат да съответстват на уникални думи в документа, докато клетките – на брой срещания). Това е по-дълбока вода, която ще покрием по-натам.
scikit-learn предлага няколко набора от примерни данни с които може да работите.
Всички те могат да се ползват за прости експерименти и илюстрация на моделите. Дори ще ползваме някои.
Ако искате да ползвате определен dataset:
from sklearn.datasets import load_boston
boston = load_boston()
print(boston.data.shape)
Ето описание на boston dataset-а:
print(boston.DESCR)
Данните са в boston.data
, имената на feature-ите са в boston.feature_names
(съответстват не тези кратки съкращения по-горе), а очакваната цел е в boston.target
.
boston.data
boston.feature_names
boston.target
Обърнете внимание, че това не са Python масиви, ами NumPy вектори и матрици.
scikit-learn предлага и някои синтетични набори от данни. Понякога и те са интересни.
Любопитен пример е make_moons
, който прави два полумесеца.
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=100, noise=0.25, random_state=3)
plt.close()
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
None
Този dataset е по-лесно разбираем.
X
y
Впрочем, ето невронна мрежа, която разпознава граница между двата класа:
from sklearn.neural_network import MLPClassifier
plt.close()
mlp = MLPClassifier(solver='lbfgs', random_state=0).fit(X, y)
mglearn.plots.plot_2d_separator(mlp, X, fill=True, alpha=.3)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
Горния код има няколко проблема, в които ще влезем по-натам. Засега просто искаме да ви покажем малко графики, не да разберем как работят невронните мрежи (което е дълъг и сложен въпрос).
Повече информация за наборите от данни в scikit-learn може да намерите в документацията:
Алгоритмите могат да се разделят на два видя:
Примери за supervised learning са:
Тези алгоритми са по-разнородни и приложими в определени сфери. Например:
Бихме могли да разделим supervised learning на два вида:
Стандартен подход за класификация с 3+ класа е one-vs-many – създаваме по един класификатор за всяка категория, прекарваме данните през тях и избираме най-вероятната.
Сега ще разгледаме няколко алгоритъма отгоре-отгоре. Целта е да разберем как работят концептуално. Ще разгледаме всеки от тях в детайли в следващи лекции.
Ще гледаме набори от данни с едно или две измерения. Те са доста лесни за визуализация, но рядко реалистични – обикновено работим със десетки, стотици или дори хиляди feature-а (т.е. измерения). Това е далеч по-трудно за визуализация, откъдето идва и голяма част от предизвикателството.
mglearn.plots.plot_knn_classification(n_neighbors=1)
Предния пример гледаше 1 най-близък съсед. Може да се имплементира да гледа няколко:
mglearn.plots.plot_knn_classification(n_neighbors=3)
Броят съседи определя колко "гладка" е границата между двата класа. Ето един пример с различен брой съседи:
from sklearn.neighbors import KNeighborsClassifier
X, y = mglearn.datasets.make_forge()
fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for n_neighbors, ax in zip([1, 3, 9], axes):
clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X, y)
mglearn.plots.plot_2d_separator(clf, X, fill=True, eps=0.5, ax=ax, alpha=.4)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
ax.set_title("{} neighbour(s)".format(n_neighbors))
Фонът в горната диаграма определя в кой от двата класа ще попадне дадена точка. Обърнете внимание, че при k=1 границата е начупена и хваща всеки елемент. При по-голямо k границата става по-плавна, макар и да класифицира някои елементи грешно. Това може да е предимство (ще игнорира аномалии в данните). Ще видим вариации на тази тема по-натам с нормализация в линейните модели.
mglearn.plots.plot_linear_regression_wave()
Алгоритъмът се опитва да намери линейна функция, която минимизира общата грешката (сумата от квадратите на дистанцията между резултата от линейната функция и y координата на всеки елемент от набора от данни). В горния е трудно да се направи по-точен линеен модел, тъй като данните имат голяма вариация за едни и същи входни стойности. При наличието на повече измерения обикновено може да се постигне по-добър резултат.
Можете да сведете многомерно пространство до такова с по-малко измерения, които запазват (почти напълно) същата информация.
Може да се ползва за feature selection – да намалите броя характеристики с които тренирате модел, свеждайки ги до по-малко.
mglearn.plots.plot_pca_illustration()
Графиките горе илюстрират как PCA се опитва да сведе двуизмерно пространство до едноизмерно. Данните могат да се представят чрез базис от два вектора (component 1 и component 2), където component 1 съдържа много информация, а component 2 – малко. С този dataset бихме могли да тренираме относително точен модел само с component 1. Обърнете внимание, че той е функция на оригиналните два feature-а.
При две измерения това не е нужно, но при 1000+ подобна трансформация на данните може да е задължителна за да има шанс да съберете модела в паметта.
mglearn.plots.plot_kmeans_algorithm()
Този алгоритъм е относително магически. Работи по следния начин:
Този алгоритъм е недетерминистичен – различен избор на първоначални точки може да произведе различни резултати. По тази причина на практика се изпълнява няколко пъти и се взема добър резултат.
Това също е мотив, който се среща често.