Это краткий справочник по применению контролируемого машинного обучения с использованием 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.