Автор оригинала: Lukas Halim.
В чем разница между Statsmodels и Scikit – учиться? Оба имеют обычные наименьшие квадраты и логистическую регрессию, поэтому кажется, что Python дает нам два способа сделать то же самое. Statsmodels предлагает моделирование с точки зрения статистика Отказ Scikit-Learn предлагает некоторые из тех же моделей с точки зрения Машинное обучение Отказ
Поэтому нам нужно понять разницу между статистикой и машиной обучение! Статистика делает математически действительные выводы о популяции на основе данных образца. Статистика отвечает на вопрос: «Какие доказательства того, что X связан с Y? «Машинное обучение имеет целью оптимизации прогностической точности, а не вывод. Машинное обучение отвечает на вопрос: «Дано X, какой прогноз мы должны сделать для вас?»
В приведенном ниже примере мы создадим поддельный набор данных с переменными предикторов и двоичной переменной Y. Тогда мы будем выполнять логистическую регрессию с Scikit-Survey и Statsmodels. Мы увидим, что Scikit-Nearn позволяет нам легко настроить модель для оптимизации прогнозирующей мощности. Statsmodels предоставит краткое изложение статистических мер, которые будут очень знакомы тем, кто использовал SAS или R.
Если вам нужно вступление в логистическую регрессию, см. Это пост Finxter.
Создание поддельных данных для модели логистической регрессии
Я пытался использовать некоторые общедоступные данные для этого упражнения, но не нашли ни одного с характеристиками, которые я хотел. Поэтому я решил создать некоторые поддельные данные с помощью Numpy Действительно Есть пост здесь Это объясняет математику и как это сделать в R.
import numpy as np import pandas as pd #The next line is setting the seed for the random number generator so that we get consistent results rg = np.random.default_rng(seed=0) #Create an array with 500 rows and 3 columns X_for_creating_probabilities = rg.normal(size=(500,3))
Создайте массив с удаленным первым столбцом. Удаленная колонна может считаться случайным шумом или в качестве переменной, к которой у нас нет доступа к созданию модели.
X1 = np.delete(X_for_creating_probabilities,0,axis=1) X1[:5] """ array([[-0.13210486, 0.64042265], [-0.53566937, 0.36159505], [ 0.94708096, -0.70373524], [-0.62327446, 0.04132598], [-0.21879166, -1.24591095]]) """
Теперь мы создадим еще два столбца, коррелированные с помощью x1. Наборы данных часто имеют очень коррелированные переменные. Корреляция увеличивает вероятность переоценки. Объединить, чтобы получить один массив.
X2 = X1 + .1 * np.random.normal(size=(500,2)) X_predictors = np.concatenate((X1,X2),axis=1)
Мы хотим создать нашу вариабельную переменную и быть связано с X_PREDICTORS. Для этого мы используем наши данные в качестве входных данных для модели логистической регрессии, чтобы получить вероятности. Затем мы устанавливаем переменную результата, Y, чтобы верно, когда вероятность выше .5.
P = 1 / (1 + np.e**(-np.matmul(X_for_creating_probabilities,[1,1,1]))) Y = P > .5 #About half of cases are True np.mean(Y) #0.498
Теперь разделите данные в обучение и тестовые данные. Мы возьмем логистическую регрессию на тренировочных данных, то увидим, насколько хорошо модель выполняет данные о тренировках.
#Set the first 50 rows to train the model X_train = X_predictors[:50] Y_train = Y[:50] #Set the remaining rows to test the model X_test = X_predictors[50:] Y_test = Y[50:] print(f"X_train: {len(X_train)} X_test: {len(X_test)}") #X_train: 50 X_test: 450
Логистическая регрессия со скопиками
Мы готовы тренироваться и тестировать модели.
Когда мы тренируем модели, нам нужно предпринять шаги, чтобы избежать перенапряжения. Модель машинного обучения может иметь очень точные результаты с данными, используемыми для обучения модели. Но это не означает, что он будет одинаково точным при совершении прогнозов с данными, которые он не видел ранее. Когда модель не может обобщить для новых данных, мы говорим, что она имеет «переполнение» учебных данных. Переоснащение более вероятно, когда на тренировках мало наблюдений, и когда модель использует множество коррелированных предикторов.
Как избежать преодоления? По умолчанию логистическая регрессия Scikit – Nears применяет регулярию. Регуляризация уравновешивает необходимость прогнозирования точности на обучение данных с наказанием на величину модельных коэффициентов. Увеличение пенальти уменьшает коэффициенты и, следовательно, снижает вероятность переоценки. Если наказание слишком велико, тем не менее, он снизит прогнозную мощность как на тренировках, так и на тестовых данных.
from sklearn.linear_model import LogisticRegression scikit_default = LogisticRegression(random_state=0).fit(X_train, Y_train) print(f"intecept: {scikit_default.intercept_} coeficients: {scikit_default.coef_}") print(f"train accuracy: {scikit_default.score(X_train, Y_train)}") print(f"test accuracy: {scikit_default.score(X_test, Y_test)}") """ Results will vary slightly, even when you set random_state. intecept: [-0.44526823] coeficients: [[0.50031563 0.79636504 0.82047214 0.83635656]] train accuracy: 0.8 test accuracy: 0.8088888888888889 """
Мы можем установить выключение регуляризации, установив штраф так, как никто. Применение регуляризации уменьшает величину коэффициентов. Установка наказания на не увеличит коэффициенты. Обратите внимание, что точность на тестовые данные уменьшается. Это указывает на нашу модель переполняет данные тренировки.
from sklearn.linear_model import LogisticRegression scikit_no_penalty = LogisticRegression(random_state=0,penalty='none').fit(X_train, Y_train) print(f"intecept: {scikit_no_penalty.intercept_} coeficients: {scikit_no_penalty.coef_}") print(f"train accuracy: {scikit_no_penalty.score(X_train, Y_train)}") print(f"test accuracy: {scikit_no_penalty.score(X_test, Y_test)}") """ intecept: [-0.63388911] coeficients: [[-3.59878438 0.70813119 5.10660019 1.29684873]] train accuracy: 0.82 test accuracy: 0.7888888888888889 """
C 1,0 по умолчанию. Меньшие значения C увеличивают регуляризацию, поэтому, если мы устанавливаем значение .1 Мы уменьшаем величину коэффициентов.
from sklearn.linear_model import LogisticRegression scikit_bigger_penalty = LogisticRegression(random_state=0,C=.1).fit(X_train, Y_train) print(f"intecept: {scikit_bigger_penalty.intercept_} \ coeficients: {scikit_bigger_penalty.coef_}") print(f"train accuracy: {scikit_bigger_penalty.score(X_train, Y_train)}") print(f"test accuracy: {scikit_bigger_penalty.score(X_test, Y_test)}") """ intecept: [-0.13102803] coeficients: [[0.3021235 0.3919277 0.34359251 0.40332636]] train accuracy: 0.8 test accuracy: 0.8066666666666666 """
Приятно иметь возможность настроить коэффициент сглаживания, но как мы определим оптимальное значение? GridSearchcv Scikit-Surrey обеспечивает эффективный, но простой в использовании метод для выбора оптимального значения. «Поиск сетки» в Gridsearch CV означает, что мы поставляем Словарь С знаниями параметров, которые мы хотим проверить. Модель подходит со всеми комбинациями этих значений. Если у нас есть 4 возможных значения C и 2 возможных значений для решателя, мы будем искать все комбинации.
Gridsearchcv ищет через эту сетку
0.01 | Ньютон-Кг. |
0.10 | Ньютон-Кг. |
1.00 | Ньютон-Кг. |
10.00 | Ньютон-Кг. |
0.01 | lbfgs. |
0.10 | lbfgs. |
1.00 | lbfgs. |
10.00 | lbfgs. |
«CV» в GridSearch CV обозначает C росс- V Оглашение. Перекрестная проверка – это метод сегментирования данных тренировки. Модель обучается всем, кроме одной из сегментов, и оставшийся сегмент подтверждают модель.
1-я итерация | Проверка | Тренироваться | Тренироваться | Тренироваться | Тренироваться |
2 итерация | Тренироваться | Проверка | Тренироваться | Тренироваться | Тренироваться |
3 итерация | Тренироваться | Тренироваться | Проверка | Тренироваться | Тренироваться |
4 итерация | Тренироваться | Тренироваться | Тренироваться | Проверка | Тренироваться |
5-я итерация | Тренироваться | Тренироваться | Тренироваться | Тренироваться | Проверка |
Гридсея и перекрестная проверка работают в комбинации. GRIDSEARCHCV ITERATES через значения C и Solver для разных тестовых и тренировок сегментов. Алгоритм выбирает лучшие характеристики на основе оценки на сегментах проверки.
Это позволяет нам определить, какие значения C и Solver работают лучше всего для наших учебных данных. Это то, как Scikit – учиться помогает нам оптимизировать прогнозную точность.
Давайте увидимся в действии.
from sklearn.model_selection import GridSearchCV parameters = {'C':[.01, .1, 1, 10],'solver':['newton-cg','lbfgs']} Logistic = LogisticRegression(random_state=0) scikit_GridSearchCV = GridSearchCV(Logistic, parameters) scikit_GridSearchCV.fit(X_train, Y_train) print(f"best estimator: {scikit_GridSearchCV.best_estimator_}") #best estimator: LogisticRegression(C=0.1, random_state=0, solver='newton-cg')
Используйте метод оценки Возвращает среднюю точность на данные тестовые данные и этикетки. Точность – это процент наблюдений, правильно предсказанных.
print(f"train accuracy: {scikit_GridSearchCV.score(X_train, Y_train)}") print(f"test accuracy: {scikit_GridSearchCV.score(X_test, Y_test)}") """ train accuracy: 0.82 test accuracy: 0.8133333333333334 """
Логистическая регрессия со статусами
Теперь давайте попробуем то же самое, но с Statsmodels. С Scikit – учиться, чтобы выключить регуляризацию мы набор пенальти = «никто»
, но с помощью Statsmodels регуляризация выключается по умолчанию. Квирк, чтобы посмотреть на то, что стандартмодели не включают в себя перехват по умолчанию. Чтобы включить перехват, мы используем метод SM.ADD_Constant.
import statsmodels.api as sm #adding constant to X X_train_with_constant = sm.add_constant(X_train) X_test_with_constant = sm.add_constant(X_test) # building the model and fitting the data sm_model_all_predictors = sm.Logit(Y_train, X_train_with_constant).fit() # printing the summary table print(sm_model_all_predictors.params) """ Optimization terminated successfully. Current function value: 0.446973 Iterations 7 [-0.57361523 -2.00207425 1.28872367 3.53734636 0.77494424] """
Если вы привыкли делать логистическую регрессию в R или SAS, что придет дальше, будет знакомым. После того, как мы обучаем логистическую модель регрессии со стандартами, суммарный метод будет легко создавать таблицу с статистическими мерами, включая P-значения и доверительные интервалы.
sm_model_all_predictors.summary()
Деп. Переменная: | y | Нет. Наблюдения: | 50.000000 |
Модель: | Логит | Остатки DF: | 45.000000 |
Метод: | Мнение | Модель DF: | 4.000000 |
Дата: | Чт, 04 февраля 2021 | Pseudo r-squ. : | 0.384600 |
Время: | 14:33:19. | Журнал-вероятность: | -21.228000 |
Конвергент: | Правда | LL-NULL: | -34.497000 |
Тип ковариации: | нерешительный | Llr p-значение: | 0.000025 |
коэффициент | std err. | z | P> | z | | [0.025 | 0.975] | |
конститут | -0.7084 | 0.478 | -1.482 | 0.138 | -1.645 | 0.228 |
х1. | 5.5486 | 4.483 | 1.238 | 0.216 | -3.237 | 14.335 |
х2. | 10.2566 | 5.686 | 1.804 | 0.071 | -0.887 | 21.400 |
x3. | -3.9137 | 4.295 | -0.911 | 0.362 | -12.333 | 4.505 |
х4. | -7.8510 | 5.364 | -1.464 | 0.143 | -18.364 | 2.662 |
Здесь здесь много, но мы сосредоточимся на втором столе с коэффициентами.
Первый столбец показывает значение для коэффициента. Четвертая колонна с заголовком P> | z |, показывает значения p. P-значение является измерением вероятности, а P-значения выше .05 часто рассматриваются: «Не статистически значим. «Ни один из предикторов не считается статистически значимым! Это потому, что у нас есть относительно небольшое количество наблюдений в наших учебных данных, и поскольку предикторы сильно коррелируют. Некоторые статистические пакеты, такие как R и SAS, имеют встроенные методы для выбора функций для включения в модели, основанные на которых предсказалки имеют низкие (значимые) P-значения, но, к сожалению, это не доступно в Statsmodels.
Если мы попробуем еще раз только с x1 и x2, мы получим совершенно другой результат, причем очень низкие значения p для x1 и x2, что означает, что доказательства взаимоотношений с зависимой переменной является статистически значимым. Однако мы обманываем – потому что мы создали данные, мы знаем, что нам нужен только x1 и x2.
sm_model_x1_x2 = sm.Logit(Y_train, X_train_with_constant[:,:3]).fit() sm_model_x1_x2.summary()
Теперь мы видим X1 и X2 как статистически значимыми.
У Statsmodels не имеет такой же метод точности, который у нас есть в Scikit – учиться. Мы будем использовать метод прогнозирования для прогнозирования вероятностей. Тогда мы будем использовать правило решения, что вероятности выше .5 верны, и все остальные ложные. Это то же самое правило, используемое, когда Scikit – учиться рассчитывает точность.
all_predicted_train = sm_model_all_predictors.predict(X_train_with_constant)>.5 all_predicted_test = sm_model_all_predictors.predict(X_test_with_constant)>.5 x1_x2_predicted_train = sm_model_x1_x2.predict(X_train_with_constant[:,:3])>.5 x1_x2_predicted_test = sm_model_x1_x2.predict(X_test_with_constant[:,:3])>.5 #calculate the accuracy print(f"train: {(Y_train==all_predicted_train).mean()} and test: {(Y_test==all_predicted_test).mean()}") print(f"train: {(Y_train==x1_x2_predicted_train).mean()} and test: {(Y_test==x1_x2_predicted_test).mean()}") """ train: 0.8 and test: 0.8066666666666666 train: 0.8 and test: 0.8111111111111111 """
Подводя итоги результатов
Давайте создадим dataframe с результатами. Модели имеют одинаковую точность на учебных данных, но разные результаты на тестовые данные. Модели со всеми предикторами и без сглаживания имеют наихудшую точность тестирования, что предполагает, что у них есть перенапряжение на тренировочные данные, и поэтому не обогатим новых данных.
Даже если мы используем лучшие методы создания нашей модели, все еще есть шансы, участвующие в том, насколько хорошо он обобщает данные теста.
lst = [['scikit-learn','default', scikit_default.score(X_train, Y_train),scikit_default.score(X_test, Y_test)], ['scikit-learn','no penalty', scikit_no_penalty.score(X_train, Y_train),scikit_no_penalty.score(X_test, Y_test)], ['scikit-learn','bigger penalty', scikit_bigger_penalty.score(X_train, Y_train),scikit_bigger_penalty.score(X_test, Y_test)], ['scikit-learn','GridSearchCV', scikit_GridSearchCV.score(X_train, Y_train),scikit_GridSearchCV.score(X_test, Y_test)], ['statsmodels','include intercept and all predictors', (Y_train==all_predicted_train).mean(),(Y_test==all_predicted_test).mean()], ['statsmodels','include intercept and x1 and x2', (Y_train==x1_x2_predicted_train).mean(),(Y_test==x1_x2_predicted_test).mean()] ] df = pd.DataFrame(lst, columns =['package', 'setting','train accuracy','test accuracy']) df
Scikit-Surve | дефолт | 0 | 0.808889 | 0.80 |
Scikit-Surve | Нет наказания | 1 | 0.764444 | 0.78 |
Scikit-Surve | больший наказание | 2 | 0.813333 | 0.82 |
Scikit-Surve | Gridsearchcv. | 3 | 0.808889 | 0.80 |
statsmodels. | включить перехват и Все предикторы | 4 | 0.764444 | 0.78 |
statsmodels. | включить перехват и x1 и х2. | 5 | 0.811111 | 0.80 |
Scikit-Surlection против Statsmodels
Upshot – это то, что вы должны использовать Scikit – учиться для логистической регрессии, если вам не нужна результаты статистики, предоставленные StatsModels.
Вот стол самых актуальных сходств и различий:
Регуляризация | Не использует регуляризацию по умолчанию | Использует регуляризацию L2 по умолчанию, но регуляризация может быть отключена с использованием |
Гиперпараметрическая настройка | Пользователь должен будет написать строки кода для настройки параметра регулирования | Gridsearchcv позволяет легко настроить параметр регуляризации |
Перехватить | Используйте метод Add_Constant, чтобы включить перехват | Включает в себя перехватить по умолчанию |
Оценка модели | Сводный метод показывает P-значения, доверительные интервалы и другие статистические меры | Метод оценки доклады Точность прогнозирования |
Когда вы должны использовать это? | Для статистического вывода. | Для точных прогнозов |
Сравнение с R и SAS | Похожий | Другой |
Вот и все сейчас! Пожалуйста, проверьте мою другую работу в OnliceTableau.com и мой новый сайт DatascienceRills.com Отказ
Оригинал: “https://blog.finxter.com/logistic-regression-scikit-learn-vs-statsmodels/”