Учитывая набор данных из 920 выборок с 40 признаками в задаче двоичной классификации. Набор данных - это набор данных о заболеваниях сердца, общедоступный здесь: archive.ics.uci.edu/ml/datasets/heart+Disease
Я предварительно обработал набор данных, отбрасывая те функции, которые содержат> 50% пропущенных данных. Те, в которых содержится <50%, я вменял это, используя MICE ncbi.nlm.nih.gov/pmc/articles/PMC3074241. Затем я поместил числовые данные в категориальные данные, собрав значения в равных диапазонах, а затем кодировав функции с помощью OHE. Информация о наборе данных следующая: </p>
Рассмотрены следующие модели:
Линейный SVM, RBF SVM, логистическая регрессия, KNN, дерево решений, случайный лес
Я настроил параметры, используя RandomSearchCV:
> Model: SVC(C=0.1, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=0.1, kernel='linear',
max_iter=-1, probability=True, random_state=None, shrinking=True,
tol=0.001, verbose=False)
> Model: SVC(C=10000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=0.0001, kernel='rbf',
max_iter=-1, probability=True, random_state=None, shrinking=True,
tol=0.001, verbose=False)
> Model: LogisticRegression(C=0.01, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1, penalty='l2', random_state=None, solver='liblinear', tol=0.0001, verbose=0, warm_start=False)
> Model: KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
metric_params=None, n_jobs=1, n_neighbors=65, p=2,
weights='uniform')
> Model: DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
max_features=None, max_leaf_nodes=10,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='random')
> Model: RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=30, max_features='sqrt', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=4, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=400, n_jobs=1,
oob_score=False, random_state=None, verbose=0,
warm_start=False)
Я получил следующие оценки (среднее +/- стандартное) в 10-CV:
Меня удивляет, что точность тренировки и F-показатель выше (особенно в случайном лесу), чем у тестового.
Кроме того, я вычислил алгоритмы пакетирования по той же методике (настраивая число оценщиков с помощью RandomSearchCV и имея base_estimator, рассмотренный предыдущими моделями):
Model: BaggingClassifier(base_estimator=SVC(C=0.1, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=0.1, kernel='linear',
max_iter=-1, probability=True, random_state=None, shrinking=True,
tol=0.001, verbose=False),
bootstrap=True, bootstrap_features=False, max_features=1.0,
max_samples=1.0, n_estimators=200, n_jobs=1, oob_score=False,
random_state=36, verbose=0, warm_start=False)
Model: BaggingClassifier(base_estimator=SVC(C=10000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=0.0001, kernel='rbf',
max_iter=-1, probability=True, random_state=None, shrinking=True,
tol=0.001, verbose=False),
bootstrap=True, bootstrap_features=False, max_features=1.0,
max_samples=1.0, n_estimators=100, n_jobs=1, oob_score=False,
random_state=37, verbose=0, warm_start=False)
Model: BaggingClassifier(base_estimator=LogisticRegression(C=0.01, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False),
bootstrap=True, bootstrap_features=False, max_features=1.0,
max_samples=1.0, n_estimators=100, n_jobs=1, oob_score=False,
random_state=38, verbose=0, warm_start=False)
Model: BaggingClassifier(base_estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
metric_params=None, n_jobs=1, n_neighbors=65, p=2,
weights='uniform'),
bootstrap=True, bootstrap_features=False, max_features=1.0,
max_samples=1.0, n_estimators=100, n_jobs=1, oob_score=False,
random_state=38, verbose=0, warm_start=False)
Model: BaggingClassifier(base_estimator=DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
max_features=None, max_leaf_nodes=10,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='random'),
bootstrap=True, bootstrap_features=False, max_features=1.0,
max_samples=1.0, n_estimators=500, n_jobs=1, oob_score=False,
random_state=34, verbose=0, warm_start=False)
Model: RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=30, max_features='sqrt', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=4, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=400, n_jobs=1,
oob_score=False, random_state=None, verbose=0,
warm_start=False)
Я получил следующие оценки (среднее +/- стандартное) в 10-CV:
Меня также удивляет, что не так много улучшений от отдельных алгоритмов до пакетных алгоритмов.
С другой стороны, я также пробовал AdaBoost с деревом решений и логистической регрессией (та же настройка n_estimators и скорости обучения с помощью Random SearchCV:
Model: AdaBoostClassifier(algorithm='SAMME.R',
base_estimator=LogisticRegression(C=0.01, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False),
learning_rate=10, n_estimators=600, random_state=38)
Model: AdaBoostClassifier(algorithm='SAMME.R',
base_estimator=DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
max_features=None, max_leaf_nodes=10,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='random'),
learning_rate=0.01, n_estimators=200, random_state=34)
Я также получил следующие оценки:
Читая об ансамблевых методах, можно полагать, что его точность улучшается от единичных моделей, однако для логистической регрессии даже ухудшается (чуть-чуть), но, тем не менее, для деревьев решений это не так значительно улучшилось <1%. </p>
Что могло случиться? Я переоснащаюсь?
EDIT:
Как отметил @ Quickbeam2k1, группы с горячим кодированием НЕ имеют одинакового количества точек данных. Другими словами, некоторые группы слишком малы, и поэтому они не отображаются в тестовом наборе, и алгоритм не сможет хорошо обобщить. Смотрите пример:
Кроме того, некоторые функции очень несбалансированы, в некоторых случаях на каждую функцию приходится всего пара сэмплов. Поэтому я считаю, что мне нужно отказаться от некоторых функций OHE. Дело в том, какой порог я должен рассмотреть, чтобы отказаться? Я думаю об отбрасывании тех характеристик, процент которых не достигает 10% меньше, чем пропорциональное равное отношение его значений. Это означает, что если функция, скажем, боль в груди, получила 4 значения, то есть cp_1, cp_2, cp_3, cp_4. Если одно из этих значений OHE получило менее 25% - 10% (поскольку имеется 4 значения, равное соотношение составляет 25% для каждого значения) = 15%. Если функция не достигает 15% сэмплов в этой функции, откажитесь от нее. Это хороший подход?
Кроме того, как сказал @HarisNadeem, алгоритмы пакетирования направлены на уменьшение дисперсии набора данных. Поскольку я OneHotEncoded кодировал функции, я значительно сократил набор данных и, таким образом, он не улучшил алгоритмы.