<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Общая информация
Срок сдачи
Step1:  IRIS
Step2:  MNIST
Step3:  Задание 5
<ASSISTANT_TASK:>
Python Code:
import numpy as np
import matplotlib.pyplot as plt
from line_profiler import LineProfiler
from sklearn.metrics.pairwise import pairwise_distances
import seaborn as sns
from sklearn import datasets
from sklearn.base import ClassifierMixin
from sklearn.datasets import fetch_mldata
from sklearn.neighbors.base import NeighborsBase, KNeighborsMixin, SupervisedIntegerMixin 
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
%load_ext pycodestyle_magic
def profile_print(func_to_call, *args):
    profiler = LineProfiler()
    profiler.add_function(func_to_call)
    profiler.runcall(func_to_call, *args)
    profiler.print_stats()
%%pycodestyle
class MyKNeighborsClassifier(NeighborsBase, KNeighborsMixin,
                             SupervisedIntegerMixin, ClassifierMixin):
    def __init__(self, n_neighbors=3):
        self.n_neighbors = n_neighbors
    def fit(self, X, y):
        self.X = np.float64(X)
        self.classes, self.y = np.unique(y, return_inverse=True)
    def euclidean_metric(self, v):
        return np.sqrt(((self.X - v) ** 2).sum(axis=1))
    '''
    def cnt(self, v):
        z = np.zeros(self.classes.size)
        for i in v:
            z[i] += 1
        return z
    def predict_proba(self, X): # more understandable
        X = np.float64(X)
        # euclidean by default, can use multithreading
        dist = pairwise_distances(X, self.X)
        ind = np.argsort(dist, axis=1)[:, :self.n_neighbors]
        return np.apply_along_axis(self.cnt, 1, self.y[ind]) / self.n_neighbors
    '''
    # '''
    def predict_proba(self, X):  # more quickly
        X = np.float64(X)
        # euclidean by default, can use multithreading
        dist = pairwise_distances(X, self.X)
        ind = np.argsort(dist, axis=1)[:, :self.n_neighbors]
        classes = self.y[ind]
        crange = np.arange(self.classes.shape[0])
        clss = classes.reshape((classes.shape[0], 1, classes.shape[1]))
        crng = crange.reshape((1, crange.shape[0], 1))
        counts = np.sum(clss == crng, axis=2)
        return counts / self.n_neighbors
    # '''
    def predict(self, X):
        proba = self.predict_proba(X)
        return self.classes[np.argsort(proba, axis=1)[:, -1]]
    def score(self, X, y):
        pred = self.predict(X)
        return 1 - np.count_nonzero(y - pred) / y.shape[0]
Explanation: Общая информация
Срок сдачи: 13 марта 2017, 06:00 <br>
Штраф за опоздание: -2 балла после 06:00 13 марта, -4 балла после 06:00 20 марта, -6 баллов после 06:00 27 марта
При отправлении ДЗ указывайте фамилию в названии файла
Присылать ДЗ необходимо в виде ссылки на свой github репозиторий в slack @alkhamush
Необходимо в slack создать таск в приватный чат:
/todo Фамилия Имя ссылка на гитхаб @alkhamush
Пример:
/todo Ксения Стройкова https://github.com/stroykova/spheremailru/stroykova_hw1.ipynb @alkhamush
Используйте данный Ipython Notebook при оформлении домашнего задания.
Задание 1 (2 баллов)
Реализовать KNN в классе MyKNeighborsClassifier (обязательное условие: точность не ниже sklearn реализации)
Разберитесь самостоятельно, какая мера расстояния используется в KNeighborsClassifier дефолтно и реализуйте свой алгоритм именно с этой мерой. Самостоятельно разберитесь, как считается score из KNeighborsClassifier и реализуйте аналог в своём классе.
Задание 2 (2 балла)
Добиться скорости работы на fit,  predict и predict_proba сравнимой со sklearn 4 балла для iris и mnist
Для этого используем numpy
Задание 3 (2 балла)
Для iris найдите такой параметр n_neighbors, при котором выдаётся наилучший score. Нарисуйте график зависимости score от n_neighbors
Задание 3 (2 балла)
Выполнить требования pep8
Задание 5 (2 балла)
Описать для чего нужны следующие библиотеки/классы/функции (список будет ниже)
End of explanation
iris = datasets.load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.1, stratify=iris.target)
clf = KNeighborsClassifier(n_neighbors=17)
my_clf = MyKNeighborsClassifier(n_neighbors=17)
%time clf.fit(X_train, y_train)
%time my_clf.fit(X_train, y_train)
%time clf.predict(X_test)
%time my_clf.predict(X_test)
#profile_print(my_clf.predict, X_test)
%time clf.predict_proba(X_test)
#%time my_clf.predict_proba(X_test)
profile_print(my_clf.predict_proba, X_test)
clf.score(X_test, y_test)
my_clf.score(X_test, y_test)
# Задание 3
# 16 - 17
num_n = 30
num_av = 2000
scm = np.zeros(num_n)
sc = np.zeros(num_av)
for n in range(1, num_n + 1):
    print (n)
    for i in range(num_av):
        X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.1, stratify=iris.target)
        my_clf = MyKNeighborsClassifier(n_neighbors=n)
        my_clf.fit(X_train, y_train)
        sc[i] = my_clf.score(X_test, y_test)
    scm[n - 1] = sc.mean()
plt.plot(range(1, num_n + 1), scm, 'ro-')
plt.show()
Explanation: IRIS
End of explanation
mnist = fetch_mldata('MNIST original')
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.01, stratify=mnist.target)
y_train.shape
clf = KNeighborsClassifier(n_neighbors=5)
my_clf = MyKNeighborsClassifier(n_neighbors=5)
%time clf.fit(X_train, y_train)
%time my_clf.fit(X_train, y_train)
%time clf.predict(X_test)
%time my_clf.predict(X_test)
%time clf.predict_proba(X_test)
#%time my_clf.predict_proba(X_test)
%time profile_print(my_clf.predict_proba, X_test)
clf.score(X_test, y_test)
my_clf.score(X_test, y_test)
# n_neighbors = 5
num_n = 30
num_av = 20
scm = np.zeros(num_n)
sc = np.zeros(num_av)
for n in range(1, num_n + 1):
    print (n)
    for i in range(num_av):
        print (n, ' ', i)
        X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.001, stratify=mnist.target)
        my_clf = MyKNeighborsClassifier(n_neighbors=n)
        my_clf.fit(X_train, y_train)
        sc[i] = my_clf.score(X_test, y_test)
    scm[n - 1] = sc.mean()
plt.plot(range(1, num_n + 1), scm, 'ro-')
plt.show()
print (1)
Explanation: MNIST
End of explanation
# seaborn - красивые и простые в написании графики и визуализация
# matplotlib - более сложные в написании и более функциональные, чем seaborn
# train_test_split - разбиение данных на обучающую и тестовую часть
# Pipelin%load_ext e (from sklearn.pipeline import Pipeline) - конвейерный классификатор
# StandardScaler (from sklearn.preprocessing import StandardScaler) - нормировка
# ClassifierMixin - общий Mixin для классификаторов, в нем реализован score
# NeighborsBase - базовый класс Knn
# KNeighborsMixin - Mixin содержащий метод поиска ближайших соседей
# SupervisedIntegerMixin - Mixin с функцией fit для установления соответствия
#                          между данными и целевыми переменными
Explanation: Задание 5
End of explanation
<END_TASK>