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

Почему мы обучаем и тестируем несколько моделей с разными параметрами

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

Это может выглядеть примерно так

logisticRegression = LogisticRegression()
logisticRegression.fit(x_train, y_train)
print(logisticRegression.score(x_test, y_test))
logisticRegression2 = LogisticRegression(C=10)
logisticRegression2.fit(x_train, y_train)
print(logisticRegression2.score(x_test, y_test))
logisticRegression3 = LogisticRegression(C=0.1)
logisticRegression3.fit(x_train, y_train)
print(logisticRegression3.score(x_test, y_test))
decisionTreeGini = DecisionTreeClassifier(criterion="gini")
decisionTreeGini.fit(x_train, y_train)
print(decisionTreeGini.score(x_test, y_test))
decisionTreeEntropy = DecisionTreeClassifier(criterion="entropy")
decisionTreeEntropy.fit(x_train, y_train)
print(decisionTreeEntropy.score(x_test, y_test))
# and so on and so on

В этом беспорядочном куске кода мы тестируем 2 алгоритма машинного обучения — логистическую регрессию и дерево решений. Для каждого алгоритма есть разные параметры, которые мы можем протестировать. Здесь мы тестируем разные значения C для алгоритма логистической регрессии и разные значения критерия для алгоритма дерева решений. (Ни в коем случае мы не должны запоминать это — все это доступно в документации sklearn!)

Вот в чем загвоздка — этот кусок кода беспорядочный и не масштабируемый. Если вы хотите добавить 1 новый алгоритм, вам нужно добавить еще 3 строки кода и, возможно, еще 1 оператор импорта. Если вы хотите изменить способ печати партитуры, вам нужно отредактировать каждый отдельный оператор печати, существующий во всем фрагменте. (Боже, пожалуйста, нет) Тот факт, что мы обычно тестируем гораздо больше моделей, чем только 2, не помогает в нашем случае!

Более чистый способ тестирования нескольких моделей

1) Выберите и импортируйте свои модели

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

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

Важно: четко определите, делаете ли вы регрессию или классификацию, и убедитесь, что все выбранные вами модели верны! (Логистическая регрессия имеет в своем названии регрессию, но это алгоритм классификации)

2) Определите параметры, которые вы хотите протестировать для каждого алгоритма.

Каждый алгоритм машинного обучения имеет разные параметры для тестирования. Например, мы обычно тестируем LogisticRegression с разными значениями C (обратными силе регуляризации), для KNeighborsClassifier мы можем тестировать разные значения n_neighbors, и так далее. Для каждого алгоритма скомпилируйте каждую комбинацию параметров, которые вы хотите протестировать, в виде списка словарей.

Например, предположим, что я хочу протестировать различные значения C для LogisticRegression — вот как будет выглядеть мой список:

log_reg_params = [ {"C":0.01}, {"C":0.1}, {"C":1}, {"C":10} ]

Поскольку разные алгоритмы имеют разные параметры (перейдите к документации sklearn, чтобы узнать больше), нам нужен список параметров для каждого алгоритма. Вот пример:

log_reg_params = [{"C":0.01}, {"C":0.1}, {"C":1}, {"C":10}]
dec_tree_params = [{"criterion": "gini"}, {"criterion": "entropy"}]
rand_for_params = [{"criterion": "gini"}, {"criterion": "entropy"}]
kneighbors_params = [{"n_neighbors":3}, {"n_neighbors":5}]
naive_bayes_params = [{}]
svc_params = [{"C":0.01}, {"C":0.1}, {"C":1}, {"C":10}]

Отступление: оператор ** в Python

Допустим, у нас есть эта функция, которая складывает 2 параметра, a и b вместе:

def add(a, b):
    return a + b

Когда мы вызываем функцию, мы обычно передаем ее параметры следующим образом:

x = add(5, 6) # x will be 11

Мы также можем передать параметры в виде словаря, используя оператор **. Это все еще добавит 5 и 6, чтобы стать 11.

kwargs = {"a": 5, "b": 6}
x = add( **kwargs ) # x will still be 11

В некотором смысле оператор ** как бы открывает словарь, позволяя функции принимать «a» как 5 и «b» как 6.

3) Поместите их в двумерный список

Затем поместите импортированные классы в двумерный список в следующем формате:

modelclasses = [
    ["log regression", LogisticRegression, log_reg_params],
    ["decision tree", DecisionTreeClassifier, dec_tree_params],
    ["random forest", RandomForestClassifier, rand_for_params],
    ["k neighbors", KNeighborsClassifier, kneighbors_params],
    ["naive bayes", GaussianNB, naive_bayes_params],
    ["support vector machines", SVC, svc_params]
]

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

После подготовки этого списка мы можем использовать вложенный цикл for для перебора каждого алгоритма, а также каждого набора параметров для каждого алгоритма.

insights = []
for modelname, Model, params_list in modelclasses:
    for params in params_list:
        model = Model(**params)
        model.fit(x_train, y_train)
        score = model.score(x_test, y_test)
        insights.append((modelname, model, params, score))

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

insights.sort(key=lambda x:x[-1], reverse=True)
for modelname, model, params, score in insights:
    print(modelname, params, score)

Вывод

Надеюсь, это было полезно и приятного кодирования!

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

Вот ссылка для чтения неограниченного доступа к Medium