<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:  Загрузка датасета digits с помощью функции load_digits из sklearn.datasets и подготовка матрицы признаков X и ответов на обучающей выборке y (потребуются поля data и target в объекте, который возвращает load_digits).
Step2:  Для оценки качества далее нужно использовать cross_val_score из sklearn.cross_validation с параметром cv=10. Эта функция реализует k-fold cross validation c k равным значению параметра cv. Предлагается использовать k=10, чтобы полученные оценки качества имели небольшой разброс, и было проще проверить полученные ответы. На практике же часто хватает и k=5. Функция cross_val_score будет возвращать numpy.ndarray, в котором будет k чисел - качество в каждом из k экспериментов k-fold cross validation. Для получения среднего значения (которое и будет оценкой качества работы) вызовите метод .mean() у массива, который возвращает cross_val_score.
С небольшой вероятностью можно натолкнуться на случай, когда полученное качество в каком-то из пунктов не попадет в диапазон, заданный для правильных ответов - в этом случае необходимо попробовать перезапустить ячейку с cross_val_score несколько раз и выбрать наиболее «типичное» значение.
Если захочется ускорить вычисление cross_val_score - можно попробовать использовать параметр n_jobs, но нужно быть осторожным
Step3:  2.
Воспользуемся BaggingClassifier из sklearn.ensemble, чтобы обучить бэггинг над DecisionTreeClassifier. Используем в BaggingClassifier параметры по умолчанию, задав только количество деревьев равным 100.
Качество классификации новой модели - ответ в пункте 2. Обратите внимание, как соотносится качество работы композиции решающих деревьев с качеством работы одного решающего дерева.
Step4:  3.
Теперь изучим параметры BaggingClassifier и выберем их такими, чтобы каждый базовый алгоритм обучался не на всех d признаках, а на sqrt(d) случайных признаков. Качество работы получившегося классификатора - ответ в пункте 3. Корень из числа признаков - часто используемая эвристика в задачах классификации, в задачах регрессии же часто берут число признаков, деленное на три. Но в общем случае ничто не мешает вам выбирать любое другое число случайных признаков.
Step5:  4.
Наконец, попробуем выбрать случайные признаки не один раз на все дерево, а при построении каждой вершины дерева. Сделать это несложно
Step6:  5.
Полученный в пункте 4 классификатор - бэггинг на рандомизированных деревьях (в которых при построении каждой вершины выбирается случайное подмножество признаков и разбиение ищется только по ним). Это в точности соответствует алгоритму Random Forest, поэтому почему бы не сравнить качество работы классификатора с RandomForestClassifier из sklearn.ensemble. Затем изучите, как качество классификации на данном датасете зависит от количества деревьев, количества признаков, выбираемых при построении каждой вершины дерева, а также ограничений на глубину дерева. Для наглядности лучше построить графики зависимости качества от значений параметров, но для сдачи задания это делать не обязательно.
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import cross_val_score, validation_curve
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier, RandomForestClassifier
import numpy as np
import seaborn as sns
Explanation: Бэггинг и случайный лес
End of explanation
digits = load_digits()
print(digits.data.shape)
print(digits.DESCR)
plt.gray()
plt.plot(digits.images[0])
plt.show()
X = digits.data
y = digits.target
Explanation: Загрузка датасета digits с помощью функции load_digits из sklearn.datasets и подготовка матрицы признаков X и ответов на обучающей выборке y (потребуются поля data и target в объекте, который возвращает load_digits).
End of explanation
dt_classifier = DecisionTreeClassifier()
cvs = cross_val_score(dt_classifier, X, y, cv=10)
print(cvs)
print('Mean model quality value: ' + str(cvs.mean()))
with open("answer1.txt", "w") as fout:
    fout.write(str(cvs.mean()))
Explanation: Для оценки качества далее нужно использовать cross_val_score из sklearn.cross_validation с параметром cv=10. Эта функция реализует k-fold cross validation c k равным значению параметра cv. Предлагается использовать k=10, чтобы полученные оценки качества имели небольшой разброс, и было проще проверить полученные ответы. На практике же часто хватает и k=5. Функция cross_val_score будет возвращать numpy.ndarray, в котором будет k чисел - качество в каждом из k экспериментов k-fold cross validation. Для получения среднего значения (которое и будет оценкой качества работы) вызовите метод .mean() у массива, который возвращает cross_val_score.
С небольшой вероятностью можно натолкнуться на случай, когда полученное качество в каком-то из пунктов не попадет в диапазон, заданный для правильных ответов - в этом случае необходимо попробовать перезапустить ячейку с cross_val_score несколько раз и выбрать наиболее «типичное» значение.
Если захочется ускорить вычисление cross_val_score - можно попробовать использовать параметр n_jobs, но нужно быть осторожным: в одной из старых версий sklearn была ошибка, которая приводила к неверному результату работы cross_val_score при задании n_jobs отличным от 1. Сейчас такой проблемы возникнуть не должно, но проверить, что все в порядке, не будет лишним.
1.
Создадим DecisionTreeClassifier с настройками по умолчанию и измерим качество его работы с помощью cross_val_score. Эта величина и будет ответом в пункте 1.
End of explanation
bagging = BaggingClassifier(dt_classifier, n_estimators=100)
cvs = cross_val_score(bagging, X, y, cv=10)
print(cvs)
print('Mean model quality value: ' + str(cvs.mean()))
with open("answer2.txt", "w") as fout:
    fout.write(str(cvs.mean()))
Explanation: 2.
Воспользуемся BaggingClassifier из sklearn.ensemble, чтобы обучить бэггинг над DecisionTreeClassifier. Используем в BaggingClassifier параметры по умолчанию, задав только количество деревьев равным 100.
Качество классификации новой модели - ответ в пункте 2. Обратите внимание, как соотносится качество работы композиции решающих деревьев с качеством работы одного решающего дерева.
End of explanation
n_features = digits.data.shape[1]
bagging = BaggingClassifier(dt_classifier, n_estimators=100, max_features=int(np.sqrt(n_features)))
cvs = cross_val_score(bagging, X, y, cv=10)
print(cvs)
print('Mean model quality value: ' + str(cvs.mean()))
with open("answer3.txt", "w") as fout:
    fout.write(str(cvs.mean()))
Explanation: 3.
Теперь изучим параметры BaggingClassifier и выберем их такими, чтобы каждый базовый алгоритм обучался не на всех d признаках, а на sqrt(d) случайных признаков. Качество работы получившегося классификатора - ответ в пункте 3. Корень из числа признаков - часто используемая эвристика в задачах классификации, в задачах регрессии же часто берут число признаков, деленное на три. Но в общем случае ничто не мешает вам выбирать любое другое число случайных признаков.
End of explanation
dt_classifier = DecisionTreeClassifier(max_features=int(np.sqrt(n_features)))
bagging = BaggingClassifier(dt_classifier, n_estimators=100)
cvs = cross_val_score(bagging, X, y, cv=10)
print(cvs)
print('Mean model quality value: ' + str(cvs.mean()))
with open("answer4.txt", "w") as fout:
    fout.write(str(cvs.mean()))
Explanation: 4.
Наконец, попробуем выбрать случайные признаки не один раз на все дерево, а при построении каждой вершины дерева. Сделать это несложно: нужно убрать выбор случайного подмножества признаков в BaggingClassifier и добавить его в DecisionTreeClassifier. Будем выбирать опять же sqrt(d) признаков. Качество полученного классификатора на контрольной выборке и будет ответом в пункте 4.
End of explanation
rf_classifier = RandomForestClassifier()
bagging = BaggingClassifier(rf_classifier, n_estimators=100)
cvs = cross_val_score(bagging, X, y, cv=10)
print(cvs)
print('Mean model quality value: ' + str(cvs.mean()))
with open("answer5.txt", "w") as fout:
    answer = str(2) + ' ' + str(3) + ' ' + str(4) + ' ' + str(7)
    fout.write(answer)
param_range = np.array([10, 50, 100, 150])
train_scores, test_scores = validation_curve(bagging, X, y, param_name="n_estimators", param_range=param_range, cv=10, scoring="accuracy")
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
print(train_scores_mean, test_scores_mean)
param_range = np.array([5, 10, 20, 40])
train_scores, test_scores = validation_curve(bagging, X, y, param_name="max_features", param_range=param_range, cv=10, scoring="accuracy")
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
print(train_scores_mean, test_scores_mean)
param_range = np.array([5, 10, 50, 100])
train_scores, test_scores = validation_curve(bagging, X, y, param_name="base_estimator__max_depth", param_range=param_range, cv=10, scoring="accuracy")
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
print(train_scores_mean, test_scores_mean)
Explanation: 5.
Полученный в пункте 4 классификатор - бэггинг на рандомизированных деревьях (в которых при построении каждой вершины выбирается случайное подмножество признаков и разбиение ищется только по ним). Это в точности соответствует алгоритму Random Forest, поэтому почему бы не сравнить качество работы классификатора с RandomForestClassifier из sklearn.ensemble. Затем изучите, как качество классификации на данном датасете зависит от количества деревьев, количества признаков, выбираемых при построении каждой вершины дерева, а также ограничений на глубину дерева. Для наглядности лучше построить графики зависимости качества от значений параметров, но для сдачи задания это делать не обязательно.
End of explanation
<END_TASK>