Проблемы полиномиальной классификации уникальны тем, что вместо классификации x-количества признаков в класс «A» или класс «B» мы классифицируем 3 или более классов. Это приходит с новыми наборами трудностей. В этом примере я буду использовать классификацию случайного леса, обучать 3 функции и классифицировать их по классам от 0 до 4; всего пять классов.
На этот пост меня вдохновило то, что я не смог найти наборы данных или примеры, которые касались бы некоторых проблем, с которыми я столкнулся, особенно с сильно несбалансированным набором данных, с которым я работал, и я хотел объединить все свои выводы и стратегии в один. почта.
Данные
Функции в моем наборе данных — это типы с плавающей запятой от -4,831 до 6,7965.
Признаки 1 и 2 имеют наибольшую корреляцию, а признаки 1 и 3 — наименьшую корреляцию.
Как видно из приведенных выше графиков и подсчетов значений, выходные данные, с которыми я имел дело, были сильно несбалансированными. Это может привести к переобучению данных и ложной высокой точности при создании отчета о классификации.
Техника SMOTE - это обычное использование переобучения классов меньшинства, чтобы попытаться сбалансировать набор данных. Имейте в виду, это может быть опасно использовать с несбалансированным набором данных, таким как мой выше. По сути, это может привести к тому, что ваша модель просто запомнит, как выглядят классы 2, 3 и 4, и точность возрастет. Это не то, чего мы хотим, когда пытаемся классифицировать.
Итак, как нам справиться с этим серьезным дисбалансом классов?
Поиск по сетке
Существуют различные способы сделать это. В частности, для моего набора данных и модели я реализовал:
◦ Поиск по сетке — создав сетку параметров и используя GridSearchCV, я смог найти наиболее оптимизированные гиперпараметры для моего набора данных и модели.
# Example of parameter grid for GridSearchCV parameter_grid = { 'n_estimators': [100, 200, 500, 1000], 'max_features': ['auto', 'sqrt', 'log2', 3], 'max_depth' : [2,4,5,6,7,8,10], 'criterion' :['gini', 'entropy'], 'bootstrap': [True, False] } my_model = RandomForestClassifier() clf = GridSearchCV(my_model, parameter_grid, cv = 10, scoring = 'accuracy', n_jobs = -1, verbose = 1) clf.fit(X_train, y_train) from sklearn import metrics print(clf.best_params_) print(clf.best_score_) # Best Parameters Output: {bootstrap = True, max_features = 16, max_depth = 4, n_estimators = 1000, criterion = 'gini'} # Best Score with Parameters: 0.9414807104745758
Балансировка веса класса с использованием аналогичных методов поиска по сетке
# Weighted Decision Tree to find the best weights balance = [{0:1.0, 1:30.0, 2:50.0, 3:70.0, 4:100.0}, {0:1.0, 1:20.0, 2:40.0, 3:70.0, 4:100.0}, {0:1.0, 1:50.0, 2:70.0, 3:80.0, 4:100.0}, {0:1.0, 1:40.0, 2:50.0, 3:85.0, 4:100.0}, {0:1.0, 1:60.0, 2:70.0, 3:80.0, 4:100.0}] my_model = RandomForestClassifier(bootstrap = True, max_features = 16, max_depth = 4, n_estimators = 1000, criterion = 'gini') weight_grid = dict(class_weight=balance) grid = GridSearchCV(estimator=my_model, param_grid=weight_grid, cv=10, scoring='accuracy', verbose = 1) # report the best configuration grid_result = grid.fit(x, y) print('Best: %f using %s' % (grid_result.best_score_, grid_result.best_params_)) weights = {0: 1.0, 1: 50.0, 2: 70.0, 3: 80.0, 4: 100.0} #best weights outcome from grid searching
Из кривой ROC здесь видно, что мы по-прежнему можем правильно классифицировать большое количество точек данных, даже с сильнонесбалансированным набором данных.
Заключение
Балансировка веса класса с несбалансированными данными может быть сложной задачей в машинном обучении. В зависимости от ваших вариантов использования вы должны определить, как вы будете проверять «хорошесть» вашей модели; то есть точность, F1-скоринг, TPR и далее.
Используя поиск по сетке или методы избыточной / недостаточной выборки, вы можете начать решать свою уникальную проблему классификации.