Исследуем численно разброс и смещение различных моделей обучения. Данные будем генирировать следующим образом. x- одномерное распределение (рассмотрите три различных распределения: нормальное ( np.random.normal(0, 0.3), экспоненциальное (np.random.exponential(0.3)), равномерное (np.random.uniform(0, 1)) y- сумма f(x)=cos(2pi x) и случайного шума (равномерное распределение на [-0.2. 0.2]
Возьмем метод обучения (рассмотрите 4 различных "LinearRegression", "DecisionTree", "RandomForest", "GradientBoosting")
1) Обучите модель с параметрами по умолчанию на сгенерированной выборке (число объектов выборки 100). Постройте на одном графике объекты выборки и восстановленную регрессионную кривую
2) Рассмотрим ансамбль обучающих моделей. Сгенерируйте N_samples=25 случайных выборок, обучите и постройте все выборки и все регрессионные кривые на одном графике (полупрозрачным). Посчитайте среднюю кривую F(x) , как среднее арифмитическое по ансамблю регрессионных кривых. Изобразите его тоже на графике. Изобразите истинную кривую ответов.
3) Вычислите смещение метода обучения. Смещение - это среднее квадрата разности вектора зашумленных ответов и вектора предсказаний
$$ Bias= E_{x,y} ((\mathbb{E}[y|x] - \mathbb{E}_X [\mu(X)])^2)$$.
Для вычисления этого мат.ожидания будем генерировать выборку размера N_objects=100. Средний ответ $\mathbb{E}[y|x] $ на объекте x вычислите как сумму f(x) + среднее значение шума на выборке N_objects (для этого можно сгенерировать отдельно N_objects шумовых компонент) Среднее предсказание $\mathbb{E}_X [\mu(X)]$ на объекте x - это значение построенной функции F(x) (см.2) Мат. ожидание заменяем на среднее арифмитическое по выборке N_objects.
4) Вычислите разброс метода обучения. Разброс - это среднеквадратичное отклонение предсказания алгоритмов метода $\mu$ на объекте x от среднего предсказания $\mathbb{E}_X [\mu(X)]$ $$ Variance=E_{x,y} (E_{X}(\mathbb{E}_X [\mu(X)] - \mu(X)])^2)$$
Чтобы его вычислить, на выборке N_objects вычислите среднее арифмитическое по N_samples алгоритмам (см. 2) для N_objects объектов.
5) Представьте результаты в виде таблицы, проанализируйте (какой метод дает наименьший разброс, какой наименьшее смещение, почему?, как смещение и разброс связаны с распределением признака x)
1)Загрузите датасет digits с помощью функции load_digits из sklearn.datasets и подготовьте матрицу признаков X и ответы на обучающей выборке y.
2)Для оценки качества далее нужно будет использовать cross_val_score из sklearn.cross_validation с параметром cv=10. Эта функция реализует k-fold cross validation c k равным значению параметра cv. Используйте k=10, чтобы полученные оценки качества имели небольшой разброс. Функция cross_val_score будет возвращать numpy.ndarray, в котором будет k чисел - качество в каждом из k экспериментов k-fold cross validation. Получите среднее значение (которое и будет оценкой качества работы) массива, который возвращает cross_val_score.
3)Воспользуйтесь BaggingClassifier из sklearn.ensemble, чтобы обучить бэггинг над DecisionTreeClassifier. Используйте в BaggingClassifier параметры по умолчанию, задав только количество деревьев равным 100. Качество классификации новой модели - среднее значение cross_val_score . Сравните работу композиции деревьев с одним решающем деревом.
4)Теперь изучите параметры BaggingClassifier и выберите их такими, чтобы каждый базовый алгоритм обучался не на всех d признаках, а на $\sqrt{d}$ случайных признаков. Каково качество работы алгоритма?
5)Наконец, давайте попробуем выбирать случайные признаки не один раз на все дерево, а при построении каждой вершины дерева. Сделать это несложно: нужно убрать выбор случайного подмножества признаков в BaggingClassifier и добавить его в DecisionTreeClassifier. Какой параметр за это отвечает, можно понять из документации sklearn. Попробуйте выбирать опять же $\sqrt{d}$ признаков. Какое теперь качество полученного классификатора?
6)Полученный в пункте 4 классификатор - бэггинг на рандомизированных деревьях (в которых при построении каждой вершины выбирается случайное подмножество признаков и разбиение ищется только по ним). Это в точности соответствует алгоритму Random Forest. Сравнить качество работы классификатора с RandomForestClassifier из sklearn.ensemble.
7)Изучите, как качество классификации на данном датасете зависит от количества деревьев, количества признаков, выбираемых при построении каждой вершины дерева, а также ограничений на глубину дерева. Для наглядности лучше построить графики зависимости качества от значений параметров
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target
print(digits.DESCR)
print(X.shape,'\n', y.shape)
from sklearn import cross_validation
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
cv_score = cross_validation.cross_val_score(model, X, y, cv=10)
print(cv_score.shape)
print(np.mean(cv_score))
from sklearn.ensemble import BaggingClassifier
bag_model = BaggingClassifier(model, n_estimators=100)
cv_score_bag = cross_validation.cross_val_score(bag_model, X, y, cv=10)
print(cv_score_bag.shape)
print(np.mean(cv_score_bag))
bag_model1 = BaggingClassifier(model, n_estimators=100, max_features=int(np.sqrt(X.shape[1])))
cv_score_bag1 = cross_validation.cross_val_score(bag_model1, X, y, cv=10)
print(cv_score_bag1.shape)
print(np.mean(cv_score_bag1))
tree_model = DecisionTreeClassifier(splitter='random', max_features=int(np.sqrt(X.shape[1])))
bag_model2 = BaggingClassifier(tree_model, n_estimators=100, bootstrap=False, max_features=int(np.sqrt(X.shape[1])))
cv_score_bag2 = cross_validation.cross_val_score(bag_model2, X, y, cv=10)
cv_score_tree = cross_validation.cross_val_score(tree_model, X, y, cv=10)
print(np.mean(cv_score_bag2))
print(np.mean(cv_score_tree))
from sklearn.ensemble import RandomForestClassifier
model_rfc = RandomForestClassifier()
cv_score_rfc = cross_validation.cross_val_score(model_rfc, X, y, cv=10)
print(np.mean(cv_score_rfc))
num_trees = np.arange(1, 200, 10)
num_features = np.arange(1, X.shape[1]+1, 1)
depths = np.arange(1, 100, 5)
a = []
nn = 0
for i in num_trees:
nn += 1
print(nn)
temp_tree = DecisionTreeClassifier(splitter='best')
temp_model = BaggingClassifier(temp_tree, n_estimators=i)
temp_score = cross_validation.cross_val_score(temp_model, X, y, cv=10)
a.append(np.mean(temp_score))
plt.plot(num_trees, a)
plt.xlabel("num_trees")
plt.ylabel("Score")
nn = 0
for i in num_features:
nn += 1
print(nn)
temp_tree = DecisionTreeClassifier(splitter='best', max_features=i)
temp_model = BaggingClassifier(temp_tree, max_features=i)
temp_score = cross_validation.cross_val_score(temp_model, X, y, cv=10)
a.append(np.mean(temp_score))
plt.plot(num_features, a[num_trees.shape[0]:])
plt.xlabel("num_features")
plt.ylabel("Score")
nn = 0
b = []
for i in depths:
nn += 1
print(nn)
temp_tree = DecisionTreeClassifier(splitter='best', max_depth=i)
temp_model = BaggingClassifier(temp_tree)
temp_score = cross_validation.cross_val_score(temp_model, X, y, cv=10)
b.append(np.mean(temp_score))
plt.plot(depths, b)
plt.xlabel("depth")
plt.ylabel("Score")