Сравнение производительности методов машинного обучения (ML) для данной задачи и выбор окончательного метода - обычная операция в прикладном машинном обучении.

Цель этого поста - сначала продемонстрировать, почему нам нужно использовать статистические методы для выбора окончательной модели. Затем объясняется, почему один из часто используемых тестов статистических гипотез (т. Е. Парный t-критерий Стьюдента) неадекватен для сравнения производительности моделей машинного обучения. Наконец, этот пост демонстрирует, как скорректированную версию парного t-критерия Стьюдента можно применить для изучения производительности моделей машинного обучения.

На следующем рисунке показана эффективность десяти различных моделей классификации с точки зрения F-балла, обученного с использованием определенного набора данных.

Производительность моделей измеряется с использованием тестового или невидимого набора данных. Кроме того, они обучаются с помощью перекрестной проверки в K-кратном порядке, которая случайным образом разделяет набор данных на разные складки, как показано на следующем рисунке.

Из рисунка видно, что QDA работает намного лучше, чем другие модели классификации для этого конкретного набора данных. Может возникнуть вопрос: «предоставляют ли результаты статистически убедительные доказательства того, что QDA превосходит другие прикладные модели машинного обучения?». Фактически, нам нужно оценить, являются ли различия между производительностью моделей машинного обучения истинными и надежными или они вызваны статистической случайностью.

Прежде чем ответить на вышеуказанный вопрос, нам нужно знать, что на практике у нас часто есть один набор данных размера N, и все оценки должны быть получены из этого одного набора данных. Обычно обычно получают различные обучающие наборы путем подвыборки и используют экземпляры, не выбранные для обучения, для тестирования. Производительность классификаторов может измениться при использовании разных подвыборок данных для тестирования и обучения. Другими словами, производительность модели машинного обучения очень чувствительна к конкретному случайному разделению, используемому в процессе обучения. На следующем рисунке показано, что производительность модели машинного обучения может измениться при использовании разных подмножеств обучения и тестирования.

Чтобы понять, как изменение обучающих наборов и наборов тестов может повлиять на производительность модели, мы рассмотрим очень простой пример с набором данных Диабет индейцев пима. Цель набора данных - диагностически предсказать, есть ли у пациента диабет, на основе определенных диагностических измерений, включенных в набор данных. Мы используем две разные модели машинного обучения, включая случайный лес и машину опорных векторов (SVM), чтобы обучать модели предсказывать, есть ли у человека диабет или нет. Мы обучили модели два раза, и каждый раз мы использовали другую подвыборку данных в качестве обучающего набора (это можно сделать, изменив начальное число или random_state). Кроме того, мы использовали те наблюдения, которые не были выбраны для обучения, в качестве тестового набора данных.

#Import required libraries
#import kaggle
import random
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import model_selection, svm
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.model_selection import RandomizedSearchCV
import warnings
warnings.filterwarnings("ignore")
# To download the dataset
!kaggle datasets download -d uciml/pima-indians-diabetes-database
#To read the dataset
df_pima = pd.read_csv('pima-indians-diabetes-database.zip')
X = df_pima.drop('Outcome', axis=1)
y = df_pima['Outcome']
RFC_score = []
SVM_score = []
for random_state in [42, 193]:
    # Splitting the dataset into train and test set
    #random_state = random.randint(100, 10000)
    #print(random_state)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state= random_state)
    
    # number of trees in random forest
    n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
    # number of features at every split
    max_features = ['auto', 'sqrt']
# max depth
    max_depth = [int(x) for x in np.linspace(100, 500, num = 11)]
    max_depth.append(None)
    # create random grid
    random_grid = {
     'n_estimators': n_estimators,
     'max_features': max_features,
     'max_depth': max_depth
     }
    # Random search of parameters
    rfc_random = RandomizedSearchCV(estimator = RandomForestClassifier(), param_distributions = random_grid, 
                                    n_iter = 100, cv = 3, verbose=0, random_state=42, n_jobs = -1)
    # Fit the model
    rfc_random.fit(X_train, y_train)
# print results
    best_params = rfc_random.best_params_
rfc = RandomForestClassifier(n_estimators=best_params['n_estimators'], 
                                 max_depth=best_params['max_depth'],
                                 max_features=best_params['max_features'], 
                                 random_state=42).fit(X_train,y_train);
    RFC_score.append(rfc.score(X_test, y_test))
    
    
    ##Train SVM 
    random_grid_svm = {
    'C': [0.001, 0.01, 0.1, 1, 10],
    'gamma': [0.001, 0.01, 0.1, 1]}
    svm_random = RandomizedSearchCV(estimator = svm.SVC(kernel='rbf'),
                                    param_distributions = random_grid_svm, 
                                    n_iter = 100, cv = 3, verbose=0,
                                    random_state=42, n_jobs = -1)
    svm_random.fit(X_train, y_train)
    
    best_params = svm_random.best_params_
    
    SVM_model = svm.SVC(kernel='rbf',C = best_params['C'],
              gamma=best_params['gamma'], random_state=42).fit(X_train,y_train);
    
    SVM_score.append(SVM_model.score(X_test, y_test))
    
    #print('Iteration {}'.format(i))
    print('The accuracy of SVM model is {}'.format(round(SVM_model.score(X_test, y_test),2)*100))
    print('The accuracy of Random Forest model is {}'.format(round(rfc.score(X_test, y_test),2)*100))
    print('-'*30)

Мы видим, что впервые метод случайного леса работает лучше, чем SVM; в то время как SVM показывает лучшую производительность на второй итерации. Это означает, что использование разницы в характеристиках моделей, полученных только с использованием одной итерации, не будет подходящим способом выбора окончательной модели. Кроме того, мы не знаем распределение, лежащее в основе домена, и, следовательно, не можем точно вычислить разницу. Следовательно, нам необходимо оценить распределение различий. Распределение различий позволяет нам проверить, является ли расчетная разница «истинной» разницей или просто случайной. Для ответа на вопрос мы можем использовать статистический тест.

Чтобы выполнить статистический тест, нам также необходимо иметь среднее значение и дисперсию различий на разных итерациях. Получить объективную оценку среднего и дисперсии различий легко, если имеется достаточный объем данных. Для этого мы можем выбрать несколько обучающих и тестовых наборов из основного набора данных. Затем мы должны обучить модели машинного обучения на каждом из обучающих наборов и измерить производительность моделей, используя подмножества контрольных тестов. Затем мы можем вычислить разницу в производительности моделей для каждой пары классификаторов.

Давайте реализуем это на нашем примере. Мы повторили процесс обучения моделей машинного обучения 100 раз, чтобы увидеть влияние случайного разделения набора данных на производительность моделей. На следующем рисунке сравнивается точность моделей случайного леса и SVM.

Статистические проверки гипотез

Имея вышеуказанную информацию, теперь мы можем использовать статистическую проверку гипотез, чтобы выбрать окончательную модель. Тесты статистической значимости предназначены для сравнения производительности моделей машинного обучения и количественной оценки вероятности наблюдаемых выборок показателей производительности при условии, что они были взяты из одного и того же распределения. Если это предположение или нулевая гипотеза отклоняется, это говорит о том, что разница в оценке навыков статистически значима.

Наиболее распространенным тестом статистической гипотезы, используемым для сравнения производительности моделей машинного обучения, является парный t-критерий Стьюдента, объединенный с помощью случайных подвыборок обучающего набора данных. Нулевая гипотеза в этом тесте заключается в том, что нет разницы между производительностью двух применяемых моделей машинного обучения. Другими словами, нулевая гипотеза предполагает, что обе модели машинного обучения работают одинаково. С другой стороны, альтернативная гипотеза предполагает, что две применяемые модели машинного обучения работают по-разному.

Хотя парный t-критерий Стьюдента является очень распространенным способом сравнения производительности двух разных моделей машинного обучения, нам необходимо проверить допущения, лежащие в основе этого теста, перед его использованием. Ключевое предположение заключается в том, что данные, используемые для проведения парного t-критерия Стьюдента, должны отбираться независимо от двух сравниваемых популяций. Это предположение, как правило, невозможно проверить на основе данных. Однако, если известно, что данные подвергаются зависимой выборке, то парный t-критерий Стьюдента может дать вводящие в заблуждение результаты. Основным следствием нарушения этого предположения является высокая ошибка I типа (т. Е. Отклонение истинной нулевой гипотезы).

В случае сравнения производительности моделей машинного обучения, как упоминалось выше, тестовые и обучающие наборы обычно получаются из разных подвыборок исходных данных. Тестовые и обучающие наборы перекрываются в разных итерациях и, следовательно, не являются независимыми. Это нарушает предположение о независимости, необходимое для надлежащего тестирования значимости, поскольку мы повторно используем данные для получения различий. Следствием нарушения предположения о независимости является то, что ошибка типа I превышает уровень значимости. Следовательно, если мы воспользуемся этим тестом, мы можем обнаружить «значительную» разницу между производительностью двух моделей машинного обучения, хотя ее нет.

В целом, парный t-критерий Стьюдента не подходит для сравнения производительности двух моделей машинного обучения.

Надо и Бенжио показали, что нарушение t-критерия независимости может привести к недооценке дисперсии различий. Чтобы решить эту проблему с помощью парного критерия Стьюдента, они предлагают скорректировать оценку дисперсии, приняв во внимание эту зависимость. На следующем рисунке показано, как мы можем изменить оценку дисперсии, используя метод, предложенный Надо и Бенжио, и вычислить P-значение.

Вычисленная выше статистика t используется с распределением Стьюдента с n-1 степенями свободы для количественной оценки уровня достоверности или значимости разницы между характеристиками моделей. Это позволяет делать более сильные и надежные утверждения в рамках выбора модели, чем при использовании исходного парного t-критерия Стьюдента.

Поскольку нулевая гипотеза состоит в том, что ничего не происходит или нет разницы между производительностью двух моделей машинного обучения, значение P, меньшее, чем рассматриваемый уровень значимости, отвергает нулевую гипотезу в пользу альтернативной гипотезы, которая предполагает модели машинного обучения. выполнять иначе. Кроме того, значение P, превышающее уровни значимости, показывает, что мы не можем отвергнуть нулевую гипотезу.

Мы использовали описанную выше процедуру для сравнения производительности моделей случайного леса и SVM для нашего набора данных тематического исследования.

#Compute the difference between the results
diff = [y - x for y, x in zip(RFC_score, SVM_score)]
#Comopute the mean of differences
d_bar = np.mean(diff)
#compute the variance of differences
sigma2 = np.var(diff)
#compute the number of data points used for training 
n1 = len(y_train)
#compute the number of data points used for testing 
n2 = len(y_test)
#compute the total number of data points
n = len(y)
#compute the modified variance
sigma2_mod = sigma2 * (1/n + n2/n1)
#compute the t_static
t_static =  d_bar / np.sqrt(sigma2_mod)
from scipy.stats import t
#Compute p-value and plot the results 
Pvalue = ((1 - t.cdf(t_static, n-1))*200)
Pvalue

P-значение для настоящего тематического исследования составляет около 1,85%, что меньше, чем рассматриваемый уровень значимости (т.е. 5%), показывая, что мы можем отклонить нулевую гипотезу. Таким образом, результаты статистически убедительно доказывают, что случайный лес и SVM работают по-разному. В среднем средняя точность для модели случайного леса на 4% больше, чем для модели SVM.