Это краткий справочник по применению контролируемого машинного обучения с использованием sklearn в Python. В этом руководстве предполагается, что вы знакомы с основными концепциями машинного обучения с учителем.

Регрессия с использованием линейной модели

Находит вес (w) и постоянный член (b), который минимизирует квадратичную ошибку модели (также называемую функцией потерь). Линейные модели не имеют каких-либо параметров для управления сложностью модели, однако предварительная обработка функций и регуляризация используются для повышения производительности модели.

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
fruits = pd.read_table(‘filename.txt’)
X = fruits[‘mass’, ‘width’, ‘height’]
y = fruits[‘fruit_label’]
X_train, X_test, y_train, y_test = train_test_split(X,y,randome_state = 123)
lin = LinearRegression().fit(X_train,y_train)
train_score = lin.score(X_train, y_train)
test_score = lin.score(X_test, y_test)
intercept = lin.intercept_
coef = lin.coef_
Number_of_non_zero_features = np.sum(lin.coef_ !=0)
#to predict on new examples
y_new = coef*X_new + intercept

Регрессия с использованием K-ближайших соседей (KNN)

Измеряет, насколько хорошо модель прогнозирования регрессии соответствует данным. Значение r_squared = 0 означает постоянную модель, которая предсказывает среднее значение для всех целевых значений обучения. Значение r_square = 1 означает идеальное предсказание. R_squared также известен как coefficient of determination

from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
fruits = pd.read_table(‘filename.txt’)
X = fruits[‘mass’, ‘width’, ‘height’]
y = fruits[‘fruit_label’]
X_train, X_test, y_train, y_test = train_test_split(X,y,randome_state = 123)
knn = KNeighborsClassifer(n_neighbors = 5)
train_score = knn.score(X_train, y_train)
test_score = knn.score(X_test, y_test)
#to predict on new examples
X_new = np.linspace(-3,3,500).reshape(-1,1) 
y_new = knn.predict(X_new)

Классификация с использованием K-ближайших соседей (KNN)

В KNN все соседи могут обрабатываться одинаково, или им можно отдать предпочтение, чтобы они были ближе, то есть имели набор функций, аналогичный маркированным образцам. Параметр для этого - weights и может иметь weights =’uniform’ или =’distance’.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
fruits = pd.read_table(‘filename.txt’)
# to get human readable labels like {1: ‘apple’, 2: ‘mandarin’, 3: ‘orange’, 4: ‘lemon’}, use the below code
lookup_fruit_name = dict(zip(fruits.fruit_label.unique(), fruits.fruit_name.unique()))
# create train test split
X = fruits[‘mass’, ‘width’, ‘height’] # this is where I choose which columns of dataframe ‘fruits’ will be features
y = fruits[‘fruit_label’] # this is where I choose which column will be the ‘target variable’
X_train, X_test, y_train, y_test = train_test_split(X,y,randome_state = 123) # splits in 75%:25% ratio of train:test
#create a classifier object
knn = KNeighborsClassifer(n_neighbors = 5, weights = ‘uniform’)
#train the classifer using the training data
knn.fit(X_train, y_train)
#asssess the accuracy
knn.score(X_test, y_test) # accuracy = (TN + TP)/ # of samples
#checking for individual instances
X_new = [’20 g’, ’10 cm broad’, ‘5.5 cm high’] # units are for demonstration, I’d actually use just the values.
fruit_prediction_number = knn.predict(X_new)
fruit_prediction_text = lookup_fruit_name[fruit_prediction_number[0]]

Повышение производительности KNN и линейных моделей:

1. Понимая компромисс между отклонением и смещением

  • Меньший K=1, классификатор хорошо заучивает отдельные точки в обучающей выборке. Прогноз чувствителен к шуму, выбросам, неверно маркированным данным.
    Более крупные K=5 области не так фрагментированы, более устойчивы к шуму, но возможно больше ошибок для отдельных точек.
  • Увеличивая K с 1, 10, 25, мы переходим от сложных моделей с низким смещением и высокой дисперсией к более простым моделям, которые могут иметь более высокое смещение, но могут быть более устойчивыми с меньшей дисперсией.
  • Чтобы получить более надежный результат из приведенного ниже кода, попробуйте использовать несколько разделений на поезд-тест (проблема, называемая выбором модели)
k_range = range(1,20)
scores = []
for k in k_range:
    knn = KNeighborsClassifer(n_neighbors = k)
    knn.fit(X_train, y_train)
    scores.append(knn.score(X_test, y_test))

Подбор KNN и линейной модели с использованием наименьших квадратов - два наиболее распространенных метода. Другие модели: деревья решений, машины опорных векторов с ядром, нейронные сети.

2. Путем обработки переобучения и недообучения

  • Обобщаемость - это цель: как модель работает с тестовыми / невидимыми данными.
  • Сложность модели: попытка подогнать слишком сложную модель с недостаточным объемом обучающих данных.
  • Недостаток (слишком простая модель, которая даже не подходит для обучающих данных, пусть только тестовые данные), Overfit (слишком сложная модель, которая слишком хорошо запоминает все примеры в обучающих данных и плохо работает с тестовыми данными. ).

3. Нормализация функций

  • Предварительная обработка данных путем нормализации значений признаков перед применением регуляризации Ridge. Это препятствует тому, чтобы Ridge чрезмерно утяжелял элементы с более крупными масштабами. MinMaxScaler () - распространенный метод нормализации. x ’= (x-xmin) / (xmax-xmin)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Notice ‘transform’. train scaler on training data to prevent data leakage

4. Полиномиальные преобразования.

  • Создает более богатый набор функций для работы без необходимости добавлять новые образцы в набор обучающих данных. degree управляет степенью полинома, до которой можно повышать характеристики для создания новых комбинаций. Для набора данных с двумя функциями X1 и X2 новые функции, добавленные с помощью degree=2: X1*X1, X1*X2, X2*X2
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree = 2)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)
lin = LinearRegression().fit(X_train_poly. y_train)
train_score = lin.score(X_train_poly, y_train)
test_score = lin.score(X_test_poly, y_test)
intercept = lin.intercept_
coef = lin.coef_
Number_of_non_zero_features = np.sum(lin.coef_ !=0)

5. Преобразование хребта (L2), лассо (L1) и полиномиальных признаков.

  • Риджевая регрессия добавляет штраф за большой разброс параметров w, это также называется регуляризацией. Поскольку Ридж использует квадрат весов, это называется L2-регуляризацией.
  • Снижает сложность окончательной модели. Если две модели имеют одинаковую минимизированную функцию потерь, регрессия Риджа предпочтет модель с меньшей суммой весов признаков. Значительно повышает точность, когда набор функций большой (100 функций). Степень регуляризации контролируется параметром alpha. большее значение означает большую регуляризацию и более простые модели. значение по умолчанию 1.0. Регуляризация становится менее важной по мере увеличения объема обучающих данных, которые у меня есть.
from sklearn.linear_model import Ridge
for alpha in [0,1,10,20,50,100,1000]:
linridge = Ridge(alpha = 20.0).fit(X_train_scaled, y_train)
   train_score = linridge.score(X_train_scaled, y_train)
   test_score = lnridge.score(X_test_scaled, y_test)
   intercept = linridge.intercept_
   coef = linridge.coef_
   Number_of_non_zero_features = np.sum(linridge.coef_ !=0)
  • Лассо имеет одинарные степени | весов | вместо квадратов, как в Ridge. Предпочитайте лассо, если меньше объектов со средними / большими эффектами. Код почти такой же. Лассо устанавливает больше коэффициентов и, наблюдая ненулевые веса и сортируя их по величине, дает хорошее представление о наиболее важных функциях модели.
from sklearn.linear_model import Lasso
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
for alpha in [0,1,10,20,50,100,1000]:
linlasso = Lasso(alpha = alpha).fit(X_train_scaled, y_train)
    train_score = linlasso.score(X_train_scaled, y_train)
    test_score = linlasso.score(X_test_scaled, y_test)
    intercept = linlasso.intercept_
    coef = linlasso.coef_
    Number_of_non_zero_features = np.sum(linlasso.coef_ !=0) # with lasso, more features are set to zero as compared to Ridge
linlasso = Lasso(alpha = 20.0).fit(X_train_scaled, y_train)
train_score = linlasso.score(X_train_scaled, y_train)
test_score = linlasso.score(X_test_scaled, y_test)
for e in sorted ([*zip ( [*X_labels] , linlasso.coeff_ ) ], key = lambda e: -abs(e[1])

Деревья решений

  • Найдите черту, которая приводит к наиболее информативному разделению. Переоснащение - типичная проблема, поскольку классификатор дерева решений продолжает добавлять новые узлы, пока каждый узел не станет чистым.
  • Существует три метода управления сложностью этих деревьев и предотвращения их переобучения: max_depth, max_leaf_nodes , min_samples_leaf (минимальное количество экземпляров в узле для рассмотрения разбиения). SciKit learn поддерживает только предварительную обрезку, когда я заранее решаю, насколько большими / сложными должны быть мои деревья решений.
  • Преимущества: нет необходимости выполнять предварительную обработку функций, легко визуализировать и хорошо работает, если функции относятся к разным типам (категориальные, непрерывные, двоичные).
  • Недостатки: даже после настройки деревья по-прежнему имеют тенденцию переоснащаться, и для получения хорошей производительности обобщения требуется ансамбль деревьев.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state = 123)
tree = DecisionTreeClassifer(max_depth = 3).fit(X_train, y_test)
train_score = tree.score(X_train, y_train)
test_score = tree.score(X_test, y_test)
#how does each node look like:
decision: The split criteria
samples: number of samples to split
distribution: [# samples class A, # samples class B, # samples class C, …]
class: Name of the class with most #samples at this node.

Улучшение деревьев решений с помощью случайных лесов и повышения градиента

1. Ансамбль - Случайные леса

  • n_estimator - количество используемых деревьев решений. Каждое дерево строится из разных выборок данных, также называемых самонастраиваемыми выборками (случайный выбор с заменой - позволяет включать строку в выборку несколько раз). Вместо того, чтобы строить дерево решений по всем признакам, для разных деревьев выбирается случайный набор признаков, управляемый параметром max_features.
  • Объединение результатов после вычисления всех деревьев решений: Для регрессии веса и пересечения принимаются как среднее значение всех деревьев, а затем применяются для каждой выборки. Для классификации каждое дерево дает вероятность для каждого класса для каждой выборки, вероятности усредняются по деревьям для каждой выборки, выбирается класс с наибольшей вероятностью для выборки.
  • n_estimators Должно быть больше для больших наборов данных, чтобы уменьшить переобучение.
  • max_features влияет на разнообразие деревьев в лесу. По умолчанию достаточно, но настройка может дать некоторый выигрыш.
  • max_depth необходимо устанавливать каждый раз, поскольку значение по умолчанию - Нет и работает до тех пор, пока все листы не станут чистыми.
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
clf = RandomForestClassifier( n_estimators = 10, n_features = 3, random_state = 123).fit (X_train, y_train)

2. Деревья решений с градиентным усилением (GBDT)

  • Используйте ансамбль как Random Forest, но в отличие от параллельного построения деревьев и усреднения их результатов, таких как RandomForest, он строит деревья последовательно, где каждое дерево исправляет ошибки предыдущего дерева.
  • Вначале использует слабых учеников (неглубокие деревья) и улучшает их в дальнейшем. learning_rate, если высокий, означает, что каждое последующее дерево будет уделять особое внимание исправлению ошибок предыдущего дерева, что приведет к созданию более сложных деревьев.
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
clf = GradientBoostingClassifier(learning_rate=0.1, n_estimators=100, max_depth=3, random_state = 123).fit (X_train, y_train)
  • n_estimators # слабых учеников, обычно сначала корректируются для повышения точности и использования вычислительной эффективности.
  • learning_rate настроен, но n_estimators исправлены.
  • max_depth всегда сохраняется маленьким (3–5), поскольку ГБДТ предполагают, что каждое дерево является слабым учеником.

Деревья решений с градиентным усилением являются одними из лучших стандартных доступных методов обучения с учителем и используют только скромную память и время выполнения (хотя обучение модели требует очень больших вычислительных ресурсов). У них тоже есть преимущества, присущие деревьям решений (не требуется предварительной обработки / нормализации функций, можно использовать несколько типов функций). Большинство основных коммерческих приложений, которые мы видим в области машинного обучения, основаны на GBDT. И, как и другие деревья решений, GBDT также не рекомендуются для моделей классификации с очень большим количеством функций, таких как те, которые необходимы в распознавании речи и классификации текста.

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