Линейная регрессия и логистическая регрессия в несколько строк в Python
Пока я изучал линейную и логистическую регрессию по наброску, я ни разу не наткнулся на что-то простое, короткое. Поэтому я решил написать инструкцию по использованию двух самых распространенных и простых подходов Machine Learning, в максимально доступной форме. Без земного кода причины, без изучения дополнительных параметров и того, как они работают. Здесь не будем копаться под капотом, а просто сядем и поедем.
Что должен знать каждый Data Scientist? Правильно! Как предсказывать числовые значения и как классифицировать объекты и явления.
Итак, первый метод — линейная регрессия. Это метод предсказания одних чисел по другим. Например, вам нужно продать свой старый автомобиль, прежде чем размещать объявление о продаже. Вы хотите принять решение о цене, которую вы планируете получить за это. Для установки оптимального ценника с учетом всех параметров вашего автомобиля (год выпуска, пробег, дефекты по кузову, объем двигателя, комплектация и т. д.) вы решили провести изучение похожих объявлений. Вы собираете большую таблицу со всеми возможными характеристиками и ценами на подобные автомобили. После этого вы обрабатываете эти данные с помощью линейной регрессии, и вуаля, узнаете рыночную стоимость вашей старой лошади. Ниже вас ждет более подробное знакомство с линейной регрессией. Прочтите второй раздел этой статьи.
Второй метод, который мы здесь рассмотрим, — это логистическая регрессия, используемая для классификации. Простой пример классификации — получить ответ на вопрос в виде: да/нет (два класса, что означает бинарную классификацию).
Предположим, вы давно хотели узнать о пригодности воды для питья в источнике недалеко от вашего дома. Как настоящий Data Scientist, вы решаете собирать данные о воде из других водоемов, такие как значение pH, органический углерод и т. д., чтобы выяснить, пригодна ли она для питья или нет. Затем на основе логистической регрессии сравните данные, чтобы получить ответ.
Перейдем к коду. Осмелюсь сказать, что даже если вы новичок в программировании, то простое копирование кода и вставка его в IDE должно у вас работать :)
Линейная регрессия в 5 строках кода
Для работы с младшим оракулом — линейной регрессией нам нужно всего пять строк кода (не считая метода print()).
Давайте представим, что вы хотите устроиться на работу в новую компанию: у вас пять лет опыта, плюс на последнем месте работы у вас было восемь сотрудников. Давайте установим целью прогнозирования линейной регрессии ожидаемую заработную плату.
Вы уже успели познакомиться с тремя сотрудниками этой компании, работающими на аналогичной должности, и расспросить об их опыте и зарплате.
Чтобы определить нашу будущую зарплату, нам нужно обучить прогностическую модель. Для этого нам нужна собранная информация. Преобразуем полученные данные разведки в таблицу, которую ML-инженеры обычно называют набором данных.
В первой колонке мы собрали опыт в годах. Во втором — количество людей в подчинении, это тоже опыт, просто другой параметр. И в-третьих, соответствующие этому стажу зарплаты.
Время кода! Давайте создадим два списка Python с этими данными. В нашем случае список Python — это список для хранения нескольких чисел в одной переменной.
X = [[2, 1], [2, 0], [3, 4]] y = [2000, 1000, 4000]
«Х» — мы обозначили стаж в годах и количество людей в управлении, а «у» теперь «цель», то есть заработную плату, которую мы собираемся спрогнозировать.
Заглавная «X», потому что в математике принято обозначать матрицы заглавными буквами. Строчная «y», потому что это простой список, или если мы хотим углубиться в математику — вектор. Но не будем углубляться.
Теперь пришло время вызвать и обучить модель линейной регрессии.
from sklearn.linear_model import LinearRegression model = LinearRegression().fit(X, y)
Всего две строчки кода и модель обучена!
В первой строке будем загружать модель из библиотеки «sklearn» (если у вас нет такой библиотеки, то используйте команду в терминале вашей IDE: pip install -U scikit-learn). Во второй строке обучаем модель на данных «Х» и «у» (стаж и зарплата).
Поскольку наша модель обучена, пора попросить ее предсказать нашу зарплату!
prediction = model.predict([[5, 8]]) print('Prediction:', round(*prediction)) # Prediction: 6000
Поскольку наш опыт составляет пять лет и восемь человек в управлении, мы передаем эти параметры предсказательной машине (1 и 2 столбцы нашего набора данных).
Получаем ответ: 6000.
Теперь самое время усомниться в правильности предсказаний нашей модели.
Для тщательной оценки точности модели воспользуемся такой метрикой, как Mean Absolute Error. Эта метрика показывает, насколько прогноз, сделанный этой моделью, в среднем отличается от реальных цифр.
from sklearn.metrics import mean_absolute_error mae = round(mean_absolute_error(y, model.predict(X)), 10) print("Average error:", mae) # Average error: 0.0
Импортируем метрику оценки из уже используемой библиотеки. Мы позволим этой метрике сравнить прогнозируемые значения и реальные значения «у» (зарплата). И обнаруживаем, что в нашем экземпляре нет ошибки до десяти знаков после запятой. Для установления этой точности здесь использовался «круглый» метод. Оракул под названием «Линейная регрессия» сработал на 100%.
Если вы хотите углубиться в линейную регрессию, добро пожаловать:
Логистическая регрессия
Задача классификации — получить от модели ответ, к какому классу относится объект.
Для наиболее распространенной модели классификации, логистической регрессии, мы будем использовать больший набор данных. Используемая ранее библиотека машинного обучения sklearn подготовила наборы данных, которые загружаются и распаковываются для работы всего тремя строками кода. Рассмотрим один из них:
from sklearn.datasets import load_iris X = load_iris().data y = load_iris().target
Как вы уже, наверное, догадались, мы собираемся классифицировать цветы, а именно виды ирисов. Этот набор данных содержит три типа ирисов, которые названы здесь: 0, 1 и 2. Это разновидности цветов: Setosa, Versicolor и Virginica.
В первой строке мы загрузили подготовленный набор данных прямо из библиотеки. На фото ниже, как это выглядит (случайные пять рядов):
Вторая строка кода вырезала первые четыре столбца из набора данных и помечала их «X» (размеры цветов), а третья вырезала последний столбец и помечала его «y» (типы цветов или «цель»).
Подкованные в машинном обучении инженеры обычно делят наборы данных на две части. Первая часть — это набор данных для обучения, а вторая — набор данных для тестирования обученной модели. Например, они берут первую половину строк, чтобы модель училась на них, а на другой половине строк проверяют, насколько хорошо модель может угадать результат, сравнивая его с правильными данными.
В нашем случае мы выделим для тестирования 33% всех строк, а на оставшихся 67% будем обучать модель:
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=23)
В первой строке мы загрузили метод разделения набора данных из библиотеки. Вторая строка отделяла X и y для тестирования от X и y для обучения модели. test_size задает количество строк для тестирования модели, т. е. 0,33 из 1 (наши 33%); random_state=23 означает перетасовку строк. Число 23 — это не количество перетасовок и не количество рядов, которые нужно перетасовать, а просто число, помогающее компьютеру перетасовывать. Выберите любое число по вашему выбору, обычно любое число до 100.
Обучим модель:
from sklearn.linear_model import LogisticRegression model = LogisticRegression(max_iter=10000).fit(X_train, y_train)
Обратите внимание, что в обучении используются данные, отделенные от общих (67% набора данных, т.е. «X_train» и «y_train»). «max_iter=10000» здесь служит ограничителем количества прогонов модели. Так как теперь у нас есть больший набор данных, ограничимся 10000, чтобы не ждать долго.
Время предсказания!
Оценим, насколько хорошо обученная модель предсказывает класс цветка — заставим ее предсказывать остальную часть набора данных (33%) и сравним с реальными данными.
import pandas as pd prediction = model.predict(X_test) pred_10 = pd.DataFrame(X_test[0:10], columns=[["sepal length", "sepal width", "petal length", "petal width"]]) pred_10["predicted"] = prediction[0:10] pred_10["real"] = y_test[0:10] print(pred_10)
Первая строка загружает библиотеку для работы с таблицами. Второй дает пищу для предсказания — ранее выделенные данные для тестирования X_test (33% набора данных, которые не использовались для обучения).
Остальные строки кода используются для построения таблицы на рисунке ниже. Это первые десять строк тестового набора данных. Столбцы с первого по четвертый — это размеры цветов, которые использовались моделью в качестве данных прогноза. «прогнозируемый» — это класс цветка, предсказанный моделью, а «реальный» — это реальные значения класса цветка.
Согласно таблице, точность предсказания класса оказалась 100%, так как все прогнозируемые значения равны реальным. Но чтобы не сравнивать вручную все оставшиеся строки, воспользуемся такой метрикой, как precision_score:
from sklearn.metrics import precision_score precision = precision_score(y_test, prediction, average="macro") print("Precision:", round(precision, 2)) # Precision: 0.96
Первая строка вызывает метрику производительности из библиотеки, вторая сравнивает прогнозируемый результат для тестового набора данных с реальным, а третья строка выводит значение точности. Параметр medium="macro" используется для получения среднего значения метрики среди всех трех классов цветов и "макро" здесь именно потому, что эффективность всех трех классов оценивается вместе, а не по отдельности.
Ответ «0,96», что означает точность модели 96%. Да, модель не идеальна.
Если вы хотите углубиться в логистическую регрессию, добро пожаловать:
Теперь вы знаете два наиболее распространенных метода машинного обучения и можете предсказывать числа с помощью линейной регрессии. А с помощью Логистической регрессии отличать один класс объектов или явлений от других. С такой базой можно смело называть себя начинающим Data Scientist.
А теперь, дорогой читатель, пришло время скачать этот код:
Перейдите в свою IDE и поэкспериментируйте с предсказаниями значений и классификациями объектов :)