Фактор инфляции дисперсии в Python
Я пытаюсь рассчитать фактор инфляции дисперсии (VIF) для каждого столбца в простом наборе данных на Python.
a b c d
1 2 4 4
1 2 6 3
2 3 7 4
3 2 8 5
4 1 9 4Я уже сделал это в R с помощью функции vif из [библиотеки usdm](https://cran.r-project.org/web/packages/usdm/usdm.pdf), что дало следующие результаты:a <- c(1, 1, 2, 3, 4)
b <- c(2, 2, 3, 2, 1)
c <- c(4, 6, 7, 8, 9)
d <- c(4, 3, 4, 5, 4)
df <- data.frame(a, b, c, d)
vif_df <- vif(df)
print(vif_df)
Variables VIF
a 22.95
b 3.00
c 12.95
d 3.00Однако, когда я делаю то же самое в Python, используя функцию VIF в statsmodel, мои результаты следующие:
Полученные результаты существенно различаются, хотя входные данные одинаковы. Как правило, результаты, полученные с использованием функции VIF из пакета statsmodel, кажутся неверными, но я не уверен, связано ли это с тем, как я вызываю эту функцию, или это проблема самой функции.
Я надеялся, что кто-нибудь сможет помочь мне понять, неправильно ли я вызывал функцию statsmodel или объяснить расхождения в результатах. Если это проблема с функцией, то есть ли альтернативы VIF на Python?
Как упоминалось другими и в этом посте от автора функции Йозефа Перктольда, функция variance_inflation_factor требует наличия константы в матрице объясняющих переменных. Можно использовать add_constant из statsmodels, чтобы добавить необходимую константу к датафрейму перед передачей его значений в функцию.
Я верю, вы также можете добавить константу в крайнюю правую колонку dataframe, используя
Исходный код довольно лаконичный:
Также довольно просто изменить код, чтобы вернуть все VIF в виде серии:
Согласно решению @T_T, можно также просто сделать следующее:
Я считаю, что причина этого заключается в отличии OLS в Python. OLS, который используется при расчете фактора инфляции дисперсии в Python, по умолчанию не добавляет константу. Однако добавление константы действительно желательно.
Чтобы добавить еще один столбец к вашей матрице, ck, заполненный единицами для представления константы, это будет константа уравнения пересечения. После этого ваши значения должны правильно совпасть.
Для тех, кто придет сюда в будущем (как я):
Этот код дает
[EDIT]
In response to a comment, I tried to use DataFrame as much as possible (numpy is required to invert a matrix).
The code gives
_TT_T
1,23817 silver badges23 bronze badges
3
In case you don't wanna deal with variance_inflation_factor and add_constant. Please consider the following two functions.
1. Use formula in statasmodels:
2. Use LinearRegression in sklearn:
Example:
answered Feb 24, 2019 at 23:06
stevensteven
2,32921 silver badges40 bronze badges
3
Хотя уже поздно, я вношу некоторые изменения в данном ответе. Чтобы получить лучший набор после удаления мультиколлинеарности, если мы используем решение @Chef1075, тогда мы потеряем переменные, которые коррелируют. Нам нужно удалить только одну из них. Для этого я пришел к следующему решению, используя ответ @steve:
answered Apr 26, 2020 at 13:36
asteroidasteroid
591 silver badge9 bronze badges
4
Example for Boston Data:
VIF (Коэффициент инфляции дисперсии) вычисляется с помощью вспомогательной регрессии, поэтому не зависит от фактического соответствия модели.
See below:
answered Aug 18, 2017 at 6:22
s_mjs_mj
54011 silver badges28 bronze badges
Я написал эту функцию, основываясь на некоторых других публикациях, которые видел на Stack Overflow и CrossValidated. Она отображает признаки, которые превышают порог, и возвращает новый DataFrame без этих признаков.
answered Jul 13, 2018 at 16:35
Chef1075Chef1075
2,6649 gold badges40 silver badges57 bronze badges
2
here code using dataframe python:
To create data
import numpy as np
import scipy as sp
a = [1, 1, 2, 3, 4]
b = [2, 2, 3, 2, 1]
c = [4, 6, 7, 8, 9]
d = [4, 3, 4, 5, 4]
To create dataframe
import pandas as pd
data = pd.DataFrame()
data["a"] = a
data["b"] = b
data["c"] = c
data["d"] = d
Calculate VIF
cc = np.corrcoef(data, rowvar=False)
VIF = np.linalg.inv(cc)
VIF.diagonal()
Result
array([22.95, 3. , 12.95, 3. ])
answered Jan 24, 2020 at 15:23
Еще одно решение. Следующий код дает точно такие же результаты VIF, как и пакет R car.
I've tested it on the titanic dataset. You can get the full example here: https://github.com/tulicsgabriel/Variance-Inflation-Factor-VIF-
answered Dec 1, 2021 at 23:00
b0zg0rb0zg0r
1051 silver badge7 bronze badges
Last updated