Kaggl Titanic: машинное обучение на основе катастроф | Моделирование Часть 2
Перейдите к части 1.
Раньше мы делали следующее
- исследовать набор данных
- предварительная разработка функций
Однако, чтобы получить представление обо всей статье (части 1 и 2), откройте этот блокнот просмотра и если вы хотите запустить каждую ячейку записной книжки, вы также можете использовать связующее
Или пойти к нему Kaggle-Play репо и запустите связующее для запуска ячейки ноутбука.
Хорошо, пришло время построить модель для нашей задачи прогнозирования выживания.
TL;DR
Здесь мы разделяем наши наборы данных в соответствии с предыдущими суммами и делаем набор тестов и обучаем. Чтобы избежать переобучения события, мы можем создать набор проверки, но это неэффективно. Итак, мы используем К-кратный подходы и использование СтратифицированныйKFold чтобы разделить наборы данных поезда на 10 (по умолчанию).
train = dataset[:len(train)]
test = dataset[len(train):]
test.drop(labels=["Survived"],axis = 1,inplace = True)
Y_train = train["Survived"].astype(int)
X_train = train.drop(labels = ["Survived"],axis = 1)
K_fold = StratifiedKFold(n_splits=10)
Классификатор
Я сравниваю 10 популярных классификаторов и оцениваю среднюю точность каждого из них с помощью стратифицированной процедуры перекрестной проверки kfold.
- КНН
- АдаБуст
- Древо решений
- Случайный лес
- Дополнительные деревья
- Машина опорных векторов
- Повышение градиента
- Логистическая регрессия
- Линейный дискриминантный анализ
- Многослойный перцептон
Оценка с использованием перекрестной проверки
Отличной альтернативой является использование Scikit-Learn’s cross-validation
особенность. Следующее выполняет К-кратный перекрестная проверка; он случайным образом разбивает тренировочный набор на 10 отдельных подмножеств, называемых кратностями, затем обучает и оценивает модели 10 раз, каждый раз выбирая для оценки разные кратности и тренируясь на остальных 9 кратностях.
# Modeling step Test differents algorithms
random_state = 2
models = [] # append all models or predictive models
cv_results = [] # cross validation result
cv_means = [] # cross validation mean value
cv_std = [] # cross validation standard deviation
models.append(KNeighborsClassifier())
models.append(AdaBoostClassifier(DecisionTreeClassifier(random_state=random_state),random_state=random_state,learning_rate=0.1))
models.append(DecisionTreeClassifier(random_state=random_state))
models.append(RandomForestClassifier(random_state=random_state))
models.append(ExtraTreesClassifier(random_state=random_state))
models.append(SVC(random_state=random_state))
models.append(GradientBoostingClassifier(random_state=random_state))
models.append(LogisticRegression(random_state = random_state))
models.append(LinearDiscriminantAnalysis())
models.append(MLPClassifier(random_state=random_state))
for model in models :
cv_results.append(cross_val_score(model, X_train, Y_train,
scoring = "accuracy", cv = K_fold, n_jobs=4))
for cv_result in cv_results:
cv_means.append(cv_result.mean())
cv_std.append(cv_result.std())
cv_frame = pd.DataFrame(
{
"CrossValMeans":cv_means,
"CrossValErrors": cv_std,
"Algorithms":[
"KNeighboors",
"AdaBoost",
"DecisionTree",
"RandomForest",
"ExtraTrees",
"SVC",
"GradientBoosting",
"LogisticRegression",
"LinearDiscriminantAnalysis",
"MultipleLayerPerceptron"]
})
cv_plot = sns.barplot("CrossValMeans","Algorithms", data = cv_frame,
palette="husl", orient = "h", **{'xerr':cv_std})
cv_plot.set_xlabel("Mean Accuracy")
cv_plot = cv_plot.set_title("CV Scores")
Рассмотрим отдельно следующие модели:
- Классификатор ГБС
- Линейный дискриминантный анализ
- Логистическая регрессия
- Случайный лесной классификатор
- Гауссовский наивный байесовский метод
- Поддержка Vectore машины
Начнем с Gradient Boosting Classifier.
# GBC Classifier
GBC_Model = GradientBoostingClassifier()
scores = cross_val_score(GBC_Model, X_train, Y_train, cv = K_fold,
n_jobs = 4, scoring = 'accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.83146067 0.82954545 0.76136364 0.89772727 0.90909091 0.875
0.84090909 0.79545455 0.84090909 0.82954545]
84.11
Далее ЛДА
# Linear Discriminant Analysis
LDA_Model= LinearDiscriminantAnalysis()
scores = cross_val_score(LDA_Model, X_train, Y_train, cv = K_fold,
n_jobs = 4, scoring = 'accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.84269663 0.82954545 0.76136364 0.88636364 0.81818182 0.80681818
0.79545455 0.78409091 0.86363636 0.84090909]
82.29
Классификатор логистической регрессии.
# Logistic Regression
#
Log_Model = LogisticRegression(C=1)
scores = cross_val_score(Log_Model, X_train, Y_train, cv=K_fold,
n_jobs=4, scoring='accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.83146067 0.81818182 0.76136364 0.875 0.81818182 0.77272727
0.79545455 0.79545455 0.84090909 0.84090909]
81.5
Случайный лес обычно представляет собой ансамбль классификатора дерева решений. Он должен работать лучше всех. Посмотрим.
# Random Forest Classifier Model
#
RFC_model = RandomForestClassifier(n_estimators=10)
scores = cross_val_score(RFC_model, X_train, Y_train, cv=K_fold,
n_jobs=4, scoring='accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.79775281 0.88636364 0.73863636 0.80681818 0.86363636 0.79545455
0.82954545 0.76136364 0.84090909 0.82954545]
81.5
Gaussian NB довольно хорошо работает с бинарной классификацией.
# Gaussian Naive Bayes
GNB_Model = GaussianNB()
scores = cross_val_score(GNB_Model, X_train, Y_train, cv=K_fold,
n_jobs=4, scoring='accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.78651685 0.81818182 0.75 0.86363636 0.77272727 0.79545455
0.80681818 0.78409091 0.85227273 0.84090909]
80.71
Машина опорных векторов или SVM в значительной степени многообещающий алгоритм ML. Он также должен хорошо работать.
# Support Vector Machine
SVM_Model = SVC()
scores = cross_val_score(SVM_Model, X_train, Y_train, cv=K_fold,
n_jobs=4, scoring='accuracy')
print(scores)
round(np.mean(scores)*100, 2)
# output
[0.69662921 0.65909091 0.64772727 0.72727273 0.76136364 0.70454545
0.76136364 0.73863636 0.72727273 0.78409091]
72.08
Настройка гиперпараметров
Решил выбрать эту перспективную модель GradientBoosting, линейный дискриминантный анализ, RandomForest, логистическая регрессия а также SVM для ансамблевого моделирования. Итак, теперь нам нужно их настроить.
Одним из способов сделать это было бы возиться с гиперпараметры вручную, пока не найдем отличное сочетание значений гиперпараметров. Это была бы очень утомительная работа, и у нас может не хватить времени на изучение многих комбинаций. Вместо этого мы должны получить Scikit-Learn’s GridSearchCV искать нас. Все, что нам нужно сделать, это указать, с какими гиперпараметрами мы хотим поэкспериментировать и какие значения попробовать, и он оценит все возможные комбинации значений гиперпараметров, используя перекрестную проверку.
Здесь мы выполняем оптимизацию поиска по сетке для GradientBoosting, RandomForest, линейного дискриминантного анализа, логистической регрессии и классификатора SVC.
Настройка гиперпараметров на GBC
# Gradient boosting tunning
GBC = GradientBoostingClassifier()
gb_param_grid = {
'loss' : ["deviance"],
'n_estimators' : [100,200,300],
'learning_rate': [0.1, 0.05, 0.01, 0.001],
'max_depth': [4, 8,16],
'min_samples_leaf': [100,150,250],
'max_features': [0.3, 0.1]
}
gsGBC = GridSearchCV(GBC, param_grid = gb_param_grid, cv=K_fold,
scoring="accuracy", n_jobs= 4, verbose = 1)
gsGBC.fit(X_train,Y_train)
GBC_best = gsGBC.best_estimator_
# Best score
gsGBC.best_score_
#output
Fitting 10 folds for each of 216 candidates, totalling 2160 fits
[Parallel(n_jobs=4)]: Done 42 tasks | elapsed: 2.6s
[Parallel(n_jobs=4)]: Done 626 tasks | elapsed: 12.9s
[Parallel(n_jobs=4)]: Done 1626 tasks | elapsed: 30.5s
[Parallel(n_jobs=4)]: Done 2160 out of 2160 | elapsed: 41.0s finished
0.8365493757094211
Настройка гиперпараметров на RFC
# RFC Parameters tunning
RFC = RandomForestClassifier()
## Search grid for optimal parameters
rf_param_grid = {"max_depth": [None],
"min_samples_split": [2, 6, 20],
"min_samples_leaf": [1, 4, 16],
"n_estimators" :[100,200,300,400],
"criterion": ["gini"]}
gsRFC = GridSearchCV(RFC, param_grid = rf_param_grid, cv=K_fold,
scoring="accuracy", n_jobs= 4, verbose = 1)
gsRFC.fit(X_train,Y_train)
RFC_best = gsRFC.best_estimator_
# Best score
gsRFC.best_score_
# output
Fitting 10 folds for each of 36 candidates, totalling 360 fits
[Parallel(n_jobs=4)]: Done 42 tasks | elapsed: 5.5s
[Parallel(n_jobs=4)]: Done 192 tasks | elapsed: 18.7s
[Parallel(n_jobs=4)]: Done 360 out of 360 | elapsed: 32.5s finished
0.8422247446083996
Настройка гиперпараметров на LR
# LogisticRegression Parameters tunning
LRM = LogisticRegression()
## Search grid for optimal parameters
lr_param_grid = {"penalty" : ["l2"],
"tol" : [0.0001,0.0002,0.0003],
"max_iter": [100,200,300],
"C" :[0.01, 0.1, 1, 10, 100],
"intercept_scaling": [1, 2, 3, 4],
"solver":['liblinear'],
"verbose":[1]}
gsLRM = GridSearchCV(LRM, param_grid = lr_param_grid, cv=K_fold,
scoring="accuracy", n_jobs= 4, verbose = 1)
gsLRM.fit(X_train,Y_train)
LRM_best = gsLRM.best_estimator_
# Best score
gsLRM.best_score_
# output
Fitting 10 folds for each of 180 candidates, totalling 1800 fits
[Parallel(n_jobs=4)]: Done 351 tasks | elapsed: 2.6s
[LibLinear]
[Parallel(n_jobs=4)]: Done 1800 out of 1800 | elapsed: 4.4s finished
0.8240635641316686
Настройка гиперпараметров на LDA
# Linear Discriminant Analysis - Parameter Tuning
LDA = LinearDiscriminantAnalysis()
## Search grid for optimal parameters
lda_param_grid = {"solver" : ["svd"],
"tol" : [0.0001,0.0002,0.0003]}
gsLDA = GridSearchCV(LDA, param_grid = lda_param_grid, cv=K_fold,
scoring="accuracy", n_jobs= 4, verbose = 1)
gsLDA.fit(X_train,Y_train)
LDA_best = gsLDA.best_estimator_
# Best score
gsLDA.best_score_
# output
Fitting 10 folds for each of 3 candidates, totalling 30 fits
[Parallel(n_jobs=4)]: Done 23 out of 30 | elapsed: 1.9s remaining: 0.5s
[Parallel(n_jobs=4)]: Done 30 out of 30 | elapsed: 1.9s finished
0.8229284903518729
Настройка гиперпараметров на SVC
### SVC classifier
SVMC = SVC(probability=True)
svc_param_grid = {'kernel': ['rbf'],
'gamma': [0.0001, 0.001, 0.01, 0.1, 1],
'C': [1, 10, 50, 100, 200, 300]}
gsSVMC = GridSearchCV(SVMC, param_grid = svc_param_grid, cv = K_fold,
scoring="accuracy", n_jobs= -1, verbose = 1)
gsSVMC.fit(X_train,Y_train)
SVMC_best = gsSVMC.best_estimator_
# Best score
gsSVMC.best_score_
# output
Fitting 10 folds for each of 30 candidates, totalling 300 fits
[Parallel(n_jobs=-1)]: Done 50 tasks | elapsed: 3.2s
[Parallel(n_jobs=-1)]: Done 300 out of 300 | elapsed: 17.3s finished
0.8161180476730987
Диагностируйте смещение и дисперсию, чтобы уменьшить ошибку
Кривые обучения — это хороший способ увидеть влияние переобучения и недообучения на тренировочный набор, а также влияние размера обучения на точность. Кривые обучения отображают производительность модели на обучающем наборе и проверочном наборе в зависимости от размера обучающего набора. Чтобы создать графики, мы просто обучаем модель несколько раз на подмножествах обучающих наборов разного размера. В двух словах, кривые обучения показывают, как изменяется ошибка по мере увеличения размера обучающей выборки.
Если модели хорошо работают с обучающими данными, но плохо обобщаются в соответствии с метриками перекрестной проверки, модель называется переоснащением. И снова, если он плохо работает на обоих, модель называется недообученной.
Когда модель обучается на очень небольшом количестве тренировочных экземпляров, она не способна правильно обобщать, поэтому ошибка валидации изначально будет довольно большой.
Недооснащение: если модель не соответствует обучающим данным, добавление дополнительного обучающего примера не поможет. Нам нужно использовать более сложную модель или придумать лучшие функции.
Переоснащение: Один из способов улучшить модель переобучения — снабжать ее дополнительными обучающими данными до тех пор, пока ошибка проверки не достигнет ошибки обучения.
Ресурс:
Компромисс смещения и дисперсии
Ошибка обобщения модели может быть выражена как сумма трех очень разных ошибок.
- Предвзятость
- Дисперсия
- Неустранимая ошибка
Ошибка смещения в кривой обучения
Эта часть ошибки обобщения связана с неправильным предположением, например, с предположением, что данные являются линейными, тогда как на самом деле они квадратичны.
- Модель с высоким смещением, скорее всего, не соответствует обучающим данным.
Ошибка дисперсии в кривой обучения
Эта часть обобщения связана с чрезмерной чувствительностью модели к небольшим изменениям обучающих данных.
- Модель с высокой дисперсией, скорее всего, будет соответствовать обучающим данным.
Неустранимая ошибка в кривой обучения
Это связано с зашумленностью самих данных. Это не проблема сейчас, потому что мы уже чистим наборы данных
Увеличение сложности модели обычно увеличивает ее дисперсию и уменьшает смещение. И наоборот, уменьшение сложности модели увеличивает ее смещение и уменьшает ее дисперсию.
Теперь мы определим функцию построения кривой обучения, где оси x и y будут постепенно изменять размер набора и оценки (не ошибки). Таким образом, чем выше оценка, тем лучше производительность модели.
# Plot learning curve
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5)):
"""
Generate a simple plot of the test and traning learning curve.
Parameters
----------
estimator : object type that implements the "fit" and "predict" methods
An object of that type which is cloned for each validation.
title : string
Title for the chart.
X : array-like, shape (n_samples, n_features)
Training vector, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape (n_samples) or (n_samples, n_features), optional
Target relative to X for classification or regression;
None for unsupervised learning.
ylim : tuple, shape (ymin, ymax), optional
Defines minimum and maximum yvalues plotted.
cv : integer, cross-validation generator, optional
If an integer is passed, it is the number of folds (defaults to 3).
Specific cross-validation objects can be passed, see
sklearn.cross_validation module for the list of possible objects
n_jobs : integer, optional
Number of jobs to run in parallel (default 1).
x1 = np.linspace(0, 10, 8, endpoint=True) produces
8 evenly spaced points in the range 0 to 10
"""
plt.figure()
plt.title(title)
if ylim is not None:
plt.ylim(*ylim)
plt.xlabel("Training examples")
plt.ylabel("Score")
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
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)
plt.grid()
plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
train_scores_mean + train_scores_std, alpha=0.1,
color="r")
plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
test_scores_mean + test_scores_std, alpha=0.1, color="g")
plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
label="Training score")
plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
label="Cross-validation score")
plt.legend(loc="best")
return plt
# Gradient boosting - Learning Curve
plot_learning_curve(estimator = gsGBC.best_estimator_,title = "GBC learning curve",
X = X_train, y = Y_train, cv = K_fold);
# Random Forest - Learning Curve
plot_learning_curve(estimator = gsRFC.best_estimator_ ,title = "RF learninc curve",
X = X_train, y = Y_train, cv = K_fold);
# Logistic Regression - Learning Curve gsLRM.best_estimator_
plot_learning_curve(estimator = Log_Model ,title = "Logistic Regression - Learning Curve",
X = X_train, y = Y_train, cv = K_fold);
# Linear Discriminant Analysis - Learning Curve
plot_learning_curve(estimator = gsLDA.best_estimator_ ,title = "Linear Discriminant - Learning Curve",
X = X_train, y = Y_train, cv = K_fold);
# Support Vector Machine - Learning Curve
plot_learning_curve(estimator = gsSVMC.best_estimator_,title = "SVC learning curve",
X = X_train, y = Y_train, cv = K_fold);
SVC, кажется, лучше обобщает прогноз, поскольку кривые обучения и перекрестной проверки близки друг к другу. И снова классификаторы Random Forest и GradientBoosting имеют тенденцию превосходить тренировочный набор. Один из способов улучшить модель переобучения — снабжать ее дополнительными обучающими данными до тех пор, пока ошибка проверки не достигнет ошибки обучения.
Еще один способ тонкой настройки нашей системы — попытаться объединить модели, которые работают лучше всего. Группа часто будет работать лучше, чем лучшая отдельная модель, особенно если отдельные модели допускают очень разные типы ошибок.
Построение модели поверх многих других моделей называется ансамблевое обучение. И часто это отличный способ продвинуть алгоритм ML еще дальше.
Я использую классификатор голосования, чтобы объединить прогнозы, полученные от двух классификаторов. Я предпочел передать аргумент soft параметру голосования, чтобы учесть вероятность каждого голоса.
#about 84%
VotingPredictor = VotingClassifier(estimators =
[('rfc', RFC_best),
('gbc', GBC_best)],
voting='soft', n_jobs = 4)
VotingPredictor = VotingPredictor.fit(X_train, Y_train)
scores = cross_val_score(VotingPredictor, X_train, Y_train, cv = K_fold,
n_jobs = 4, scoring = 'accuracy')
print(scores)
print(round(np.mean(scores)*100, 2))
# output
[0.79775281 0.84090909 0.72727273 0.90909091 0.90909091 0.85227273
0.85227273 0.77272727 0.88636364 0.84090909]
83.89 # score increased
Отправить предиктор
Predictive_Model = pd.DataFrame({
"PassengerId": TestPassengerID,
"Survived": VotingPredictor.predict(test)})
Predictive_Model.to_csv('titanic_model.csv', index=False)
Таким образом, мы доходим до конца этой серии. Вы можете найти Часть 1 отсюда. Однако вы можете запустить каждую ячейку записной книжки, поэтому используйте связующееэто потрясающе.
Вы можете получить исходный код всей демонстрации (части 1 и 2) по ссылке ниже, а также можете подписаться на меня в Гитхаб для будущих обновлений кода. Исходный код : Титаник:МЛ
Передай привет: электронная почта | LinkedIn | Куора | Гитхаб | Середина | Твиттер | Инстаграм