Разное

Train test split sklearn: sklearn.model_selection.train_test_split — scikit-learn 0.18.2 documentation

Содержание

Алгоритм КНН — поиск ближайших соседей

Алгоритм K-ближайших соседей (KNN) — это тип управляемого алгоритма ML, который может использоваться как для классификации, так и для задач прогнозирования регрессии. Тем не менее, он в основном используется для классификации прогнозирующих проблем в промышленности. Следующие два свойства будут определять KNN хорошо —

  • Алгоритм ленивого обучения — KNN — это алгоритм ленивого обучения, потому что он не имеет специальной фазы обучения и использует все данные для обучения во время классификации.

  • Непараметрический алгоритм обучения — KNN также является непараметрическим алгоритмом обучения, потому что он не предполагает ничего о базовых данных.

Алгоритм ленивого обучения — KNN — это алгоритм ленивого обучения, потому что он не имеет специальной фазы обучения и использует все данные для обучения во время классификации.

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

Работа алгоритма КНН

Алгоритм K-ближайших соседей (KNN) использует «сходство признаков» для прогнозирования значений новых точек данных, что также означает, что новой точке данных будет присвоено значение на основе того, насколько близко он соответствует точкам в обучающем наборе. Мы можем понять его работу с помощью следующих шагов —

Шаг 1 — Для реализации любого алгоритма нам нужен набор данных. Таким образом, во время первого шага KNN мы должны загрузить данные обучения, а также данные испытаний.

Шаг 2 — Далее нам нужно выбрать значение K, то есть ближайшие точки данных. K может быть любым целым числом.

Шаг 3 — Для каждой точки в тестовых данных сделайте следующее —

  • 3.1 — Рассчитайте расстояние между данными испытаний и каждой строкой данных тренировки с помощью любого из методов, а именно: Евклидово, Манхэттенское или Хэмминговское расстояние. Наиболее часто используемый метод расчета расстояния — евклидов.

  • 3.2 — Теперь, основываясь на значении расстояния, отсортируйте их в порядке возрастания.

  • 3.3 — Далее он выберет верхние K строк из отсортированного массива.

  • 3.4 — Теперь он назначит класс контрольной точке на основе наиболее часто встречающегося класса этих строк.

3.1 — Рассчитайте расстояние между данными испытаний и каждой строкой данных тренировки с помощью любого из методов, а именно: Евклидово, Манхэттенское или Хэмминговское расстояние. Наиболее часто используемый метод расчета расстояния — евклидов.

3.2 — Теперь, основываясь на значении расстояния, отсортируйте их в порядке возрастания.

3.3 — Далее он выберет верхние K строк из отсортированного массива.

3.4 — Теперь он назначит класс контрольной точке на основе наиболее часто встречающегося класса этих строк.

Шаг 4 — Конец

пример

Ниже приведен пример для понимания концепции K и работы алгоритма KNN.

Предположим, у нас есть набор данных, который можно построить следующим образом:

Теперь нам нужно классифицировать новую точку данных с черной точкой (в точке 60, 60) в синий или красный класс. Мы предполагаем, что K = 3, то есть он найдет три ближайшие точки данных. Это показано на следующей диаграмме —

На приведенной выше диаграмме мы видим трех ближайших соседей точки данных с черной точкой. Среди этих трех два из них принадлежат к Красному классу, поэтому черная точка также будет назначена в Красном классе.

Реализация в Python

Как мы знаем, алгоритм K-ближайших соседей (KNN) может использоваться как для классификации, так и для регрессии. Ниже приведены рецепты использования Python в качестве классификатора и регрессора в Python:

КНН как классификатор

Во-первых, начните с импорта необходимых пакетов Python —

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

Затем загрузите набор данных iris с веб-ссылки следующим образом:

path = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"

Далее нам нужно назначить имена столбцов для набора данных следующим образом:

headernames = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class']

Теперь нам нужно прочитать набор данных в pandas dataframe следующим образом:

dataset = pd.read_csv(path, names = headernames)
dataset.head()
чашелистник длины чашелистник ширины Лепесток длина Лепесток ширины Учебный класс
0 5,1 3,5 1.4 0.2 Iris-setosa
1 4,9 3.0 1.4 0.2 Iris-setosa
2 4,7 3,2 1,3 0.2 Iris-setosa
3 4,6 3,1 1,5 0.2 Iris-setosa
4 5.0 3,6 1.4 0.2 Iris-setosa

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

X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 4].values

Далее, мы разделим данные на разделение на поезда и тесты. Следующий код разделит набор данных на 60% данных обучения и 40% данных тестирования —

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.40)

Далее, масштабирование данных будет сделано следующим образом —

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

Далее обучаем модель с помощью класса sklearn класса KNeighborsClassifier следующим образом —

from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors = 8)
classifier.fit(X_train, y_train)

Наконец нам нужно сделать прогноз. Это можно сделать с помощью следующего скрипта —

y_pred = classifier.predict(X_test)

Затем распечатайте результаты следующим образом —

from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
result = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:")
print(result)
result1 = classification_report(y_test, y_pred)
print("Classification Report:",)
print (result1)
result2 = accuracy_score(y_test,y_pred)
print("Accuracy:",result2)

Выход

Confusion Matrix:
[[21 0 0]
[ 0 16 0]
[ 0 7 16]]
Classification Report:
                  precision   recall   f1-score   support
    Iris-setosa        1.00     1.00       1.00        21
Iris-versicolor        0.70     1.00       0.82        16
 Iris-virginica        1.00     0.70       0.82        23
      micro avg        0.88     0.88       0.88        60
      macro avg        0.90     0.90       0.88        60
   weighted avg        0.92     0.88       0.88        60

Accuracy: 0.8833333333333333

КНН в качестве регрессора

Во-первых, начните с импорта необходимых пакетов Python —

import numpy as np
import pandas as pd

Затем загрузите набор данных iris с веб-ссылки следующим образом:

path = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"

Далее нам нужно назначить имена столбцов для набора данных следующим образом:

headernames = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class']

Теперь нам нужно прочитать набор данных в pandas dataframe следующим образом:

data = pd.read_csv(url, names = headernames)
array = data.values
X = array[:,:2]
Y = array[:,2]
data.shape
output:(150, 5)

Затем импортируйте KNeighborsRegressor из sklearn, чтобы соответствовать модели —

from sklearn.neighbors import KNeighborsRegressor
knnr = KNeighborsRegressor(n_neighbors = 10)
knnr.fit(X, y)

Наконец, мы можем найти MSE следующим образом —

print ("The MSE is:",format(np.power(y-knnr.predict(X),2).mean()))

Выход

The MSE is: 0.12226666666666669

Плюсы и минусы КНН

Pros

  • Это очень простой алгоритм для понимания и интерпретации.

  • Это очень полезно для нелинейных данных, потому что в этом алгоритме нет предположения о данных.

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

  • Он имеет относительно высокую точность, но есть гораздо лучшие контролируемые модели обучения, чем KNN.

Это очень простой алгоритм для понимания и интерпретации.

Это очень полезно для нелинейных данных, потому что в этом алгоритме нет предположения о данных.

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

Он имеет относительно высокую точность, но есть гораздо лучшие контролируемые модели обучения, чем KNN.

Cons

  • Это вычислительно немного дорогой алгоритм, потому что он хранит все данные обучения.

  • Требуется большой объем памяти по сравнению с другими контролируемыми алгоритмами обучения.

  • Прогнозирование медленное в случае большого N.

  • Он очень чувствителен к масштабу данных, а также к несущественным функциям.

Это вычислительно немного дорогой алгоритм, потому что он хранит все данные обучения.

Требуется большой объем памяти по сравнению с другими контролируемыми алгоритмами обучения.

Прогнозирование медленное в случае большого N.

Он очень чувствителен к масштабу данных, а также к несущественным функциям.

Применение КНН

Ниже приведены некоторые из областей, в которых KNN может быть успешно применен:

Банковская система

KNN может использоваться в банковской системе, чтобы предсказать, подходит ли человек для утверждения кредита? Есть ли у этого человека характеристики, аналогичные неплательщикам?

Расчет кредитных рейтингов

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

Политика

С помощью алгоритмов KNN мы можем классифицировать потенциального избирателя по разным классам, таким как «Буду голосовать», «Не буду голосовать», «Буду голосовать за партию« Конгресс »,« Буду голосовать за партию «BJP».

Другими областями, в которых может использоваться алгоритм KNN, являются распознавание речи, обнаружение почерка, распознавание изображений и распознавание видео.

Scikit-learn: SVM, линейная регрессия, градиентный спуск

Для начала ответ на главный вопрос: а где мне, дизайнеру, пригодится линейная регрессия? Она популярна для решения прикладных задач, вроде прогнозирования. Это в первую очередь таргетированная реклама, нейрон в слоях классификации, простенькие системы скоринга для банков. В общем, любые задачи, где отношения между переменными линейны по своей природе: как возраст влияет на здоровье или сколько операторов в банке справляются с поставленными KPI. Или есть ли связь между продажаи и затратами на таргет, какие площадки больше всего влияют на продажи, линейна ли наблюдаемая зависимость.

Линейная регрессия позволяет прогнозировать зависимость переменной Y на основе переменной X. Визуализируя эту зависимость на графике, получается прямая линия, часто называемая «линия наилучшего соответствия». Линейная регрессия весьма проста, мы прогнозируем Y с учетом X. Есть целевая target-переменная, и потенциальное множество значений для target-переменной бесконечно. Пример: предсказание стоимости квартиры, подавая на вход количество комнат и удаленность от метро, это задача для линейной регрессии. Метрическая модель отвечает на метрическую гипотезу, или целевая переменная линейно зависит от признаков объектов. Типовая задача это прогноз выручки за год магазина, где гипотеза это зависимость количества магазинов и объема выручки. В общем, модель про деньги, поэтому очень популярна в банках: выдавать кредиты надо cумом, каждый параметр влияет на решение о кредите (заработок, дети, просрочки, стаж, состояние здоровья, риск дефолта).

Модели линейной регрессии используются для демонстрации или прогнозирования взаимосвязи между двумя переменными или факторами. Прогнозируемый фактор (фактор, для которого решается уравнение) называется зависимой переменной. Факторы, которые используются для предсказания значения зависимой переменной, называются независимыми переменными. Линейный регрессионный анализ используется для прогнозирования значения переменной на основе значения другой переменной.

Линейная регрессия это «строительный блок» для более сложных моделей, например для нейронок. Нейронки это простая череда логистических регрессий, для понимания которых нужна линейная. Она хорошо интерпретируема и её достаточно для многих задач. Существует парная регрессия, это частный случай линейной регрессии, в которой рассматривается только один признак (k = 1). Если все-же признаков больше одного, для аналитического решения может подойти метод наименьших квадратов.

Задача регрессии это минимизация ошибки. По математическому условию, два фактора, участвующие в простом линейном регрессионном анализе, обозначаются x и y. Уравнение, описывающее связь y с x, известно как регрессионная модель. Линейная регрессионная модель также содержит термин ошибки, который представлен Ε или греческой буквой «эпсилон». Термин ошибки используется для учета изменчивости в y, которая не может быть объяснена линейной зависимостью между x и y.

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

Условие задачи: я, как руководитель дизайн-отдела, хочу понять, кто из моих сотрудников самый эффективный. Все работы дизайнеров тестируются по метрике SUM и я точно знаю, у кого какое качество дизайна. Теперь мне надо правильно соотнести количество лет опыта и результативность работы.

В рамках статьи и в рамках терминологии машинного обучения мы будем называть наши наблюдения признаками. Признак это любая характеристика исследуемых данных, выраженная числом. Для начала укажем кол-во лет опыта у специалистов и посмотрим на форму данных командой командой x.shape. У нас всего 18 наблюдений (18 дизайнеров), это один набор признаков. Для добавления второго набора признаков создаем двухмерный массив NumPy. Второй набор данных это результативность (SUM), некий средний балл в диапазоне от 0 до 100. Весь наш набор данных будет называться «признаковым описанием». Внесли данные и визуализировали:

import numpy as np
x = np.array([[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
print (x)
print (x.shape)
y = np.array([[32,54,54,35,86,12,74,67,35,75,94,12,56,54,40,35,87,47]])
print (y)
print (y.shape)
 
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
plt.scatter(x,y)

import numpy as np
x = np.array([[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
print (x)
print (x.shape)
y = np.array([[32,54,54,35,86,12,74,67,35,75,94,12,56,54,40,35,87,47]])
print (y)
print (y.shape)

import matplotlib
matplotlib.use(‘TkAgg’)
from matplotlib import pyplot as plt
plt.scatter(x,y)

По горизонтали опыт в годах, по вертикали результат SUM. Даже на глаз некая логика в этих данных есть: чем меньше опыта, тем хуже результат работы, по мере увеличения X растет и Y. Сразу возникает желание использовать эти данные об результативности специалиста для прогнозирования, на сколько ему надо повышать зарплату, или уменьшать. Так как начало данных не из 0/0, то нужен интерсепт. Существует понятия сдвига (intercept) и наклона (slope), иногда их называют коэффициентами и параметрами.

Интерсепт это тоже признак, некий сдвиг в данных, пропишем его как x0. Можно использовать и Байеса, у него вполне схожее поведение, но в данном случае он был бы неуместен (не путать с теоремой Байеса). Немного облегчим себе задачу и представим, что у нас нет кривой насыщения, так как у опытных специалистов ранние работы априори плохие, поэтому мы взяли SUM только за последний год. Если человек имеет 0 лет опыта работы, то мы взяли данные за несколько месяцев.

Так как у нас линейная регрессия, попробуем на глаз подобрать вес для признака и интерсепт, и нарисовать по ним линию. Интерсепт может быть 15, а какой наклон? Наклон сложно определить из-за разного масштаба по горизонтали и вертикали. Но попробуем на глаз 3, 4, 5:

import numpy as np
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
 
y = np.array([[32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47]])
print(y)
print(y.shape)
 
X = np.array([[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
plt.scatter(X[1], y)
plt.plot(X[1], 15*np.ones(18) + X[1]*4)
plt.show()

import numpy as np
import matplotlib
matplotlib.use(‘TkAgg’)
from matplotlib import pyplot as plt

y = np.array([[32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47]])
print(y)
print(y.shape)

X = np.array([[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
plt.scatter(X[1], y)
plt.plot(X[1], 15*np.ones(18) + X[1]*4)
plt.show()

Как это считывать: линия регрессии может показывать положительную линейную зависимость, отрицательную линейную зависимость или не показывать никакой связи. Если линия не наклонная, связь между двумя переменными отсутствует. Если линия регрессии идет вверх, мы имеем положительную линейную зависимость. Если линия регрессии наклоняется вниз, имеется отрицательная линейная зависимость. При этом линия стремится выше предела в 100, это решается клипированием. Более того, правильно клипировать и отрицательные значения. Если применять деревья, то там тоже значения могут выскакивать за пределы возможных, но это целиком зависит от алгоритма.

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

y_pred1 = 15*np.ones(18) + X[1]*4
print (y_pred1)
err = np.sum(y - y_pred1)
print (err)

y_pred1 = 15*np.ones(18) + X[1]*4
print (y_pred1)
err = np.sum(y — y_pred1)
print (err)

Получаем число 179. И это весьма большое значение, значит, мы слишком мало предсказывали. Отрицательное значение значило бы перепрогноз, это более желанный результат. Лучше переработать, чем недоработать. Сейчас же мы можем ошибиться в сторону недопрогноза, и бизнес это не устроит. Есть еще один значимый недостаток: средняя ошибка равна нулю, она плоха тем, что мы можем иметь 2 наблюдения, которые отклоняются в разные стороны на одинаковое число, и при подсчете суммы они обнулятся (-1 +1 = 0). Такие противоположные объекты с одинаковым признаковым описанием скажут нам, что наша модель очень качественная. Хотя в модели могут быть сильные отклонения. Поэтому все разности приводятся к одному знаку с помощью модуля (ошибка MAE), либо все возводится в квадрат, это убирает знак минус. MAE это метод оценки параметров модели. В MAE модули не сильно увеличивают отклонения, считающиеся выбросами. Такая оценка будет более робастная и похожая на медиану, чем MSE. Существуют более сложные метрики, MAPE, RMSPE, и моя любимая RMSE.

Итак, регрессия это целевая переменная, например, потенциальная выручка магазина. И нам надо правильно выбрать функци потерь. MSE это квадратичная функция потерь, считаем матрицу Гессе и понимаем, что она удовлетворяет достаточному условию минимума. Но сейчас мы посмотрим на MAE, так как она дифференцируема,

def calc_mse(y, y_pred):
    err = np.mean((y - y_pred) ** 2)
    return err
 
print (calc_mse (y, y_pred1))
 
 
def calc_mae(y, y_pred):
    err = np.mean(np.abs(y - y_pred))
    return err
 
print (calc_mae(y, y_pred1))

def calc_mse(y, y_pred):
err = np.mean((y — y_pred) ** 2)
return err

print (calc_mse (y, y_pred1))

def calc_mae(y, y_pred):
err = np.mean(np.abs(y — y_pred))
return err

print (calc_mae(y, y_pred1))

X — матрица наблюдений и признаков размерности строк на столбцов. y — ответ (нужно предсказать).

Функции и формула для подсчета выше, принцип подсчета MAE следующий: np.sum(np.abs(y - y_pred1)) / 18, получаем 14.944444444444445. Тут остановлюсь чуть подробнее, MAE (Mean Absolute Error) это среднее абсолютное отклонение (mean absolute error = MAE), такой модуль отклонения устойчив к выбросам. Однако функция модуля не имеет производной в нуле, и её оптимизация может вызывать трудности. Поэтому для измерения отклонения можно просто посчитать квадрат разности.

И тут мы плавно переходим к среднеквадратичному отклонению (mean squared error, MSE), или квадратичная ошибка MSE: np.mean((y - y_pred1) **2), среднее берем вместо суммы, не будем усложнять расчет. Суть метода: минимизация суммы квадратов отклонений фактических значений от расчётных. Применяем, когда намн ужно решить задачу регрессии. Полученную сумму делим на число наблюдений, и получаем MSE. MSE лучше показывает ошибки, чем MAE. Итак, MSE = 326.1666666666667 и MAE = 14.944444444444445. По этим двум точкам строится линия, значит, эта модель (она же линия) будет работать лучше для точек на графике. И именно поэтому регрессия у нас линейная, т.к. ровная линия, которая точнее всего описывает зависимость в данных.

Это был способ на глазок, но куда приятнее автоматизировать процесс. Ведь новые показания SUM приходят каждый месяц и хочется отслеживать рост молодых дизайнеров и актуальность опытных специалистов. Нам нужна формула для автоматического подсчета двух коэффициентов, тут придет на выручку метод наименьших квадратов (МНК). Для работы понадобится матрица, которая по горизонтали и вертикали будет равняться количеству признаков и по форме будет квадратная (18×18). Если у нас 18 столбцов и 18 строк, то эти две матрицы можно перемножать. Итоговая матрица берется по количеству признаков, 2×2.

Вводим команду X.shape, узнаем, что у нас матрица (2, 18) . А команда X.T.shape говорит нам, что матрица (18, 2). Значит, эти две матрицы можно перемножать. Командой np.dot(X, X.T) получаем матрицу 2×2 по количеству признаков: [[ 18 100][ 100 1076]].

Надо отметить, что работа с матрицами алгоритмом МНК не очень стабильна. Что имеется ввиду: если определитель матрицы близок к нулю, но корректно вычислить обратную матрицу сложно. Если делить на небольшое занчение, то результатом будет большое значение (10 000 / 0,003 = 3 333 333), и столь малое изменение знаменателя влеук за собой огромные изменения результата. У нас есть 0,003 и 0,0000003, между этими значениями отличие небольшое, они оба очень близки к нулю. Но если разделить 1 на 0,003 и 1 на 0,0000003, то результаты будут 333 и 3 333 333 соответственно, и это уже очень широкий диапазон между значениями. Поэтому обратная матрица неустойчива, минимальная ошибка в определителе влечет огромную ошибку в вычислении обратной матрицы.

Следующим шагом находим из квадртаной матрицы обратную матрицу print (np.linalg.inv(np.dot(X, X.T))), результат [[ 0.11485909 -0.01067464] [-0.01067464 0.00192143]].

W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T
print (W)

W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T
print (W)

И последний шаг, умножаем на транспонированную матрицу и умножаем на y. И мы получаем набор весов. Это два числа, которые ранее мы пытались угадать на глаз, в этот раз их угадала система:[[32.48548249] [ 3.64261315]]. Мы же предположили, что интерсепт 35 и 5. На практике я бы применил частные производные для вывода формулы, но в рамках нашего примера сойдет и метод наименьших квадратов.

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

X = np.array([[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
y = np.array([[32,54,54,35,86,12,74,67,35,75,94,12,56,54,40,35,87,47]])
 
print (X.shape)
print (X.T.shape)
print (np.dot(X, X.T))
print (np.linalg.inv(np.dot(X, X.T)))
W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T
print (W)
 
plt.scatter(X[1], y)
plt.plot(X[1], 15*np.ones(18) + X[1]*4)
plt.plot(X[1], W[0] + W[1] * X[1])
 
plt.show()

X = np.array([[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,3,4,5,11,0,8,6,3,7,16,0,2,3,2,4,21,4]])
y = np.array([[32,54,54,35,86,12,74,67,35,75,94,12,56,54,40,35,87,47]])

print (X.shape)
print (X.T.shape)
print (np.dot(X, X.T))
print (np.linalg.inv(np.dot(X, X.T)))
W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T
print (W)

plt.scatter(X[1], y)
plt.plot(X[1], 15*np.ones(18) + X[1]*4)
plt.plot(X[1], W[0] + W[1] * X[1])

plt.show()

Оранжевая линия основана на значениях, которые мы подсчитали с использованием весов.

На примере выше видно, что построенная машиной линейная регрессия более жестко отсеивает людей, чем сделал бы это я «на глаз». Это элементарный пример использования машинного обучения для решения бизнес-задач. Теперь подсчитаем новые MAE и MSE для свеженайденных значений:

y_ml=W[0] + W[1] * X[1]
print (calc_mse (y, y_ml))
print (calc_mae(y, y_ml))

y_ml=W[0] + W[1] * X[1]
print (calc_mse (y, y_ml))
print (calc_mae(y, y_ml))

Ранее MSE = 326.1666666666667 и MAE = 14.944444444444445, сейчас MSE = 174.00144700635732 и MAE = 11.478128854730052. Уже куда лучше (помним, чем значение ближе к нулю, тем лучше).

Помимо MSE и MAE, есть логарифмическая функция потерь MSLE и MAPE как средняя средняя абсолютная ошибка в процентах.

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

Итак, метод наименьших квадратов считает хорошо, и главное, он делает это быстро. Но постоянно его применять не получится, альтернатива: вместо метода наименьших квадратов (МНК) часто применяется градиентный спуск. Градиент это итеративный метод. Он показывает направление наискорейшего возрастания функции. Есть и обратная история: антиградиент, он показывает наибольшее убывание. У МНК есть проблема: он плох при большой размерности X, а точнее, когда много данных. Градиентный спуск не уступает по точности МНК. Принцип его работы простой, сначала он находит плохое решение, потом лучше, еще лучше, еще лучше, и так до наименьшего значения ошибки. Правило: много данных = градиентный спуск. В современном мире выбор алгоритма сильно завязан на производительность, МНК сразу оценивает весь объем данных, а стохастический градиентный спуск позволяет подавать данные батчами. Это помогает экономить оперативную память, которой всегда не хватает. Хотя и МНК, и градиентный спуск легко превращают любую железку в обогреватель. А стохастический градиентный спуск (SGD) нужен когда данные не помещаются в оперативку, и данные нужно разбивать. Это позволяет быстрее достичь глобального минимума, так как в итерациях будет участвовать не весь набор данных. Очевидный недостаток это не попадание в настоящую точку минимума, но в общем то, уровень точности приемлемый. Все по аналогии с веб-аналитикой: есть семплирование, есть и проблемы.

Давайте пощупаем в деле градиентный спуск. Он перебирает разные варианты, и двигается к поставленной цели. Матрицы позволяют сразу выполнять много операций. В математическом анализе есть тема поиска частных производных итеративным перебором весов в MSE. Этим и займемся. У нас одна переменная, но мы добавили инетрсепт и это вес для псевдо-переменных. Получается два признака: инсерсепт и вес признака опыта. Классический градиентный спуск применяется редко, чаще выбирают стохастическую оптимизацию.

Процесс минимизации ошибки в градиентном спуске строится на трехмерном пространстве, образованного за счет двух значений весов (W0 = интерсепт и slope(m) опыт). Мы можем задать начальные веса -1 и 1. Найдем производную для каждого веса векторным способом: где W[0] одновременно и интерсепт и вес. Это вес при псевдо-признаке 1.

import numpy as np
X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4]])
y = np.array([[32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47]])
W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T
 
W = np.array([1, 0.75])
gradient_form_direct = 1/18 * 2 * np.sum(X[0] * W[0] - y[0])
print(gradient_form_direct)

import numpy as np
X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4]])
y = np.array([[32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47]])
W = np.linalg.inv(np.dot(X, X.T)) @ X @ y.T

W = np.array([1, 0.75])
gradient_form_direct = 1/18 * 2 * np.sum(X[0] * W[0] — y[0])
print(gradient_form_direct)

Мы получаем значение -103.44 , и это не очень хорошо. С таким огромным шагом мы можем просто проскочить нужное нам минимальное значение.5). Если видим минус в степени, то отсчет нулей идет назад = — 0,00001.

Значения могут сильно различаться, но после стандартизации/нормализации веса будут предсказуемы: 1,2,10, но точно не 1000. Напомню, W[0] это и интерсепт, и вес одновременно. Вес при псевдо-признаке 1.

alpha = 1e-5
gradient_form_direct = alpha * (1/18 * 2 * np.sum(X[0] * W[0] - y[0]))
print(gradient_form_direct)
print(W[0] - gradient_form_direct)

alpha = 1e-5
gradient_form_direct = alpha * (1/18 * 2 * np.sum(X[0] * W[0] — y[0]))
print(gradient_form_direct)
print(W[0] — gradient_form_direct)

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

import numpy as np
 
X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
               [1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4]])
y = np.array([32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47])
W = np.array([1, 0.5])
 
 
 
gradient_form_direct = 1e-4 * (1/18 * 2 * np.sum(X[0] * W[0] - y[0]))
print(gradient_form_direct)
print(W[0] - gradient_form_direct)
 
for i in range(2000):
  gradient_form = np.dot(W, X)
  W -= (1e-2 * (1/18 * 2 * np.dot((gradient_form - y), X.T)))
  if i % 200 == 0:
    print(i, W)

import numpy as np

X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4]])
y = np.array([32, 54, 54, 35, 86, 12, 74, 67, 35, 75, 94, 12, 56, 54, 40, 35, 87, 47])
W = np.array([1, 0.5])

gradient_form_direct = 1e-4 * (1/18 * 2 * np.sum(X[0] * W[0] — y[0]))
print(gradient_form_direct)
print(W[0] — gradient_form_direct)

for i in range(2000):
gradient_form = np.dot(W, X)
W -= (1e-2 * (1/18 * 2 * np.dot((gradient_form — y), X.T)))
if i % 200 == 0:
print(i, W)

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

Получаем 32.4854816 и 3.64261324. В практических задачах обычно никто не стремится доказать существование глобального минимума. MSE или log loss ограничены снизу нулём, и чем ближе к нулю, тем больше «ок, сойдет». Просто доказать существование глобального минимума то можно, а достигнуть его куда сложнее. Для особо пытливых умов можно взять альтернативу градиентному спуску, это K-FAC. Или увеличить коэффициент альфа и тогда будет нужно меньше итераций, например 1e-2 и увеличить количество итераций. Так мы дойдем до тех же значений, что мы получили мне помощи МНК. Зачастую используют сразу несколько градиентных спусков, они сходятся к разным точкам, находят разные лучшие начальные приближения, так удается найти лучшую точку минимума. Градиентный спуск имеет линейную скорость сходимости, это вариант более честный. Стохастический — сублинейную скорость, это позволяет не очень долго считать, вопрос мощностей для расчета и количества данных.

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

Добавим новый фактор — месячную зарплату.

X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
               [1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4],
               [65000, 80000, 85000, 75000, 120000, 25000, 65000, 65000, 29000, 36650, 260000, 12000, 35000, 45600, 25000, 65000, 175000, 73000]])

X = np.array( [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 3, 4, 5, 11, 0, 8, 6, 3, 7, 16, 0, 2, 3, 2, 4, 21, 4],
[65000, 80000, 85000, 75000, 120000, 25000, 65000, 65000, 29000, 36650, 260000, 12000, 35000, 45600, 25000, 65000, 175000, 73000]])

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

Гипотеза простая — чем больше платим человеку, тем лучшего результата работы мы от него ожидаем. Все признаки разномасштабные. Коэффициенты зависят от масштаба, и по коэффициентам мы не поймем значимость признаков при разном масштабе + не все алгоритмы это смогут обработать. Данные нужно нормализировать (интервал 0 до 1), после этого по весам регрессии можно будет судить, насколько важны признаки. При этом форма даных не будет изменена, просто поменяются среднее и дисперсия. Находим для каждого признака минимум и максимум: print (X[1].min(), X[1].max()), print (X[2].min(), X[2].max()). Получаем 0-21 и 12000-260000.

Нормализация по шагам: (X[1].max() -X [1].min()) получаем размах, максимальный опыт у дизайнеров 21 год. Смотрим на минимальный опыт (X[1] -X [1].min()), получаем [ 1 3 4 5 11 0 8 6 3 7 16 0 2 3 2 4 21 4], минимальный опыт ноль. И приводим все к нужному нам диапазону (X[1] - X[1].min()) / (X[1].max() -X[1].min()), результат вида [0.04761905 0.14285714 0.19047619 0.23809524 0.52380952 0. 0.38095238 0.28571429 0.14285714 0.33333333 0.76190476 0. 0.0952381 0.14285714 0.0952381 0.19047619 1. 0.19047619]. Теперь сделаем это для двух признаков:

X_norm = X.copy()
X_norm = X_norm.astype(np.float64)
X_norm[1] = (X[1] -X[1].min()) / (X[1].max() -X [1].min())
X_norm[2] = (X[2] -X[2].min()) / (X[2].max() -X [2].min())
print(X_norm)

X_norm = X.copy()
X_norm = X_norm.astype(np.float64)
X_norm[1] = (X[1] -X[1].min()) / (X[1].max() -X [1].min())
X_norm[2] = (X[2] -X[2].min()) / (X[2].max() -X [2].min())
print(X_norm)

А теперь стандартизация: мы пытаемся получить стандартное нормальное распределение, это диапазон от -1 до 1 с 0 в середине, и большинство значений скопятся в районе нуля. Так мы сможем привести все признаки к одному масштабу. Это важно для линейных моделей, так как они не смогут работать одновременно с наборами признаков: количество арбузов 100-600, и количество семечек в мандаринах 10000-30000. Также критично для метода ближайших соседей (kNN). Поэтому лучше наши данные заранее привести к виду, когда признаки находятся в примерно одном масштабе.

Смотрим на графики

import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
plt.hist(X[1], alpha=0.6, color='g')
 
'''либо'''
import matplotlib.pyplot as plt
plt.hist(X[1], alpha=0.6, color='g')

import matplotlib
matplotlib.use(‘TkAgg’)
from matplotlib import pyplot as plt
plt.hist(X[1], alpha=0.6, color=’g’)

»’либо»’
import matplotlib.pyplot as plt
plt.hist(X[1], alpha=0.6, color=’g’)

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

Создаем первую XGBoost модель на Python с использованием scikit-learn — TechCave

XGBoost — библиотека, реализующая методы градиентного бустинга. Ее производительность сделала данную библиотеку одним из лидеров в области машинного обучения.

В этом посте вы узнаете, как установить XGBoost и создать свою первую модель на Python.

1. Установка XGBoost для использования совместно с Python

XGBoost может быть установлен легко с помощью pip.

Например так:

sudo pip install xgboost

Для того, чтобы обновить XGBoost, необходимо использовать команду:

sudo pip install --upgrade xgboost

Также можно использовать альтернативный способ установки XGBoost, если вы не можете использовать pip или вы хотите установить последнюю версию кода из GitHub. Для этого вы должны клонировать проект XGBoost и выполнить сборку и установку в ручную.

Например, чтобы построить XGBoost без многопоточности на Mac OS X (GCC должен быть установлен с помощью MacPorts или Homebrew), вы должны выполнить следующие команды:

git clone --recursive https://github.com/dmlc/xgboost
cd xgboost
cp make/minimum.mk ./config.mk
make -j4
cd python-package
sudo python setup.py install

Вы можете узнать больше о том, как установить XGBoost для различных платформ из руководства по установке XGBoost. Информацию о пакете Python можно посмотреть тут XGBoost Python Package.

Для справки, вы можете просмотреть ссылку API XGBoost Python.

2. Описание проблемы: Прогнозирование развития диабета

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

Этот набор данных состоит из 8 входных переменных, которые описывают медицинские данные пациентов, так и переменной, выходным параметром, который означает появление у пациента диабета в течение 5 лет.

Вы можете узнать больше об этом наборе данных на веб-сайте UCI Machine Learning Repository.

Это хороший набор данных для первой модели XGBoost, потому что все входные переменные являются числовыми, а задача простая бинарная проблема классификации.

Загрузите этот набор данных и поместите его в текущую рабочую директорию с именем файла «pima-indians-diabetes.csv«.

3. Загрузка и подготовка данных

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

И так, давайте начнем с импорта классов и функций, которые мы намерены использовать в этом уроке.

import numpy
import xgboost
from sklearn import cross_validation
from sklearn.metrics import accuracy_score

Далее, нам необходимо загрузить файл CSV в виде массива NumPy, используя функцию loadtxt().

# load data
dataset = numpy.loadtxt('pima-indians-diabetes.csv', delimiter=",")

Мы должны отделить столбцы (атрибуты или фичи) набора данных входных паттернов (Х) и паттернов выходных (Y). Мы можем сделать это легко, указав индексы столбцов в формате NumPy массива.

# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]

И наконец, мы должны разделить данные Х и У на обучающий и тестовый наборы данных. обучающий комплект будет использоваться для создания модели XGBoost, а тестовый набор будет использоваться, для того, чтобы сделать прогнозы, по которым мы можем оценить качество модели.

Для этого мы будем использовать функцию train_test_split() из библиотеки scikit-learn.

# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, Y, test_size=test_size, random_state=seed)

Теперь мы готовы обучить вашу модель.

4. Обучение модели XGBoost

Модель XGBoost для классификации называется XGBClassifier. Мы можем создать ее и обучить с помощью тренировочного набора данных. Эта модель имеет функцию fit() для тренировки модели.

Параметры для обучения модели могут быть переданы модели в конструкторе.

# fit model no training data
model = xgboost.XGBClassifier()
model.fit(X_train, y_train)

Вы можете увидеть параметры, используемые в уже обученной модели, используя print():

print(model)

Вы можете узнать больше о классах XGBClassifier и XGBRegressor в документации XGBoost Python scikit-learn API.

Вы можете узнать больше о значении каждого параметра и как настроить их на странице XGBoost параметров.

Теперь мы готовы использовать обученную модель, чтобы сделать прогноз.

5. Делаем прогнозы с помощью XGBoost модели

Теперь мы можем делать прогнозы, применив нашу обученную модель на тестовом наборе данных.

Для того, чтобы делать прогнозы мы используем scikit-learn функцию model.predict().

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

# make predictions for test data
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]

Теперь, когда мы использовали обученную модель, чтобы сделать прогнозы по новым данным, мы можем оценить качество предсказаний, сравнивая их с реальными значениями. Для этого мы будем использовать встроенную в scikit-learn функцию accuracy_score().

# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

6. Собираем все вместе

Ниже приведен полный листинг кода.

# First XGBoost model for Pima Indians dataset
import numpy
import xgboost
from sklearn import cross_validation
from sklearn.metrics import accuracy_score
# load data
dataset = numpy.loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, Y, test_size=test_size, random_state=seed)
# fit model no training data
model = xgboost.XGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

После запуска этого примера мы увидим следующий результат.

Accuracy: 77.95%

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

Вот и все. Мы построили простую модель с использованием XGBoost.

Пример решения задачи множественной регрессии с помощью Python

Введение

Добрый день, уважаемые читатели.

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

Для примера решения задачи прогнозирования, я взял набор данных Energy efficiency из крупнейшего репозитория UCI. В качестве инструментов по традиции будем использовать Python c аналитическими пакетами pandas и scikit-learn.

Описание набора данных и постановка задачи

Дан набор данных, котором описаны следующие атрибуты помещения:

В нем $X1 \dotsm X8$ — характеристики помещения на основании которых будет проводиться анализ, а $y1, y2$ — значения нагрузки, которые надо спрогнозировать.

Предварительный анализ данных

Для начала загрузим наши данные и помотрим на них:

from pandas import read_csv, DataFrame
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
from sklearn.cross_validation import train_test_split
dataset = read_csv('EnergyEfficiency/ENB2012_data.csv',';')
dataset.head()

Теперь давайте посмортим не связаны ли между собой какие-либо атрибуты. Сделать это можно расчитав коэффициенты корреляции для всех столбцов. Как это сделать было описано в предыдущей статье:

dataset.corr()

Как можно заметить из нашей матрицы, коррелируют между собой следующие столбы (Значение коэффициента корреляции больше 95%):

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

Как можно заметить и матрицы с коэффициентами корреляции на y1,y2 больше значения оказывают X2 и X5, нежели X1 и X4, таким образом мы можем последние столбцы мы можем удалить.

dataset = dataset.drop(['X1','X4'], axis=1)
dataset.head()

Помимо этого, можно заметить, что поля Y1 и Y2 очень тесно коррелируют между собой. Но, т. к. нам надо спрогнозировать оба значения мы их оставляем “как есть”.

Выбор модели

Отделим от нашей выборки прогнозные значения:

trg = dataset[['Y1','Y2']]
trn = dataset.2}$ - условная дисперсия зависимой величины у по фактору х

Коэффициент принимает значение на промежутке $[0,1]$ и чем он ближе к 1 тем сильнее зависимость.

Ну что же теперь можно перейти непосредственно к построению модели и выбору модели. Давайте поместим все наши модели в один список для удобства дальнейшего анализа:

models = [LinearRegression(), # метод наименьших квадратов
          RandomForestRegressor(n_estimators=100, max_features ='sqrt'), # случайный лес
          KNeighborsRegressor(n_neighbors=6), # метод ближайших соседей
          SVR(kernel='linear'), # метод опорных векторов с линейным ядром
          LogisticRegression() # логистическая регрессия
          ]

Итак модели готовы, теперь мы разобъем наши исходные данные на 2 подвыборки: тестовую и обучающую. Кто читал мои предыдущие статьи знает, что сделать это можно с помощью функции train_test_split() из пакета scikit-learn:

Xtrn, Xtest, Ytrn, Ytest = train_test_split(trn, trg, test_size=0.2 \approx 90%$

Для дальнейшего анализа давайте заново обучим нашу модель:

model = models[1]
model.fit(Xtrn, Ytrn)
RandomForestRegressor(bootstrap=True, compute_importances=None,
           criterion='mse', max_depth=None, max_features='sqrt',
           min_density=None, min_samples_leaf=1, min_samples_split=2,
           n_estimators=100, n_jobs=1, oob_score=False, random_state=None,
           verbose=0)

При внимательном рассмотрении, может возникнуть вопрос, почему в предыдущий раз и делили зависимую выборку Ytrn на переменные(по столбцамм), а теперь мы этого не делаем.

Дело в том, что некоторые методы, такие как RandomForestRegressor, может работать с несколькими прогнозируемыми переменными, а другие (например SVR) могут работать только с одной переменной. Поэтому на при предыдущем обучении мы использовали разбиение по столбцам, чтобы избежать ошибки в процессе построения некоторых моделей.

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

С помощью него, можно посмотреть вес каждого фактора в итоговой моделе:

model.feature_importances_
array([ 0.40717901,  0.11394948,  0.34984766,  0.00751686,  0.09158358,
        0.02992342])

В нашем случае видно, что больше всего на нагрузку при обогреве и охлаждении влияют общая высота и площадь. Их общий вклад в прогнозной модели около 72%.

Также необходимо отметить, что по вышеуказанной схеме можно посмотреть влияне каждого фактора одельно на обогрев и отдельно на охлаждение, но т. к. эти факторы у нас очень тесно коррелируют между собой ($r\ =\ 97%$), мы следали общий вывод по ним обоим который и был написан выше.

Заключение

В статье я постарался показать основные этапы при регрессионном анализе данных с помощью Python и аналитческих пакетов pandas и scikit-learn.

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

Файл консоли IPython Notebook: EnergyEfficiency.ipynb

Please enable JavaScript to view the comments powered by Disqus.
comments powered by

Разница между использованием train_test_split и cross_val_score в sklearn.cross_validation Ru Python

У меня есть матрица с 20 столбцами. Последний столбец – метки 0/1.

Ссылка на данные: https://www.dropbox.com/s/8v4lomociw1xz0d/data_so.csv?dl=0

Я пытаюсь запустить случайный лес в наборе данных, используя перекрестное подтверждение. Я использую два метода:

1), используя sklearn.cross_validation.cross_val_score

2) используя sklearn.cross_validation.train_test_split

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

import csv import numpy as np import pandas as pd from sklearn import ensemble from sklearn.metrics import roc_auc_score from sklearn.cross_validation import train_test_split from sklearn.cross_validation import cross_val_score #read in the data data = pd.read_csv('data_so.csv', header=None) X = data.iloc[:,0:18] y = data.iloc[:,19] depth = 5 maxFeat = 3 result = cross_val_score(ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False), X, y, scoring='roc_auc', cv=2) result # result is now something like array([ 0.66773295, 0.58824739]) xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.50) RFModel = ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False) RFModel.fit(xtrain,ytrain) prediction = RFModel.predict_proba(xtest) auc = roc_auc_score(ytest, prediction[:,1:2]) print auc #something like 0.83 RFModel.fit(xtest,ytest) prediction = RFModel.predict_proba(xtrain) auc = roc_auc_score(ytrain, prediction[:,1:2]) print auc #also something like 0.83 

Мой вопрос:

почему я получаю разные результаты, т. е. почему AUC (метрика, которую я использую) выше, когда я использую train_test_split?

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

В случае двукратного перекрестного подтверждения в приведенном выше примере первая AUC всегда выше второй; это всегда что-то вроде 0.70 и 0.58.

Спасибо за вашу помощь!

4 Python библиотеки для интерпретируемого машинного обучения

Хотите добиться лучшего объяснения моделей машинного обучения? Нужна хорошая визуализация? Используйте эти Python библиотеки.

Из-за шума вокруг предвзятости искусственного интеллекта организации всё острее нуждаются в объяснении как прогнозов создаваемых моделей, так и принципов работы.

К счастью, растёт количество библиотек, которые предлагает язык программирования Python для решения этой проблемы. Ниже краткое руководство по четырём популярным библиотекам для интерпретации и объяснения моделей машинного обучения. Устанавливаются с использованием pip, поставляются с подробной документацией и делают упор на визуальную интерпретацию.

Yellowbrick

Эта Python библиотека и расширение пакета scikit-learn. Предоставляет некоторые полезные и симпатичные визуализации для моделей машинного обучения. Объекты визуализатора, основной интерфейс – оценки scikit-learn, поэтому если привыкли работать с scikit-learn, рабочий процесс покажется знакомым.

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

Библиотека устанавливается​​ с помощью pip.

pip install yellowbrick

Чтобы проиллюстрировать пару функциональных особенностей, будем использовать набор данных scikit-learn с именем «распознавание вина». Этот датасет с 13 признаками и 3 целевыми классами загружается непосредственно из библиотеки scikit-learn. В приведённом ниже коде импортируем набор данных и преобразуем в объект DataFrame. Классификатор умеет использовать информацию без предварительной обработки.

import pandas as pd
from sklearn import datasets
wine_data = datasets.load_wine()
df_wine = pd.DataFrame(wine_data.data,columns=wine_data.feature_names)
df_wine['target'] = pd.Series(wine_data.target)

Применяйте scikit-learn для дальнейшего разделения датасета на проверку и тренировку.

from sklearn.model_selection import train_test_split
X = df_wine.drop(['target'], axis=1)
y = df_wine['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

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

from yellowbrick.features import Rank2D
import matplotlib.pyplot as plt
visualizer = Rank2D(algorithm="pearson",  size=(1080, 720))
visualizer.fit_transform(X_train)
visualizer.poof()

Теперь подгоним RandomForestClassifier и оценим производительность с помощью другого визуализатора.

from yellowbrick.classifier import ClassificationReport
from sklearn.ensemble import RandomForestClassifier
model =  RandomForestClassifier()
visualizer = ClassificationReport(model, size=(1080, 720))
visualizer.fit(X_train, y_train)
visualizer.score(X_test, y_test)
visualizer.poof()

ELI5

ELI5 – ещё одна библиотека визуализации, которая пригодится для отладки моделей машинного обучения и объяснения сделанных прогнозов. Работает с самыми распространёнными инструментами машинного обучения на Python, включая scikit-learn, XGBoost и Keras.

Примените ELI5 для проверки значимости признаков модели, которую рассматривали выше.

import eli5
eli5.show_weights(model, feature_names = X.columns.tolist())

По умолчанию метод show_weights использует gain для расчёта веса, а когда понадобятся другие типы, добавьте аргумент importance_type.

И также применяйте show_prediction для проверки оснований отдельных прогнозов.

LIME

LIME расшифровывается как локальные интерпретируемые, независимые от модели объяснения. Интерпретирует предсказания, сделанные алгоритмами машинного обучения. Lime поддерживает объяснение единичных прогнозов из диапазона классификаторов, а также взаимодействует с scikit-learn «из коробки».

Воспользуемся Lime для интерпретации прогнозов модели, которую обучали раньше.

Устанавливаем библиотеку через pip.

pip install lime

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

import lime.lime_tabular
explainer = lime.lime_tabular.LimeTabularExplainer(X_train.values,                      
feature_names=X_train.columns.values.tolist(),                                        
class_names=y_train.unique())

Затем создаём лямбда-функцию, которая берёт модель для прогнозирования выборки данных. Строчку взяли из подробного руководства по Lime.

predict_fn = lambda x: model.predict_proba(x).astype(float)

Используйте интерпретатор, чтобы объяснить прогноз на отобранном образце. Результат увидите ниже. Lime создаёт визуализацию, которая показывает, как признаки внесли вклад в определённый прогноз.

exp = explainer.explain_instance(X_test.values[0], predict_fn, num_features=6)
exp.show_in_notebook(show_all=False)

MLxtend

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

Обратимся к MLxtend для сравнения границ решения классификатора голосования и составного классификатора.

Снова понадобится pip для установки.

pip install mlxtend

Используемые импорты смотрите ниже.

from mlxtend.plotting import plot_decision_regions
from mlxtend.classifier import EnsembleVoteClassifier
import matplotlib.gridspec as gridspec
import itertools
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier

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

X_train_ml = X_train[['proline', 'color_intensity']].values
y_train_ml = y_train.values

Затем создаём классификаторы, подгоняем к данным обучения и получаем визуализацию границ решений с помощью MLxtend. Результат под кодом.

clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
eclf = EnsembleVoteClassifier(clfs=[clf1, clf2, clf3], weights=[1,1,1])
value=1.5
width=0.75
gs = gridspec.GridSpec(2,2)
fig = plt.figure(figsize=(10,8))
labels = ['Logistic Regression', 'Random Forest', 'Naive Bayes', 'Ensemble']
for clf, lab, grd in zip([clf1, clf2, clf3, eclf],
                         labels,
                         itertools.product([0, 1], repeat=2)):
                         
    clf.fit(X_train_ml, y_train_ml)
    ax = plt.subplot(gs[grd[0], grd[1]])
    fig = plot_decision_regions(X=X_train_ml, y=y_train_ml, clf=clf)
    plt.title(lab)

На этом не исчерпывается список библиотек для интерпретации, объяснения и визуализации моделей машинного обучения, которые использует Python разработчик. Попробуйте также другие полезные инструменты из длинного списка.

Какие Python библиотеки для машинного обучения используете вы?

6 любительских ошибок, которые я допустил, работая с тестовыми шпагатами | Гонсало Феррейро Вольпи

В последние недели он вместе отправился в путешествие по системам рекомендаций. Мы увидели мягкое введение в тему, а также введение в наиболее важные меры сходства вокруг нее (помните, что весь репозиторий о системе рекомендаций и других проектах всегда доступен в моем профиле GitHub). И да, я знаю, есть ооочень много всего вокруг этой темы, поэтому мы вернемся к ней вкратце.Но на этой неделе я решил зайти в тупик, чтобы поговорить об очень базовой теме Data Science, которая доставила мне неплохую головную боль, когда я только начал работать с моделированием и машинным обучением: train-test splits .

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

Чтобы понять, что такое сплит-тест, нам нужно сначала понять, что такое «тестовая группа» и зачем, черт возьми, она нам нужна один при моделировании машинного обучения.

Короче говоря, когда мы пытаемся предсказать какой-либо результат, мы будем «тренировать» модель машинного обучения с использованием набора данных. Эта модель будет пытаться извлечь как можно больше из данных, чтобы делать точные прогнозы. Настолько много, что, возможно, наша модель извлечет из этого слишком много уроков, вплоть до того момента, когда будет полезно только предсказать тот набор данных, который мы дали ему для работы, но не смогли сделать прогнозы ни с какими другими.

Эта потенциальная проблема или риск является отправной точкой для нескольких инструментов и концепций, которые мы обычно применяем в машинном обучении:

  • Компромисс смещения и дисперсии, который, в двух словах, касается только того, сколько должна наша модель учится на наших тренировочных данных. Если он узнает слишком много, мы бы сказали, что у него «высокая дисперсия», и он «переоценивает» наши данные. Напротив, если он узнает слишком мало, у него будет «высокая систематическая ошибка», и модель будет «не соответствовать» нашим обучающим данным.
  • Концепция регуляризации также пригодится, когда мы говорим обо всем этом, поскольку это метод, который позволяет нам контролировать, насколько мы позволяем нашей модели учиться на наших данных. Концепция не так проста, но может быть легко применена с Python. Если вы хотите узнать больше, я настоятельно рекомендую это и эти базовые видео из StatQuest с Джошем Стармером.
  • Помимо любого метода контроля того, насколько наша модель учится на данных, общепринятой практикой является разделение данных для оценки нашей модели, чтобы мы могли быть уверены, что она хорошо работает с различными элементами.Вот где наконец-то появляется концепция test split ! Идея состоит в том, что мы хотели бы разделить наши исходные данные на две группы: обучающая группа, что неудивительно, будет использоваться для обучения нашей модели. Хотя мы оставим в стороне кучу данных, поэтому, когда мы уже обучили нашу модель и остались довольны ее производительностью, мы можем оценить ее с помощью совершенно нового набора данных, чтобы проверить, согласована ли модель. Это будет наша тестовая группа . И если мы получим гораздо худший результат на нашем наборе тестов, чем в нашей обучающей группе, то, вероятно, мы переоснащаем наши данные обучения.Обычно разумным считается разделение на 80–20 или 70–30%.
  • Наконец, мы могли бы также поговорить о концепции перекрестной проверки при оценке производительности нашей модели, но это должно подождать до следующей статьи 🙂

Как обычно, Sklearn упрощает все для us, и у него есть красивая жизненно важная библиотека, которая действительно пригодится для выполнения разделения поезд-тест:

 из sklearn.model_selection import train_test_split 

Документация довольно ясна, но давайте все равно рассмотрим простой пример:

 X_train, X_test, y_train, y_test = train_test_split (ваши_данные, y, test_size = 0.2, random_state = 123) 

Теперь следующим шагом будет… о, подождите, вот и все!

На самом деле мало что известно о том, как реализовать эту библиотеку. Это очень просто, и теперь у вас будет 4 разных набора данных:

  1. X_train: это будет ваша тренировочная группа
  2. X_test: это будет ваша тестовая группа
  3. Y_train: это будет ваша цель для вашей тренировочной группы
  4. Y_test: как вы понимаете, это будет ваша цель для вашей тестовой группы

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

  1. Напишите беспорядочно свой код сплит-теста

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

 X_train, X_test, y_train, y_test 

Вы пишете, например:

 X_test, X_train, y_test, y_train 

Звучит глупо? Одно из самых важных правил Data Science заключается в том, что вы не должны раскрывать свой результат теста, пока не будете удовлетворены результатом обучения / перекрестной проверки. Но помните, вы в беспорядке написали код разделения тренировки и теста, поэтому результат, который вы получаете, - это не ваша тренировка, а результат теста.Вы можете часами пытаться понять, почему вы получаете такие низкие значения данных о тренировках. Или, что еще хуже, вы можете отказаться от проекта из-за плохой производительности. В любом случае это ошибка, потому что однажды ее трудно найти, и это может привести к часам глубокого погружения в ваш код, пытаясь решить эту глупую ошибку.

2. Введите неверно размер тестовой группы

Один из параметров, который вы должны указать, - это «train_size» или «test_size».Вам следует использовать только один из них, но, что еще важнее, не перепутайте их. В противном случае вы могли бы установить поезд только с 20–30%. Это могло привести к нескольким проблемам. От недостатка данных для обучения правильной модели до получения слишком хороших или слишком плохих результатов, которые могут привести вас к дальнейшему анализу, требующему много времени.

3. Нормализуйте вашу тестовую группу отдельно от данных поезда

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

Sklearn предлагает очень удобную библиотеку для этого, вызывая:

 из sklearn.preprocessing import StandardScaler 

Процесс нормализации берет среднее и стандартное отклонение каждой функции и настраивает их масштаб, чтобы быть в пределах от -1 до 1 со средним значением 0.После того, как мы импортировали библиотеку, мы можем создать объект StandardScaler, чтобы продолжить нормализацию:

 scaler = StandardScaler () 

Однако, если мы разделяем наши данные на обучающие и тестовые группы, мы должны сначала подогнать наш объект StandardScaler, используя нашу группу поездов, а затем преобразуйте нашу тестовую группу, используя тот же объект. Например:

 scaler.fit (X_train) X_train = scaler.transform (X_train) X_test = scaler.transform (X_test) 

Почему мы должны таким образом нормализовать данные? Помните, что мы будем использовать наши данные для обучения нашей модели, поэтому нам нужно, чтобы наш объект StandardScaler зарегистрировался и продолжил работу со средним и стандартным отклонением нашего набора обучающих и преобразовал нашу тестовую группу, используя его.В противном случае мы бы выполняли два разных преобразования, используя два разных средних и два разных стандартных отклонения. Рассматривать как разные данные, которые должны быть одинаковыми.

4. Не перемешивать данные при необходимости и наоборот

Еще один параметр из нашего Sklearn train_test_split - «перемешать». Сохраним предыдущий пример и предположим, что наш набор данных состоит из 1000 элементов, из которых первые 500 соответствуют мужчинам, а последние 500 - женщинам.Значение по умолчанию для этого параметра - «Истина», но если по ошибке или по незнанию мы установим его в «Ложь» и разделим наши данные на 80–20, мы закончим обучение нашей модели с набором данных с 500 мужчинами и 300 женщинами. и протестировал его с набором данных, содержащим только 200 женщин.

Учтите, что значение по умолчанию - «Истина», поэтому, если придет время, когда вы не хотите перемешивать данные, не забудьте указать его;)

5. Не используйте с умом ' stratify 'параметр

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

Обычно этот параметр используется путем передачи целевой переменной следующим образом:

 X_train, X_test, y_train, y_test = train_test_split (your_data, y, test_size = 0.2,   stratify = y  , random_state = 123, shuffle = Верно) 

6.Забудьте об установке параметра'random_state '

Наконец, это то, что мы можем найти в нескольких инструментах от Sklearn, и документация довольно четко описывает, как это работает:

Если int, random_state - это начальное число, используемое случайным образом. генератор чисел; Если экземпляр RandomState, random_state является генератором случайных чисел; Если None, генератор случайных чисел - это экземпляр RandomState, используемый np.random.

Другими словами: если вы не укажете число или экземпляр объекта RandomState, каждая итерация train_test_split будет давать вам разные группы, поскольку начальное число, используемое для продолжения случайности вокруг разделения, будет другим.Это может привести к путанице, если по какой-либо причине нам придется запустить наш код, и мы начнем получать разные результаты.

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

Кроме того, не забудьте проверить мою последнюю статью о парсинге веб-страниц за 5 минут и более в моем профиле писателя в Towards Data Science .И если вам понравилась эта статья, не забудьте подписаться на меня, , и если вы хотите получать мои последние статьи прямо на вашу электронную почту, просто подпишитесь на мою рассылку 🙂

Спасибо за чтение!

Построение модели k-ближайших соседей (k-NN) с помощью Scikit-learn | Автор: Эйджаз Аллибхай.

k-NN (Изображение предоставлено)

k-Nearest-Neighbours (k-NN) - это модель машинного обучения с учителем. Контролируемое обучение - это когда модель учится на данных, которые уже помечены. Модель обучения с учителем принимает набор входных объектов и выходных значений.Затем модель обучается на этих данных, чтобы узнать, как сопоставить входные данные с желаемыми выходными данными, чтобы научиться делать прогнозы на основе невидимых данных.

Модели

k-NN работают, беря точку данных и глядя на «k» ближайших помеченных точек данных. Затем точке данных присваивается метка большинства «k» ближайших точек.

Например, если k = 5, и 3 точки являются «зелеными», а 2 - «красными», то рассматриваемая точка данных будет помечена как «зеленая», поскольку «зеленых» составляет большинство (как показано на над графиком).

Scikit-learn - это библиотека машинного обучения для Python. В этом руководстве мы построим модель k-NN с помощью Scikit-learn, чтобы предсказать, есть ли у пациента диабет.

Чтение обучающих данных

Для нашей модели k-NN первым шагом является чтение данных, которые мы будем использовать в качестве входных. В этом примере мы используем набор данных о диабете. Для начала мы будем использовать Pandas для чтения данных. Я не буду вдаваться в подробности о Pandas, но это библиотека, с которой вам следует ознакомиться, если вы хотите глубже погрузиться в науку о данных и машинное обучение.

 import pandas as pd # считываем данные с помощью pandas 
df = pd.read_csv ('data / dia_data.csv') # проверяем, что данные были прочитаны правильно
df.head ()

Далее посмотрим, сколько данные у нас есть. Мы вызовем функцию «shape» в нашем фрейме данных, чтобы увидеть, сколько строк и столбцов есть в наших данных. В строках указано количество пациентов, а в столбцах указано количество характеристик (возраст, вес и т. Д.) В наборе данных для каждого пациента.

 # проверьте количество строк и столбцов в наборе данных 
df.shape

Мы видим, что у нас есть 768 строк данных (потенциальные пациенты с диабетом) и 9 столбцов (8 входных функций и 1 целевой выход).

Разделите набор данных на входные и целевые

Теперь давайте разделим наш набор данных на входные (X) и нашу цель (y). Мы вводим все столбцы, кроме «диабета», потому что «диабет» - это то, что мы будем пытаться предсказать. Следовательно, нашей целью будет «диабет».

Мы будем использовать функцию pandas «drop», чтобы удалить столбец «диабет» из нашего фрейма данных и сохранить его в переменной «X».Это будет наш вклад.

  # создать фрейм данных со всеми обучающими данными, кроме целевого столбца  
X = df.drop (columns = ['diver']) # проверить, что целевая переменная была удалена
X.head ()

Мы вставим столбец «диабет» нашего набора данных в нашу целевую переменную (y).

 # отдельные целевые значения 
y = df ['diab']. Values ​​# просмотреть целевые значения
y [0: 5]

Разделить набор данных на обучающие и тестовые данные

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

Scikit-learn имеет функцию, которую мы можем использовать, под названием «train_test_split», которая позволяет нам легко разделить наш набор данных на данные для обучения и тестирования.

 из sklearn.model_selection import train_test_split # разделить набор данных на обучающие и тестовые данные 
X_train, X_test, y_train, y_test = train_test_split (X, y, test_size = 0.2, random_state = 1, stratify = y)

'train_test_split 5 параметров.Первые два параметра - это входные и целевые данные, которые мы разделили ранее. Далее мы установим test_size на 0,2. Это означает, что 20% всех данных будет использоваться для тестирования, что оставляет 80% данных в качестве обучающих данных для модели, на которой можно учиться. Установка «random_state» на 1 гарантирует, что мы каждый раз будем получать одинаковое разбиение, чтобы мы могли воспроизвести наши результаты.

Установка для параметра «стратификация» значения y заставляет нашу тренировочную группу представлять долю каждого значения в переменной y. Например, в нашем наборе данных, если 25% пациентов страдают диабетом, а 75% не страдают диабетом, установка для параметра "стратификация" значения y гарантирует, что в случайном разбиении будет 25% пациентов с диабетом и 75% пациентов без диабета.

Построение и обучение модели

Затем нам нужно построить модель. Вот код:

 из sklearn.neighbors import KNeighborsClassifier # Создать классификатор KNN 
knn = KNeighborsClassifier (n_neighbors = 3) # Подобрать классификатор к данным
knn.fit (X_train, y_train)

Сначала мы создадим новый классификатор k-NN и установите для n_neighbors значение 3. Напомним, это означает, что если по крайней мере 2 из 3 ближайших точек к новой точке данных являются пациентами без диабета, то новая точка данных будет помечена как «нет». диабет », и наоборот.Другими словами, новая точка данных маркируется большинством из 3 ближайших точек.

Мы установили n_neighbors равным 3 в качестве отправной точки. Ниже мы более подробно рассмотрим, как лучше выбрать значение для «n_neighbors», чтобы модель могла улучшить свою производительность.

Далее нам нужно обучить модель. Чтобы обучить нашу новую модель, мы будем использовать функцию «fit» и передавать наши обучающие данные в качестве параметров, чтобы подогнать нашу модель к обучающим данным.

Тестирование модели

После обучения модели мы можем использовать функцию «прогноз» в нашей модели, чтобы делать прогнозы на основе наших тестовых данных.Как было видно при проверке «y» ранее, 0 указывает, что у пациента нет диабета, а 1 указывает, что у пациента действительно диабет. Для экономии места мы покажем print только первые 5 прогнозов нашего тестового набора.

 # показать первые 5 прогнозов модели на тестовых данных 
knn.predict (X_test) [0: 5]

Мы видим, что модель предсказала «отсутствие диабета» для первых 4 пациентов в наборе тестов и «диабет» для 5-го пациента.

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

 

Набор для обучения и тестирования в машинном обучении Python - как разделить

Бесплатный курс Python с 25 проектами (код купона: DATAFLAIR_PYTHON) Начать сейчас

1. Цель

На нашем последнем занятии мы обсудили предварительную обработку, анализ и визуализацию данных в Python ML . Теперь в этом руководстве мы узнаем, как разделить файл CSV на данные обучения и тестирования в Машинное обучение Python . Кроме того, мы изучим предварительные условия и процесс для разделения набора данных на данные обучения и набор тестов в Python ML.

Итак, приступим к обучению и тестированию набора в машинном обучении Python.

Набор для обучения и тестирования в машинном обучении Python - Как разделить

2. Данные для обучения и тестирования в машинном обучении Python

Поскольку мы работаем с наборами данных, алгоритм машинного обучения работает в два этапа.Обычно мы разделяем данные примерно на 20% -80% между этапами тестирования и обучения. В рамках контролируемого обучения мы разделяем набор данных на обучающие и тестовые данные в Python ML.

Набор для обучения и тестирования в машинном обучении Python

а. Предварительные требования для обучающих и тестовых данных
Нам понадобятся следующие библиотек Python для этого учебника - pandas и sklearn.
Мы можем установить их с помощью pip-

 pip install pandas 
 pip install sklearn 

Мы используем pandas для импорта набора данных и sklearn для выполнения разделения.Вы можете импортировать эти пакеты как -

 >>> импортировать панд как pd
>>> из sklearn.model_selection import train_test_split
>>> из sklearn.datasets импортируйте load_iris 

Знаете ли вы о форматах файлов данных Python - как читать CSV, JSON, XLS

3. Как разделить набор тренировок и тестов в машинном обучении Python?

Ниже приведен процесс обучения и тестирования в Python ML. Итак, давайте сначала возьмем набор данных.

Как разделить набор для обучения и тестирования в машинном обучении Python

а.Загрузка набора данных

Загрузим набор данных о лесных пожарах с помощью панд.

 >>> data = pd.read_csv ('forestfires.csv')
>>> data.head () 

Набор для обучения и тестирования в машинном обучении Python

г. Колка

Давайте разделим эти данные на метки и функции. Что это? Используя особенности, мы прогнозируем метки Я имею в виду, используя функции (данные, которые мы используем для предсказания меток), мы предсказываем метки (данные, которые мы хотим предсказывать).

 >>> y = данные.темп
>>> x = data.drop ('temp', axis = 1) 

Temp - это метка для прогнозирования температуры в y; мы используем функцию drop (), чтобы взять все остальные данные в x. Затем мы разделяем данные.

 >>> x_train, x_test, y_train, y_test = train_test_split (x, y, test_size = 0.2)
>>> x_train.head () 

Набор для обучения и тестирования в машинном обучении Python

 >>> x_train.shape 

(413, 12)
Знаете ли вы, как работать с реляционной базой данных с помощью Python

 >>> x_test.голова () 

Набор для обучения и тестирования в машинном обучении Python

 >>> x_test.shape 

(104, 12)
Строка test_size = 0,2 предполагает, что тестовые данные должны составлять 20% набора данных, а остальные должны быть данными обучения. С выходными данными функции shape () вы можете видеть, что у нас есть 104 строки в тестовых данных и 413 в обучающих данных.

г. Другой пример

Возьмем другой пример. На этот раз мы воспользуемся набором данных IRIS.

 >>> iris = load_iris ()
>>> х, у = диафрагма.данные, iris.target
>>> x_train, x_test, y_train, y_test = train_test_split (x, y,
train_size = 0,5,
test_size = 0,5,
random_state = 123)
>>> y_test 

массив ([1, 2, 2, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 2, 2, 2, 0, 0, 1, 0, 0, 2,
0, 2, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 1, 1, 2, 0, 0, 1, 1, 0, 2, 2,
2 , 2, 2, 1, 0, 0, 2, 0, 0, 1, 1, 1, 1, 2, 1, 2, 0, 2, 1, 0, 0, 2,
1, 2, 2, 0, 1, 1, 2, 0, 2])

 >>> y_train 

массив ([1, 1, 0, 2, 2, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 2, 0, 2, 0, 0, 1, 0,
0, 1, 2, 1, 1, 1, 0, 0, 1, 2, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0,
1 , 2, 2, 2, 2, 0, 1, 0, 1, 1, 0, 1, 2, 1, 2, 2, 0, 1, 0, 2, 2, 1,
1, 2, 2, 1, 0, 1, 1, 2, 2])
Давайте рассмотрим установку среды машинного обучения Python

4.Построение поезда и набора тестов на Python

Мы адаптируем нашу модель к данным поезда, чтобы делать на их основе прогнозы. Давайте импортируем linear_model из sklearn, применим линейную регрессию к набору данных и построим график результатов.

 >>> из sklearn.linear_model импортировать LinearRegression как lm
>>> model = lm (). fit (x_train, y_train)
>>> прогнозы = model.predict (x_test)
>>> импортировать matplotlib.pyplot как plt
>>> plt.scatter (y_test, прогнозы) 

 >>> plt.xlabel ('Истинные значения') 

Текст (0,5,0, ’True values’)

 >>> plt.ylabel ('Прогнозы') 

Текст (0,0.5, ’Predictions’)
Прочтите о Python NumPy - NumPy ndarray и NumPy Array

 >>> plt.show () 

Набор для обучения и тестирования в машинном обучении Python

0,9396299518034936
Итак, это все о наборе обучения и тестирования в машинном обучении Python.Надеюсь, вам понравится наше объяснение.

5. Заключение

Сегодня мы узнали, как разделить CSV или набор данных на два подмножества - обучающий набор и тестовый набор в Python Machine Learning. Обычно мы допускаем, что набор тестов составляет 20% от всего набора данных, а остальные 80% будут набором для обучения. Кроме того, если у вас есть вопрос, не стесняйтесь спрашивать в поле для комментариев.
Связанная тема - Python Географические карты и данные графиков
Для справки

Тренинг / тест по машинному обучению Python


Оцените свою модель

В машинном обучении мы создаем модели для прогнозирования исхода определенных событий,
как в предыдущей главе, где мы предсказывали выбросы CO2 от автомобиля, когда знали
вес и объем двигателя.

Чтобы измерить, достаточно ли хороша модель, мы можем использовать метод под названием Train / Test.


Что такое поезд / тест

Train / Test - это метод измерения точности вашей модели.

Это называется обучением / тестированием, потому что вы разделяете набор данных на два набора: обучающий набор и набор для тестирования.

80% на обучение и 20% на тестирование.

Вы обучили модель, используя обучающий набор.

Вы, , протестируете модель , используя набор для тестирования.

Train the model означает создать модель.

Test модель означает проверку точности модели.


Начать с набора данных

Начните с набора данных, который вы хотите протестировать.

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

Пример

import numpy
import matplotlib.pyplot as plt
numpy.random.seed (2)

x = numpy.random.normal (3, 1, 100)
y = numpy.random.normal (150, 40,
100) / x

plt.scatter (x, y)
plt.show ()

Результат:

Ось x представляет количество минут до совершения покупки.

По оси ординат отложена сумма денег, потраченная на покупку.

Пример запуска »


Разделить на поезд / тест

Обучающий набор должен представлять собой случайный выбор 80% исходных данных.

Набор для тестирования должен составлять оставшиеся 20%.

поезд_x = x [: 80]
train_y = y [: 80]

test_x = x [80:]
test_y = y [80:]


Показать обучающий набор

Отобразить тот же график рассеяния с обучающим набором:

Пример

plt.scatter (train_x,
train_y)
plt.show ()

Результат:

Похоже на исходный набор данных, так что кажется справедливым
выбор:

Пример запуска »


Показать набор для тестирования

Чтобы убедиться, что набор для тестирования не полностью отличается, мы также рассмотрим набор для тестирования.

Пример

plt.scatter (test_x,
test_y)
plt.show ()

Результат:

Набор для тестирования также выглядит как исходный набор данных:

Пример запуска »


Подходит для набора данных

Как выглядит набор данных? На мой взгляд, лучше всего подойдет
полиномиальная регрессия, поэтому давайте проведем линию полиномиальной регрессии.

Чтобы провести линию через точки данных, мы используем
plot ()
метод модуля matplotlib:

Пример

Проведите линию полиномиальной регрессии через точки данных:

импорт numpy
импорт
matplotlib.pyplot как plt
numpy.random.seed (2)

x =
numpy.random.normal (3, 1, 100)
y = numpy.random.normal (150, 40, 100) / x

train_x = x [: 80]
train_y = y [: 80]

test_x = x [80:]
test_y =
y [80:]

mymodel = numpy.poly1d (numpy.polyfit (train_x, train_y, 4))

myline = numpy.linspace (0, 6, 100)

plt.scatter (train_x, train_y)
plt.plot (myline, mymodel (myline))
plt.show ()

Результат:

Пример запуска »

Результат может подтвердить мое предположение о том, что набор данных соответствует полиному
регрессии, хотя это дало бы нам странные результаты, если бы мы попытались предсказать
значения вне набора данных.Пример: линия означает, что покупатель
Проведя в магазине 6 минут, вы сделаете покупку на 200 долларов.
признак переобучения.

А как насчет оценки R-квадрат? Оценка R-квадрат - хороший показатель
насколько хорошо мой набор данных соответствует модели.


R2

Помните R2, также известный как R-квадрат?

Он измеряет соотношение между осью x и y
оси, а значение находится в диапазоне от 0 до 1, где 0 означает отсутствие связи, а 1
означает полностью связанный.

В модуле sklearn есть метод r2_score ()
это поможет нам найти эти отношения.

В этом случае мы хотели бы измерить отношение
между минутами, в течение которых покупатель остается в магазине, и тем, сколько денег он тратит.

Пример

Насколько хорошо мои данные обучения соответствуют полиномиальной регрессии?

импортировать numpy
из sklearn.metrics import r2_score
numpy.random.seed (2)

x = numpy.random.нормальный (3, 1, 100)
y = numpy.random.normal (150, 40,
100) / x

train_x = x [: 80]
train_y = y [: 80]

test_x = x [80:]
test_y = y [80:]

mymodel = numpy.poly1d (numpy.polyfit (train_x, train_y,
4))

r2 = r2_score (train_y, mymodel (train_x))

print (r2)

Попробуй сам "

Примечание: Результат 0,799 показывает наличие отношения ОК.

Принесите набор для тестирования

Теперь мы создали модель, которая подходит, по крайней мере, когда дело доходит до данных обучения.

Теперь мы хотим протестировать модель с данными тестирования, чтобы увидеть, дает ли нам
тот же результат.

Пример

Найдем оценку R2 при использовании данных тестирования:

импортировать numpy
из sklearn.metrics import r2_score
numpy.random.seed (2)

x = numpy.random.normal (3, 1, 100)
y = numpy.random.normal (150, 40,
100) / x

train_x = x [: 80]
train_y = y [: 80]

test_x = x [80:]
test_y = y [80:]

mymodel = numpy.poly1d (numpy.polyfit (train_x, train_y,
4))

r2 = r2_score (test_y, mymodel (test_x))

print (r2)

Попробуй сам "

Примечание: Результат 0,809 показывает, что модель подходит
набор для тестирования, и мы уверены, что можем использовать модель для прогнозирования
будущие ценности.


Значения прогноза

Теперь, когда мы установили, что наша модель в порядке, мы можем начать прогнозировать
новые ценности.

Пример

Сколько денег потратит покупатель, если он или она останется в магазине
на 5 минут?

печать (mymodel (5))

Пример запуска »

В примере предполагалось, что покупатель потратит 22.88 долларов, что вроде соответствует схеме:


112. Разделение набора данных на обучающие и тестовые наборы с использованием методов Pandas DataFrames - Python для моделирования здравоохранения и обработки данных

Примечание: это также можно выполнить с использованием метода SciKit-Learn train_test_split, но здесь мы будем использовать собственные методы Pandas.

Создать DataFrame

  # Создать фрейм данных pandas

импортировать панд как pd

name = ['Сэм', 'Билл', 'Боб', 'Ян', 'Джо', 'Энн', 'Карл', 'Тони']
возраст = [22, 34, 18, 34, 76, 54, 21, 8]
гендер = ['f', 'm', 'm', 'm', 'f', 'f', 'm', 'f']
высота = [1.64, 1,85, 1,70, 1,75, 1,63, 1,79, 1,70, 1,68]
пройдено_physical = [0, 1, 1, 1, 0, 1, 1, 0]

people = pd.DataFrame ()
люди ['name'] = имя
люди ['age'] = возраст
люди ['пол'] = пол
люди ['height'] = рост
люди ['передано'] = пройдено_физическое

печать (люди)

Вне:

   имя возраст пол рост пройдено
0 Сэм 22 ж 1.64 0
1 Билл 34 м 1.85 1
2 Боб 18 м 1,70 1
3 Ян 34 м 1,75 1
4 Жо 76 ж 1.63 0
5 Анн 54 ж 1.79 1
6 Карл 21 м 1,70 1
7 Тони 8 ж 1.68 0  

Сплит-наборы для тренировок и тестов

Здесь мы берем случайную выборку (25%) строк и удаляем их из исходных данных, отбрасывая значения индекса.

  # Создайте копию DataFrame для работы с
# Опускаем случайное состояние, чтобы при каждом запуске было разное случайное разделение

people_copy = people.copy ()
train_set = people_copy.sample (frac = 0,75, random_state = 0)
test_set = people_copy.падение (train_set.index)

print ('Учебный набор')
печать (train_set)
print ('\ nТестовый набор')
печать (test_set)
print ('\ nOriginal DataFrame')
печать (люди)

Вне:

Обучающий набор
   имя возраст пол рост пройдено
6 Карл 21 м 1,70 1
2 Боб 18 м 1,70 1
1 Билл 34 м 1.85 1
7 Тони 8 ж 1.68 0
3 Ян 34 м 1,75 1
0 Сэм 22 ж 1.64 0

Набор для тестирования
   имя возраст пол рост пройдено
4 Жо 76 ж 1.63 0
5 Анн 54 ж 1.79 1

Исходный фрейм данных
   имя возраст пол рост пройдено
0 Сэм 22 ж 1.64 0
1 Билл 34 м 1.85 1
2 Боб 18 м 1,70 1
3 Ян 34 м 1,75 1
4 Жо 76 ж 1.63 0
5 Анн 54 ж 1.79 1
6 Карл 21 м 1,70 1
7 Тони 8 ж 1.68 0  

Используйте "pop" для извлечения ярлыков

«Pop» удалит столбец из DataFrame и перенесет его в новую переменную.

  train_set_labels = train_set.pop ('пройдено')
test_set_labels = test_set.pop ("пройдено")

Обучающий набор
   имя возраст пол рост
6 Карл 21 м 1,70
2 боба 18 м 1,70
1 купюра 34 м 1.85
7 Тони 8 ж 1.68
3 Ян 34 м 1,75
0 Сэм 22 ж 1.64

Вне:

Обучающий набор
   имя возраст пол рост
6 Карл 21 м 1,70
2 боба 18 м 1,70
1 купюра 34 м 1.85
7 Тони 8 ж 1.68
3 Ян 34 м 1.75
0 Сэм 22 ж 1.64

Ярлык тренировочного набора (y)
6 1
2 1
1 1
7 0
3 1
0 0
Имя: прошло, dtype: int64  

Нравится:

Нравится Загрузка ...

Связанные

Опубликовано Майкл Аллен

Интересы - использование моделирования и машинного обучения в здравоохранении, в настоящее время работает в NHS и Университете Эксетера. Обязуется выполнять всю работу, выполняемую с использованием бесплатного программного обеспечения с открытым исходным кодом (FOSS), и предоставлять как можно больше исходных данных.https://gitlab.com/michaelallen1966
Просмотреть все сообщения Майкла Аллена

Опубликовано

Общие сведения о разделении поездов / тестов - Видеоурок по Python

Обзор

Стенограммы

Файлы упражнений

Просмотр в автономном режиме

Детали курса

Наука о данных предоставляет организациям поразительную и очень ценную информацию о человеческом поведении.Хотя интеллектуальный анализ данных может показаться немного сложным, вам не нужно быть высококвалифицированным программистом, чтобы обрабатывать свои собственные данные. В этом практическом курсе вы узнаете, как использовать научный стек Python для выполнения общих задач по науке о данных. Мики Тебека описывает инструменты и концепции, необходимые для эффективной обработки данных с помощью научного стека Python, включая Pandas для обработки данных, matplotlib для визуализации данных, NumPy для числовых вычислений и многое другое.

Инструктор

  • Мики Тебека

    Генеральный директор 353solutions

    Мики Тебека - генеральный директор 353Solutions.

    В своей работе в 353Solutions Мики проводит практические семинары, которые помогают профессионалам углубить свое понимание Python и Go. Кроме того, он предлагает индивидуальные консультационные услуги, специализируясь на создании инфраструктур больших данных. Как показывает его работа в 353Solutions, он обладает высокими навыками в Python и Go, а также в C ++, JavaScript, Clojure и многом другом.

    Узнать больше

    Видеть меньше

Навыки, описанные в этом курсе

Зрители этого курса

47 912 человек смотрели этот курс

Связанные курсы

Добро пожаловать

«

- [Инструктор] Мы обманули данные, когда предоставили набор данных, а затем проверили нашу точность на тех же данных.Однако в реальной жизни наша модель должна будет делать прогнозы на основе данных, которых мы не видели. Мы рискуем тем, что называется переобучением, что означает, что наша модель точна для самих данных, но потерпит неудачу для новых данных. Обычной практикой является разделение данных на данные обучения и данные тестирования. Мы обучаем модель на обучающих данных, а затем используем тестовые данные для оценки модели. Scikit-learn упрощает этот процесс. Итак, давайте реализуем это. From.sklearn.model_selection import train_test_split. Как следует из названия, это разделит наши данные на обучающую и тестовую.Это будет происходить случайным образом. Итак, давайте сделаем x_train и x_test, y_train и y_test равными train_test_split для бостона ('данные') и бостона ('цель'). И мы скажем, что хотели бы, чтобы размер теста был третьим. Train_test_split возвращает четыре значения. Первые два - это разбивка характеристик данных. Переменная features традиционно называется x, поэтому мы называем части x_train и x_test. То же самое происходит с метками или целью, которую обычно называют y. Посмотрим, как у нас сейчас дела. Итак, clf - это RandomForcedRegressor, и теперь мы помещаем его только в данные x_train и y_train, а затем оценим его по данным x_test и y_test.Все еще не так уж и плохо. Есть несколько других методов разделения данных на обучающие и тестовые. Например, в KFold мы разделяем данные на K частей, затем вынимаем одну часть, тренируемся по остальным и оцениваем оставшиеся части. Мы делаем это для каждой части, и окончательная оценка - это средний балл. Scikit-learn поставляется с KFold и другими доступными методами, и, как правило, коммутация отличная. Обратите внимание, что иногда случайное разделение данных для тестирования и обучения может быть не очень хорошей стратегией. Например, если вы попытаетесь найти мошенничество с кредитными картами, большинство транзакций с данными не будут мошенническими, и есть большая вероятность, что мы выберем для обучения только образцы, не являющиеся мошенническими.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *