#!/usr/bin/env python
# coding: utf-8
# # Майнор по Анализу Данных, Группа ИАД-2
# ## 08/02/2017 Метод kNN, введение в sklearn
# In[ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = (12,8)
# Для кириллицы на графиках
font = {'family': 'Verdana',
'weight': 'normal'}
plt.rc('font', **font)
# In[ ]:
try:
from ipywidgets import interact, IntSlider, fixed
from utils import *
except ImportError:
print u'Так надо'
# # Метод k-ближайших соседей
# Вспомним теоретическую базу метода kNN.
#
# ## Общая постановка задачи МО
# * Множество объектов $O$
# * Каждому объекту $o \in O$ можно поставить в соответствие набор признаков $(x, y)$ где
# * $x \in X$ - вектор описательных признаков
# * $y \in Y$ - целевой признак
# * Существует неизвестная зависимость $f:X \rightarrow Y$
#
# **Задачи:**
# 1. Используя конечный набор примеров $(x, y)$, найти алгоритм (решающую функцию) $a(x) = (\hat{y})$, аппроксимирующую $f(x)$
# 2. Применить алгоритм $a(x)$ на новых объектах
#
# ## Как постросить $a(x)$ из семейства метрических методов (kNN)?
#
# * Гипотеза компактности: "Похожим объектам соответстуют похожие ответы"
# * Необходимо ввести функцию расстояния между объектами (не обязательно метрику)
# * Запоминаем обучающую выборку и используем для расчета расстояния
#
# ### Самые популярные меры расстояния
#
# $$ d(a, b) = \sum\limits_{i=1}^{D}(a_i - b_i)^2 \text{: euclidean distance} $$
#
# $$ d(a, b) = \sum\limits_{i=1}^{D}|a_i - b_i| \text{: manhattan distance} $$
#
# $$ d(a, b) = 1 - \frac{\langle a,b \rangle}{||a||_2\cdot||b||_2} \text{: cosine distance} $$
#
# ### Алгоритм (kNN)
#
# Вход: Обучающая выборка $X=(x_i,y_i)$, мера близости $d(\cdot, \cdot)$ и объект $\tilde{x}$
#
# Найти $k$ ближайших объекта в $X$ c помощью $d(\tilde{x},\cdot)$
# * (регрессия) вернуть среднее значение* $$\hat{y} = \frac{1}{k}\sum\limits_{j=1}^k y_{(j)}$$
# * (классификация) вернуть наиболее частую метку класса $$\hat{y} = \arg \max\limits_{y \in \{-1, 1\}}\sum\limits_{j=1}^k [y_{(j)} == y] $$
# ## Пример для регрессии
# In[ ]:
x_true = np.arange(-5, 5, 0.2)
x = x_true + np.random.rand(x_true.shape[0]) - 0.5
y_true = np.sin(x_true)+x_true/3
y = y_true + np.random.rand(x_true.shape[0]) - 0.5
# In[ ]:
plt.plot(x_true, y_true, c='g', label='$f(x)$')
plt.scatter(x, y, label='actual data')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=2)
# In[ ]:
try:
plot_linreg(x_true, y_true, x, y)
except:
print u'Смотрите на доску'
# In[ ]:
try:
fig = interact(plot_knn,
x_true=fixed(x_true), y_true=fixed(y_true), x=fixed(x), y=fixed(y),
k=IntSlider(min=1, max=10, value=1))
except:
print u'Увы, вновь на доске'
# #### Разберемся c sklearn и сами построим такой график
# In[ ]:
from sklearn.neighbors import KNeighborsRegressor
## Разбираемся
# ## Пример для классификации
# In[ ]:
from sklearn.datasets import make_moons
X_moons, y_moons = make_moons(noise=0.3, random_state=1234)
# In[ ]:
plt.scatter(X_moons[:,0], X_moons[:,1], c=y_moons, s=200)
plt.xlabel('$x_1$')
plt.ylabel('$x_2$')
# In[ ]:
try:
fig = interact(plot_knn_class,
X_moons=fixed(X_moons), y_moons=fixed(y_moons),
k=IntSlider(min=1, max=10, value=1))
except:
print u'Доскааааа'
# #### Задание
#
# Попробуйте сами нарисовать такой график. С этим вам могут помочь функции `np.meshgrid()` и `plt.contourf()`
# In[ ]:
from sklearn.neighbors import KNeighborsClassifier
## Your code here
# # Взвешенный kNN
#
# Вход: Обучающая выборка $X=(x_i,y_i)$, мера близости $d(\cdot, \cdot)$ и объект $\tilde{x}$
#
# Найти $k$ ближайших объекта в $X$ c помощью $d(\tilde{x},\cdot)$
#
# * (регрессия) вернуть среднее взвешенное значение* $$\hat{y} = \frac{\sum\limits_{j=1}^k w_{(j)} y_{(j)}}{\sum\limits_{j=1}^k w_{(j)}}$$
# * (классификация) вернуть наиболее частую метку класса c учетом веса $$\hat{y} = \arg \max\limits_{y \in \{-1, 1\}}\sum\limits_{j=1}^k w_{(j)} [y_{(j)} == y] $$
#
# ## Варианты весов
# * $w_{(j)} = \frac{k - j + 1}{k}$
# * $w_{(j)} = 1/d(\tilde{x},x_{(j)})$
# * $w_{(j)} = K(\frac{d(\tilde{x},x_{(j)})}{h}) $ Парзеновское окно (Parzen Window).
# * $K$ - ядро, $h$ - ширина окна
#
# ## Ядра
# * $K(d, h) \propto \exp(- \frac{d^2}{2h^2})$ - gaussian kernel
# * $K(d, h) \propto 1 if x < d$ - tophat kernel
# * $K(d, h) \propto 1 - \frac{d^2}{h^2}$ - epanechnikov kernel
# * $K(d, h) \propto \exp(-d/h)$ - exponential kernel
# * $K(d, h) \propto 1 - d/h if d < h$ - linear kernel
# * $K(d, h) \propto \cos(\frac{\pi d}{2h}) if x < h$ - linear kernel
#
#