Rr‑statistics.co

VIF / Multicollinearity Interpreter

When two predictors in a regression are highly correlated, their coefficient estimates become unstable and hard to interpret. The Variance Inflation Factor (VIF) measures how bad it is. Paste a vif() table or correlation matrix to get per-predictor VIF, tolerance, SE inflation, condition number, and which variables to drop or combine.

i New to VIFs? Read the 3-min primer

What VIF measures. The variance inflation factor for predictor j is VIF_j = 1 / (1 - R^2_j), where R^2_j is from regressing predictor j on every other predictor in the model. It tells you how much the sampling variance of beta_hat_j is inflated by the linear association between j and the rest. sqrt(VIF_j) is the multiplicative inflation on the standard error: a VIF of 4 doubles the SE compared with the perfectly orthogonal case.

Reading the flags. A common rule of thumb is VIF below 5 is fine, 5 to 10 is borderline, and above 10 is problematic. These are not laws of physics: a VIF of 8 in an exploratory study with a large sample can be tolerable, while a VIF of 4 in a small sample can already be a red flag. Tolerance, the reciprocal 1 / VIF, is the same number on a 0 to 1 scale and is sometimes preferred in textbooks.

Beyond pairwise correlation. Two predictors can each have a low pairwise correlation with every other predictor and still produce a high VIF, because VIF picks up on multivariate dependencies (e.g. one predictor is well predicted by a linear combination of three others). For factors with more than two levels the textbook VIF is not directly comparable across terms; use GVIF^(1/(2*Df)) instead, which puts everything on the same SE-inflation scale.

The condition number. An alternative diagnostic, kappa = sqrt(lambda_max / lambda_min) from the eigenvalues of the scaled correlation matrix, summarizes the overall conditioning of X. Values above 30 are commonly cited as a warning, above 100 as severe. VIF is per-predictor; the condition number is per-design.

Parses car::vif() and cor() output, traffic-light flags, condition number, GVIF support, R code, runs in your browser

Try a real-world example to load.

Awaiting paste…
Max VIF -
R code RUNNABLE
R Reproduce in R
# Compute and inspect VIFs for a linear model library(car) fit <- lm(mpg ~ wt + hp + disp + cyl, data = mtcars) vif(fit) # variance inflation factors 1 / vif(fit) # tolerance (1/VIF) sqrt(vif(fit)) # SE inflation factor # Design-level condition number kappa(model.matrix(fit), exact = TRUE) # When VIF > 10, options: # - drop one of the colinear pair / triple # - combine into an index (e.g. PCA, sum) # - switch to a regularized fit: # library(glmnet) # cv <- cv.glmnet(model.matrix(fit)[, -1], mtcars$mpg, alpha = 0)

        
VIF bar chart VISUAL
VIF per predictor; dashed lines mark the borderline (5) and problematic (10) thresholds.
Paste a vif() block or correlation matrix to render.
5
10
Inference

Read more Anatomy of a VIF
VIF for predictor j: VIF_j = 1 / (1 - R^2_j) where R^2_j is from lm(x_j ~ x_1 + ... + x_(j-1) + x_(j+1) + ... + x_p) Tolerance_j = 1 / VIF_j
Where the inflation comes from. If you regress predictor j on every other predictor, you get an R^2 that measures how well j is "explained" by the rest. The closer that R^2 is to 1, the closer 1 - R^2_j is to zero, and the larger the variance of beta_hat_j. Tolerance is just the reciprocal on a 0 to 1 scale.
SE inflation: SE_actual = SE_orthogonal * sqrt(VIF) VIF = 5 -> SE x 2.236 VIF = 10 -> SE x 3.162
What inflation looks like. The standard error of beta_hat_j is multiplied by sqrt(VIF_j) compared with what it would be if predictor j were perfectly uncorrelated with the others. A VIF of 5 makes intervals 2.24 times as wide; a VIF of 10 makes them 3.16 times as wide. p-values follow.
Computing VIF from a correlation matrix: R = cor(predictors) VIF_j = (R^-1)[j, j] # j-th diagonal of inverse
Algebra shortcut. If you only have cor(predictors), you do not need to refit p separate regressions. The j-th diagonal of solve(R) equals VIF_j. The tool uses Gauss-Jordan inversion of the pasted matrix; if the matrix is rank deficient, that is itself a sign of perfect collinearity.
Condition number: kappa = sqrt(lambda_max / lambda_min) where lambdas are eigenvalues of R
Design-level diagnostic. While VIF is per-predictor, kappa summarizes the overall conditioning. kappa < 10: well conditioned. 10 to 30: moderate concern. > 30: serious. > 100: severe; numerical instability is plausible. R's kappa(model.matrix(fit), exact = TRUE) returns this on the design matrix; this tool computes the version on the predictor correlation matrix.
Generalized VIF (Fox & Monette 1992): GVIF^(1/(2*Df)) - Use this column to compare across factors of different df - Squared, GVIF^(1/Df) is comparable to a regular VIF
Why GVIF. A factor with k+1 levels enters the design matrix as k columns, so a single "VIF" is undefined. Fox & Monette (1992) define a GVIF on the joint set of columns; the comparable inflation factor across terms is GVIF^(1/(2*Df)). A GVIF^(1/(2*Df)) of 2 corresponds, roughly, to a VIF of 4 on a continuous predictor.
Caveats When this is the wrong tool
If you have…
Use instead
A single predictor
VIF is undefined; there is nothing for predictor j to be collinear with. Just check that predictor's marginal distribution.
An intercept-only or saturated model
Very small samples or perfectly aliased predictors will return VIF = NaN or Inf. Drop the redundant column first; the parser flags VIF below 1 and infinity values.
Centered interaction terms reported as colinear
Apparent VIFs explode for raw interactions because x and x:z are mechanically linked. Center the components before fitting; the residual VIF is the one to read.
Multilevel / clustered data
VIF on a fixed-effect-only fit ignores within-cluster correlation. Switch to a mixed-effects model and inspect the variance components there; high VIF inside a fixed-effects-only fit is rarely the real issue.
Truly stuck with collinearity
Switch to ridge regression (glmnet with alpha = 0) or principal-components regression (pls); both deliver stable coefficients at the cost of bias.
Further reading

Numerical notes: VIF parser handles named vectors, matrix output (with row labels), GVIF tables (3 columns: GVIF, Df, GVIF^(1/(2*Df))), and "Inf" / "NaN" tokens. Correlation-matrix mode inverts the predictor submatrix via Gauss-Jordan with partial pivoting and reports kappa from the QR-based eigendecomposition. Cross-checked against car::vif() and base::kappa() on mtcars.