Monday, July 11, 2022

Develop Voting Ensembles With Python

 Классификатор голосования — это модель машинного обучения, которая обучается на ансамбле многочисленных моделей и прогнозирует результат (класс) на основе их наивысшей вероятности выбора класса в качестве результата.Он просто объединяет результаты каждого классификатора, переданного в классификатор голосования, и прогнозирует выходной класс на основе наибольшего большинства голосов. Идея состоит в том, чтобы вместо создания отдельных выделенных моделей и определения точности для каждой из них мы создали единую модель, которая обучается по этим моделям и прогнозирует результат на основе их совокупного большинства голосов для каждого класса вывода.

Классификатор голосования поддерживает два типа голосования.

Жесткое голосование: при жестком голосовании прогнозируемый выходной класс — это класс с наибольшим большинством голосов, то есть класс, который имел наибольшую вероятность быть предсказанным каждым из классификаторов. Предположим, что три классификатора предсказали выходной класс (A, A, B), поэтому здесь большинство предсказало A как выход. Следовательно, A будет окончательным прогнозом.

Мягкое голосование: при мягком голосовании выходной класс представляет собой прогноз, основанный на средней вероятности, данной этому классу. Предположим, что при вводе данных для трех моделей вероятность прогноза для класса A = (0,30, 0,47, 0,53) и B = (0,20, 0,32, 0,40). Таким образом, среднее значение для класса A составляет 0,4333, а для класса B — 0,3067. Очевидно, что победителем является класс A, поскольку он имеет самую высокую вероятность, усредненную по каждому классификатору.

====================

В общем случае присутсвия веса у каждого классификатора:

====================

Классификатор голосования можно рассматривать как более сильный метаклассификатор, который уравновешивает слабые стороны отдельных классификаторов в конкретном наборе данных.

Классификатор голосования — это групповой классификатор, который принимает входные данные в виде двух или более оценщиков и классифицирует данные на основе голосования большинства.

Классификатор жесткого голосования классифицирует данные на основе меток классов и весов, связанных с каждым классификатором.

Классификатор мягкого голосования классифицирует данные на основе вероятностей и весов, связанных с каждым классификатором.

=============================================

Ансамбль мягкого голосования для классификации

Мы можем продемонстрировать мягкое голосование с помощью алгоритма машины опорных векторов (SVM). Алгоритм SVM изначально не предсказывает вероятности, хотя его можно настроить для предсказания вероятностных оценок, установив для аргумента «вероятность» значение «Истина» в классе SVC. Мы можем подобрать пять различных версий алгоритма SVM с полиномиальным ядром, каждая из которых имеет разную полиномиальную степень, заданную с помощью аргумента «степень». Будем использовать степени 1-5. Мы ожидаем, что путем объединения предсказанных оценок вероятности членства в классе, предсказанных каждой отдельной моделью SVM, ансамбль мягкого голосования в среднем достигнет более высокой прогностической эффективности, чем любая автономная модель, используемая в ансамбле.

(.env) boris@boris-All-Series:~/VOTINGCLASS$ cat SoftVotingCLS.py

# compare soft voting ensemble to standalone classifiers

from numpy import mean

from numpy import std

from sklearn.datasets import make_classification

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.svm import SVC

from sklearn.ensemble import VotingClassifier

from matplotlib import pyplot

 # get the dataset

def get_dataset():

X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=2)

return X, y

 # get a voting ensemble of models

def get_voting():

# define the base models

models = list()

models.append(('svm1', SVC(probability=True, kernel='poly', degree=1)))

models.append(('svm2', SVC(probability=True, kernel='poly', degree=2)))

models.append(('svm3', SVC(probability=True, kernel='poly', degree=3)))

models.append(('svm4', SVC(probability=True, kernel='poly', degree=4)))

models.append(('svm5', SVC(probability=True, kernel='poly', degree=5)))

# define the voting ensemble

ensemble = VotingClassifier(estimators=models, voting='soft')

return ensemble

 # get a list of models to evaluate

def get_models():

models = dict()

models['svm1'] = SVC(probability=True, kernel='poly', degree=1)

models['svm2'] = SVC(probability=True, kernel='poly', degree=2)

models['svm3'] = SVC(probability=True, kernel='poly', degree=3)

models['svm4'] = SVC(probability=True, kernel='poly', degree=4)

models['svm5'] = SVC(probability=True, kernel='poly', degree=5)

models['soft_voting'] = get_voting()

return models

 # evaluate a give model using cross-validation

def evaluate_model(model, X, y):

cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)

scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')

return scores

 # define dataset

X, y = get_dataset()

# get the models to evaluate

models = get_models()

# evaluate the models and store results

results, names = list(), list()

for name, model in models.items():

scores = evaluate_model(model, X, y)

results.append(scores)

names.append(name)

print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))

# plot model performance for comparison

pyplot.boxplot(results, labels=names, showmeans=True)

pyplot.show()

















Ансамбль жесткого голосования для классификации

Мы можем продемонстрировать жесткое голосование с помощью алгоритма k-ближайших соседей. Мы можем подобрать пять разных версий алгоритма KNN, каждая из которых имеет разное количество соседей, используемых при прогнозировании. Мы будем использовать 1, 3, 5, 7 и 9 соседей (нечетные числа, чтобы избежать ничьи). Мы ожидаем, что путем объединения предсказанных меток классов, предсказанных каждой отдельной моделью KNN, ансамбль жесткого голосования достигнет в среднем лучших прогнозирующих характеристик, чем любая автономная модель, используемая в ансамбле.

(.env) boris@boris-All-Series:~/VOTINGCLASS$ cat HardVotingCLS.py

# compare hard voting to standalone classifiers

from numpy import mean

from numpy import std

from sklearn.datasets import make_classification

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import RepeatedStratifiedKFold

from sklearn.neighbors import KNeighborsClassifier

from sklearn.ensemble import VotingClassifier

from matplotlib import pyplot

 

# get the dataset

def get_dataset():

X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=2)

return X, y

 

# get a voting ensemble of models

def get_voting():

# define the base models

models = list()

models.append(('knn1', KNeighborsClassifier(n_neighbors=1)))

models.append(('knn3', KNeighborsClassifier(n_neighbors=3)))

models.append(('knn5', KNeighborsClassifier(n_neighbors=5)))

models.append(('knn7', KNeighborsClassifier(n_neighbors=7)))

models.append(('knn9', KNeighborsClassifier(n_neighbors=9)))

# define the voting ensemble

ensemble = VotingClassifier(estimators=models, voting='hard')

return ensemble

 

# get a list of models to evaluate

def get_models():

models = dict()

models['knn1'] = KNeighborsClassifier(n_neighbors=1)

models['knn3'] = KNeighborsClassifier(n_neighbors=3)

models['knn5'] = KNeighborsClassifier(n_neighbors=5)

models['knn7'] = KNeighborsClassifier(n_neighbors=7)

models['knn9'] = KNeighborsClassifier(n_neighbors=9)

models['hard_voting'] = get_voting()

return models

 

# evaluate a give model using cross-validation

def evaluate_model(model, X, y):

cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)

scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')

return scores

 

# define dataset

X, y = get_dataset()

# get the models to evaluate

models = get_models()

# evaluate the models and store results

results, names = list(), list()

for name, model in models.items():

scores = evaluate_model(model, X, y)

results.append(scores)

names.append(name)

print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))

# plot model performance for comparison

pyplot.boxplot(results, labels=names, showmeans=True)

pyplot.show()



























===============================

Plot the decision boundaries of a VotingClassifier

===============================

Сначала инициализируются три примерных классификатора (DecisionTreeClassifier, KNeighborsClassifier и SVC) и используются для инициализации мягкого голосования VotingClassifier с весами [2, 1, 2], что означает, что предсказанные вероятности DecisionTreeClassifier и SVC считаются в 2 раза больше, чем каждый. столько же, сколько веса классификатора KNeighborsClassifier при расчете усредненной вероятности.

(.env) boris@boris-All-Series:~/VOTINGCLASS$ cat plot_voting_decision_regions.py

from itertools import product

import matplotlib.pyplot as plt

from sklearn import datasets

from sklearn.tree import DecisionTreeClassifier

from sklearn.neighbors import KNeighborsClassifier

from sklearn.svm import SVC

from sklearn.ensemble import VotingClassifier

from sklearn.inspection import DecisionBoundaryDisplay

# Loading some example data

iris = datasets.load_iris()

X = iris.data[:, [0, 2]]

y = iris.target

# Training classifiers

clf1 = DecisionTreeClassifier(max_depth=4)

clf2 = KNeighborsClassifier(n_neighbors=7)

clf3 = SVC(gamma=0.1, kernel="rbf", probability=True)

eclf = VotingClassifier(

    estimators=[("dt", clf1), ("knn", clf2), ("svc", clf3)],

    voting="soft",

    weights=[2, 1, 2],

)

clf1.fit(X, y)

clf2.fit(X, y)

clf3.fit(X, y)

eclf.fit(X, y)

# Plotting decision regions

f, axarr = plt.subplots(2, 2, sharex="col", sharey="row", figsize=(10, 8))

for idx, clf, tt in zip(

    product([0, 1], [0, 1]),

    [clf1, clf2, clf3, eclf],

    ["Decision Tree (depth=4)", "KNN (k=7)", "Kernel SVM", "Soft Voting"],

):

    DecisionBoundaryDisplay.from_estimator(

        clf, X, alpha=0.4, ax=axarr[idx[0], idx[1]], response_method="predict"

    )

    axarr[idx[0], idx[1]].scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor="k")

    axarr[idx[0], idx[1]].set_title(tt)

plt.show()































No comments:

Post a Comment