Краткое введение в линейную регрессию в Python
Всем привет! После краткого знакомства с библиотекой« Pandas », а также библиотекой NumPy, я хотел дать быстрое введение в построение моделей на Python, а что может быть лучше для начала, чем одна из самых простых моделей, линейная регрессия? Это будет первый пост о машинном обучении, и в будущем я планирую писать о более сложных моделях. Будьте на связи! Но пока давайте сосредоточимся на линейной регрессии.
В этом сообщении в блоге я хочу сосредоточиться на концепции линейной регрессии и, в основном, на ее реализации в Python. Линейная регрессия - это статистическая модель, которая исследует линейную связь между двумя (Простая линейная регрессия) или более (Множественная линейная регрессия) переменными - зависимой переменной и независимой переменной (ами). Линейная связь в основном означает, что когда одна (или несколько) независимых переменных увеличивается (или уменьшается), зависимая переменная также увеличивается (или уменьшается):
Как видите, линейная зависимость может быть положительной (независимая переменная растет, зависимая переменная растет) или отрицательной (независимая переменная растет, зависимая переменная уменьшается). Как я уже сказал, я сосредоточусь на реализации регрессионных моделей в Python, поэтому я не хочу слишком углубляться в математику под капотом регрессии, но я напишу об этом немного. Если вы хотите написать об этом в блоге, не стесняйтесь писать мне в ответах!
Немного о математике
Связь между переменными Y и X представлена этим уравнением:
Y`i = mX + b
В этом уравнении Y - зависимая переменная - или переменная, которую мы пытаемся предсказать или оценить; X - независимая переменная - переменная, которую мы используем для прогнозов; m - наклон линии регрессии - он отражает влияние X на Y. Другими словами, если X увеличивается на 1 единицу, Y увеличивается ровно на m единиц. («Полное раскрытие информации»: это верно, только если мы знаем, что X и Y имеют линейную связь. Почти во всех случаях линейной регрессии это не будет правдой!) b - константа, также известная как Y-пересечение. Если X равно 0, Y будет равно b (Предупреждение: см. Полное раскрытие ранее!). Это не обязательно применимо в реальной жизни - мы не всегда знаем точную взаимосвязь между X и Y или имеем точную линейную взаимосвязь.
Эти предостережения приводят нас к простой линейной регрессии (SLR). В модели SLR мы строим модель на основе данных - наклон и пересечение по оси Y выводятся из данных; кроме того, нам не нужно, чтобы отношения между X и Y были строго линейными. Модели SLR также включают ошибки в данных (также известные как остатки). Я не буду вдаваться в подробности сейчас, возможно, в более позднем посте, но остатки - это в основном различия между истинным значением Y и прогнозируемым / оценочным значением Y. Важно отметить, что в линейной регрессии мы пытаются предсказать непрерывную переменную. В регрессионной модели мы пытаемся минимизировать эти ошибки, находя линию наилучшего соответствия - линия регрессии от ошибок будет минимальной. Мы пытаемся минимизировать длину черных линий (точнее, расстояние синих точек) от красной линии - как можно ближе к нулю. Это связано (или эквивалентно) минимизации среднеквадратичной ошибки (MSE) или суммы квадратов ошибки (SSE), также называемой остаточной суммой квадратов. (RSS), но это может выходить за рамки этого сообщения в блоге :-)
В большинстве случаев у нас будет несколько независимых переменных - у нас будет несколько переменных; это может быть всего две независимые переменные и до сотен (или теоретически даже тысяч) переменных. в этих случаях мы будем использовать модель множественной линейной регрессии (MLR). Уравнение регрессии почти такое же, как и простое уравнение регрессии, только с большим количеством переменных:
Y’i = b0 + b1X1i + b2X2i
На этом завершается математическая часть этого поста :) Готовы приступить к реализации этого на Python?
Линейная регрессия в Python
Есть два основных способа выполнения линейной регрессии в Python - с помощью Statsmodels и scikit-learn. Также можно использовать библиотеку Scipy, но я считаю, что это не так распространено, как две другие библиотеки, о которых я упоминал. Давайте посмотрим, как провести линейную регрессию в обоих из них:
Линейная регрессия в статистических моделях
Statsmodels - это модуль Python, который предоставляет классы и функции для оценки множества различных статистических моделей, а также для проведения статистических тестов и исследования статистических данных. (из документации)
Как и в случае с Pandas и NumPy, самый простой способ получить или установить Statsmodels - использовать пакет Anaconda. Если по каким-то причинам вас интересует установка другим способом, загляните по этой ссылке. После установки вам нужно будет импортировать его каждый раз, когда вы захотите его использовать:
import statsmodels.api as sm
Давайте посмотрим, как на самом деле использовать статистические модели для линейной регрессии. Я буду использовать пример из класса по науке о данных, который я проходил в General Assembly DC:
Сначала мы импортируем набор данных из sklearn (другая упомянутая мною библиотека):
from sklearn import datasets ## imports datasets from scikit-learn data = datasets.load_boston() ## loads Boston dataset from datasets library
Это датасет цен на дома в Бостоне (ссылка на описание). Поскольку это набор данных, предназначенный для тестирования и обучения инструментов машинного обучения, он поставляется с описанием набора данных, и мы можем увидеть его с помощью команды print data.DESCR (это верно только для sklearn наборы данных, а не каждый набор данных! Было бы здорово…). Я добавляю начало описания, чтобы лучше понять переменные:
Boston House Prices dataset =========================== Notes ------ Data Set Characteristics: :Number of Instances: 506 :Number of Attributes: 13 numeric/categorical predictive :Median Value (attribute 14) is usually the target :Attribute Information (in order): - CRIM per capita crime rate by town - ZN proportion of residential land zoned for lots over 25,000 sq.ft. - INDUS proportion of non-retail business acres per town - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise) - NOX nitric oxides concentration (parts per 10 million) - RM average number of rooms per dwelling - AGE proportion of owner-occupied units built prior to 1940 - DIS weighted distances to five Boston employment centres - RAD index of accessibility to radial highways - TAX full-value property-tax rate per $10,000 - PTRATIO pupil-teacher ratio by town - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town - LSTAT % lower status of the population - MEDV Median value of owner-occupied homes in $1000's :Missing Attribute Values: None :Creator: Harrison, D. and Rubinfeld, D.L. This is a copy of UCI ML housing dataset. http://archive.ics.uci.edu/ml/datasets/Housing This dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.
При запуске data.feature_names и data.target будут напечатаны имена столбцов независимых переменных и зависимой переменной соответственно. Это означает, что Scikit-learn уже установил данные о стоимости / цене дома в качестве целевой переменной, а 13 других переменных установлены в качестве предикторов. Давайте посмотрим, как запустить линейную регрессию для этого набора данных.
Во-первых, мы должны загрузить данные в виде фрейма данных pandas для упрощения анализа и установить медианное домашнее значение в качестве целевой переменной:
import numpy as np import pandas as pd # define the data/predictors as the pre-set feature names df = pd.DataFrame(data.data, columns=data.feature_names) # Put the target (housing value -- MEDV) in another DataFrame target = pd.DataFrame(data.target, columns=["MEDV"])
Что мы здесь сделали, так это взяли набор данных и загрузили его как фрейм данных pandas; после этого мы устанавливаем предикторы (как df) - независимые переменные, которые предварительно установлены в наборе данных. Мы также устанавливаем цель - зависимую переменную или переменную, которую мы пытаемся предсказать / оценить.
Теперь нам нужно построить модель линейной регрессии. Нам нужно выбрать переменные, которые, по нашему мнению, будут хорошими предикторами для зависимой переменной - это можно сделать, проверив корреляцию (и) между переменными, построив график данных и визуально выполнив поиск взаимосвязи, проведя предварительное исследование того, какие переменные являются хорошими предикторами y и т. д. Для этого первого примера возьмем RM - среднее количество комнат и LSTAT - процент более низкого статуса населения. Важно отметить, что Statsmodels не добавляет константу по умолчанию. Давайте сначала посмотрим на это без константы в нашей регрессионной модели:
## Without a constant import statsmodels.api as sm X = df["RM"] y = target["MEDV"] # Note the difference in argument order model = sm.OLS(y, X).fit() predictions = model.predict(X) # make the predictions by the model # Print out the statistics model.summary()
Выход:
Интерпретация таблицы. Это очень длинная таблица, не так ли? Сначала у нас есть зависимая переменная, модель и метод. OLS означает обычные наименьшие квадраты, а метод наименьших квадратов означает, что мы пытаемся подогнать линию регрессии, которая минимизировала бы квадрат расстояния от линии регрессии (см. предыдущий раздел эта почта). Дата и время говорят сами за себя :) Как и количество наблюдений. Df остатков и моделей относится к степеням свободы - количеству значений в окончательном расчете статистики, которые могут изменяться.
Коэффициент 3,6534 означает, что при увеличении переменной RM на 1 прогнозируемое значение MDEV увеличивается на 3,6534. Несколько других важных значений - это R-квадрат - процент отклонения, который объясняет наша модель; стандартная ошибка (стандартное отклонение выборочного распределения статистики, чаще всего среднего); t-баллы и p-значения для проверки гипотез - RM имеет статистически значимое p-значение; существует 95% доверительный интервал для RM ( означает, что мы прогнозируем с доверием 95%, что значение RM находится между 3,548 и 3,759).
Если мы действительно хотим добавить константу в нашу модель - мы должны установить ее с помощью команды X = sm.add_constant(X)
, где X - имя вашего фрейма данных, содержащего ваши входные (независимые) переменные.
import statsmodels.api as sm # import statsmodels X = df["RM"] ## X usually means our input variables (or independent variables) y = target["MEDV"] ## Y usually means our output/dependent variable X = sm.add_constant(X) ## let's add an intercept (beta_0) to our model # Note the difference in argument order model = sm.OLS(y, X).fit() ## sm.OLS(output, input) predictions = model.predict(X) # Print out the statistics model.summary()
Выход:
Интерпретация таблицы. У постоянного члена коэффициенты разные. Без константы мы заставляем нашу модель проходить через начало координат, но теперь у нас есть пересечение по оси Y на уровне -34,67. Мы также изменили наклон предиктора RM с 3,634 на 9,1021.
Теперь давайте попробуем подогнать модель регрессии с более чем одной переменной - мы будем использовать RM и LSTAT, о которых я упоминал ранее. Примерка модели такая же:
X = df[[“RM”, “LSTAT”]] y = target[“MEDV”] model = sm.OLS(y, X).fit() predictions = model.predict(X) model.summary()
И вывод:
Интерпретация выходных данных. Здесь мы видим, что эта модель имеет гораздо более высокое значение R-квадрата - 0,948, что означает, что эта модель объясняет 94,8% дисперсии в нашей зависимой переменной. Каждый раз, когда мы добавляем переменные в регрессионную модель, R² будет больше, но это довольно высокий R². Мы видим, что и RM, и LSTAT статистически значимы при прогнозировании (или оценке) медианной стоимости дома; неудивительно, что при увеличении RM на 1 MEDV увеличится на 4,9069, а при увеличении LSTAT на 1, MEDV уменьшится на -0,6557. Как вы, возможно, помните, LSTAT - это процентная доля населения с более низким статусом, и, к сожалению, мы можем ожидать, что он снизит медианное значение домов. По той же логике, чем больше комнат в доме, тем выше будет его стоимость.
Это был пример как одиночной, так и множественной линейной регрессии в Statsmodels. Мы могли бы использовать столько переменных, сколько захотим, в наших регрессионных моделях - вплоть до всех 13! Далее я продемонстрирую, как запускать модели линейной регрессии в SKLearn.
Линейная регрессия в SKLearn
SKLearn - это золотой стандарт машинного обучения на Python. Он имеет множество алгоритмов обучения для регрессии, классификации, кластеризации и уменьшения размерности. Ознакомьтесь с моим сообщением об алгоритме KNN для получения карты различных алгоритмов и дополнительных ссылок на SKLearn. Чтобы использовать линейную регрессию, нам нужно ее импортировать:
from sklearn import linear_model
Давайте использовать тот же набор данных, который мы использовали ранее, о ценах на жилье в Бостоне. Вначале процесс будет таким же - импорт наборов данных из SKLearn и загрузка в набор данных Boston:
from sklearn import datasets ## imports datasets from scikit-learn data = datasets.load_boston() ## loads Boston dataset from datasets library
Затем мы загрузим данные в Pandas (как и раньше):
# define the data/predictors as the pre-set feature names df = pd.DataFrame(data.data, columns=data.feature_names) # Put the target (housing value -- MEDV) in another DataFrame target = pd.DataFrame(data.target, columns=["MEDV"])
Итак, теперь, как и раньше, у нас есть фрейм данных, содержащий независимые переменные (помеченные как «df») и фрейм данных с зависимой переменной (помеченные как «target»). Давайте подберем регрессионную модель с помощью SKLearn. Сначала мы определим наши X и Y - на этот раз я буду использовать все переменные во фрейме данных, чтобы предсказать цену на жилье:
X = df y = target[“MEDV”]
А потом подгоню модель:
lm = linear_model.LinearRegression() model = lm.fit(X,y)
Функция lm.fit () соответствует линейной модели. Мы хотим использовать модель для прогнозирования (для этого мы и здесь!), Поэтому воспользуемся lm.predict ():
predictions = lm.predict(X) print(predictions)[0:5]
Функция печати распечатает первые 5 прогнозов для y (я не распечатал весь список, чтобы «сэкономить место». Удаление [0: 5] приведет к печати всего списка):
[ 30.00821269 25.0298606 30.5702317 28.60814055 27.94288232]
Помните, lm.predict () предсказывает y (зависимую переменную), используя подобранную нами линейную модель. Вы, должно быть, заметили, что когда мы запускаем линейную регрессию с помощью SKLearn, мы не получаем красивую таблицу (ладно, она не такая красивая… но довольно полезная), как в Statsmodels. Что мы можем сделать, так это использовать встроенные функции для возврата оценки, коэффициентов и предполагаемых пересечений. Посмотрим, как это работает:
lm.score(X,y)
Дал бы такой результат:
0.7406077428649428
Это оценка R² нашей модели. Как вы, наверное, помните, это процент объясненной дисперсии прогнозов. Если интересно, подробнее здесь. Теперь давайте проверим коэффициенты для предикторов:
lm.coef_
даст этот результат:
array([ -1.07170557e-01, 4.63952195e-02, 2.08602395e-02, 2.68856140e+00, -1.77957587e+01, 3.80475246e+00, 7.51061703e-04, -1.47575880e+00, 3.05655038e-01, -1.23293463e-02, -9.53463555e-01, 9.39251272e-03, -5.25466633e-01])
и перехват:
lm.intercept_
что даст такой результат:
36.491103280363134
Это все (оценочные / прогнозируемые) части уравнения множественной регрессии, о котором я упоминал ранее. Ознакомьтесь с документацией, чтобы узнать больше о coef_ и intercept_.
Итак, это было быстрое (но довольно долгое!) Введение в то, как проводить линейную регрессию в Python. На практике вы не будете использовать весь набор данных, но вы разделите свои данные на обучающие данные для обучения вашей модели и тестовые данные, чтобы, как вы уже догадались, протестировать свою модель / прогнозы. Если вы хотите прочитать об этом, пожалуйста, прочтите мой следующий пост в блоге. А пока я надеюсь, что вам понравился этот пост, и я увижу вас в следующем.
Спасибо за чтение!