Categories &

Functions List

Function Reference: fitlm

statistics: mdl = fitlm (X, y)
statistics: mdl = fitlm (tbl)
statistics: mdl = fitlm (tbl, ResponseVarName)
statistics: mdl = fitlm (tbl, y)
statistics: mdl = fitlm (…, modelspec)
statistics: mdl = fitlm (…, Name, Value, …)

Fit a linear regression model to data and return a LinearModel object.

The returned object stores the fitted coefficients, their standard errors, t-statistics, and p-values, summary statistics of the fit (R^2, RMSE, F-statistic, etc.), and the residuals and diagnostics of the fit, and exposes methods such as predict, plotResiduals, coefTest, addTerms, and removeTerms for further analysis of the fitted model.

Basic Syntax

mdl = fitlm (X, y) fits a linear regression model of the response y to the predictor data X. Unless removed via the 'Intercept' option, the fitted model contains a constant (intercept) term and one linear term for every column of X.

  • X is an N×P numeric or logical matrix of predictor data, where rows correspond to observations and columns correspond to variables. By default, the predictors are named 'x1', 'x2', …, 'xP'.
  • X can also be a categorical vector of length N, representing a single categorical predictor. In this case y must be supplied as the next argument, and the predictor is named 'x1' by default.
  • y is an N×1 numeric or logical vector of response values, and must have the same number of observations (rows) as X. By default, the response is named 'y'.

mdl = fitlm (tbl) fits a linear regression model using the variables contained in the table (or dataset) tbl. By default, the last variable in tbl is used as the response and all other variables are used as predictors. Variables that are categorical arrays, cell arrays of character vectors, or logical arrays are automatically treated as categorical predictors.

mdl = fitlm (tbl, ResponseVarName) fits a model using the variable named ResponseVarName in tbl as the response, and all remaining variables in tbl as predictors.

mdl = fitlm (tbl, y) fits a model using the variables in tbl as predictors and the external numeric vector y as the response. y must have height (tbl) elements.

Model Specification

mdl = fitlm (…, modelspec) additionally specifies the terms of the model to fit, using any of the input combinations shown above. modelspec can be any of the following.

ValueDescription
'constant'Model contains only an intercept term.
'linear'Model contains an intercept and one term for each predictor variable. This is the default when modelspec is not specified.
'interactions'Model contains an intercept, all linear terms, and all pairwise products of distinct predictor variables (no squared terms).
'purequadratic'Model contains an intercept, all linear terms, and all squared terms.
'quadratic'Model contains an intercept, all linear terms, all pairwise products of distinct predictor variables, and all squared terms.
'full'Model contains an intercept and all terms up to and including the full P-way interaction of the predictor variables, i.e. every combination of one or more distinct predictors.
terms matrixA T×P or T×(P+1) numeric matrix, where T is the number of terms and P is the number of predictor variables. Each row represents one term, and the value in column j is the exponent to which predictor j is raised in that term; a row of all zeros represents the intercept. If a T×(P+1) matrix is supplied, its last column (representing the response variable) must be all zeros.
Wilkinson formulaA character vector of the form 'y ~ terms' describing the response and predictor terms using Wilkinson notation. The variable name to the left of '~' is used as the response, overriding any response implied elsewhere in the call.

Source Code: fitlm

When modelspec is given as a Wilkinson formula, the following operators may be used on its right-hand side to build up terms:

OperatorMeaningExample
+add a term'x1 + x2' adds x1 and x2 as separate terms
-remove a term'x1*x2 - x1:x2' removes the interaction, leaving only x1 and x2
*cross two terms'x1*x2' expands to x1, x2, x1:x2
:interaction only'x1:x2' adds only the interaction term between x1 and x2
^power / crossing limit'x^2' adds x and x^2; '(x1+x2)^2' expands to x1, x2, x1:x2
-1remove intercept'x1 + x2 - 1' fits the model without a constant term

Source Code: fitlm

A formula includes an intercept term by default; append '- 1' to the formula to omit it. For a categorical predictor, fitlm generates the necessary indicator (dummy) variables automatically from the formula, so a formula does not need to be changed when the underlying design matrix changes.

Options

mdl = fitlm (…, Name, Value, …) specifies additional options using one or more Name-Value pair arguments, which may be combined with modelspec or used on their own.

NameValue
'Intercept'A logical scalar indicating whether to include a constant (intercept) term in the model. Default is true. This option only applies when modelspec is a character vector model name (or omitted); it is ignored when modelspec is a terms matrix or a Wilkinson formula, where the intercept is instead controlled by the matrix/formula itself.
'Weights'A numeric vector of nonnegative observation weights, with one element per observation, used to fit a weighted least squares model. Default is a vector of ones, i.e. an unweighted ordinary least squares fit.
'Exclude'A numeric or logical vector specifying observations to exclude from the fit, given as row indices into the original data or as a logical mask the same length as the number of observations. Excluded observations, together with any observation that contains a missing (NaN) value in a predictor or the response, are recorded in the ObservationInfo property of the fitted model but do not contribute to the fitted coefficients or summary statistics.
'CategoricalVars'Specifies which predictor variables are treated as categorical, given as a vector of column indices, a logical vector, or a cell array of variable names (only valid for table input). Each categorical predictor with L distinct categories is expanded into L-1 indicator (dummy) variables, using the first category (in sorted or original order) as the reference level that is omitted from the design matrix. Variables that are already categorical arrays or cell arrays of character vectors are always treated as categorical, regardless of this option.
'VarNames'A cell array of character vectors naming the predictor and response variables, listed in order with the response variable name last, e.g. {"x1", "x2", "y"} for two predictors. Only applies when X and y (or a categorical vector and y) are supplied directly, since table variables already carry their own names. By default, predictors are named 'x1', 'x2', etc. and the response is named 'y'.
'ResponseVar'A character vector naming the response variable, used to override the response variable name that would otherwise be inferred (the last table variable, or 'y' for matrix input).
'PredictorVars'A cell array of character vectors naming which variables in tbl to use as predictors. By default, all variables in tbl other than the response variable are used as predictors.
'RobustOpts'Selects ordinary least squares or robust regression fitting. This value can be 'off' (default, ordinary least squares), 'on' (robust fitting using the 'bisquare' weighting function), the name of one of the weighting functions below, a function handle for a custom weighting function, or a scalar structure with fields RobustWgtFun and Tune specifying the weighting function and its tuning constant. Robust fitting uses Iteratively Reweighted Least Squares (IRLS), refitting the model with updated observation weights until the coefficients converge. Supported weighting function names: 'andrews', 'bisquare', 'cauchy', 'fair', 'huber', 'logistic', 'ols', 'talwar', 'welsch', each with its own default tuning constant.

Source Code: fitlm

Algorithm

fitlm solves the (weighted) least squares problem by applying a pivoted QR decomposition to the design matrix, which remains numerically stable even when predictors are collinear; coefficients corresponding to columns beyond the numerically detected rank of the design matrix are set to zero. Robust fits refine this ordinary least squares solution using IRLS as described above. Observations with missing values in any variable used by the model, or explicitly excluded via 'Exclude', are omitted from the fit entirely and flagged in ObservationInfo, but are otherwise not counted as errors.

mdl is returned as a LinearModel object. If 'RobustOpts' is anything other than 'off', the returned model is a robust fit rather than an ordinary least squares fit, and its Robust property is populated accordingly.

A categorical predictor expands to indicator columns, one per level bar the reference level, which the intercept carries. When the model has no intercept, the first categorical predictor is given an indicator for every one of its levels instead, so that its coefficients are the group means; any further categorical predictor stays reference coded, which keeps the design full rank. This differs from MATLAB, which omits the reference level whether or not an intercept is present and so cannot fit the reference group at all – for a three-level grouping variable g, MATLAB fits y ~ g - 1 with two coefficients, predicts exactly 0 for every observation in the omitted group, and reports a negative R^2. This implementation returns three coefficients, one per group.

See also: LinearModel

Source Code: fitlm

The simplest call: a matrix of predictor data and a response vector. Ten students study for varying numbers of hours before an exam, with their resulting scores recorded. With no modelspec, fitlm fits an intercept plus one linear term per column of the predictor matrix.

 Hours = [1;2;3;4;5;6;7;8;9;10];
 Score = [52;55;61;64;70;73;77;81;85;90];
 mdl = fitlm (Hours, Score)
mdl =

  Linear regression model:
      y ~ 1 + x1

  Estimated Coefficients:

  2x4 table

                   Estimate       SE         tStat       pValue       
                   ________    _________    _______    ___________    

    (Intercept)     47.6667     0.488866    97.5046    1.36679e-13    
    x1              4.20606    0.0787879    53.3846    1.68076e-11    


Number of observations: 10, Error degrees of freedom: 8
Root Mean Squared Error: 0.715626
R-squared: 0.997201,  Adjusted R-Squared: 0.996851
F-statistic vs. constant model: 2849.92, p-value = 1.68076e-11

Table input with a Wilkinson formula, and a categorical predictor detected automatically from its cell-array type. Nine stores in three regions report ad spend and sales. Region is a cell array of strings, so it is expanded into indicator columns without needing 'CategoricalVars' to say so explicitly.

 AdSpend = [10;20;30;15;25;35;12;22;32];
 Region  = {'North';'North';'North';'South';'South';'South'; ...
            'East';'East';'East'};
 Sales   = [15;18;24;20;27;33;12;19;26];
 T = table (AdSpend, Region, Sales, ...
   'VariableNames', {'AdSpend','Region','Sales'});
 mdl = fitlm (T, 'Sales ~ AdSpend + Region')
mdl =

  Linear regression model:
      Sales ~ 1 + AdSpend + Region

  Estimated Coefficients:

  4x4 table

                    Estimate       SE         tStat        pValue       
                    ________    _________    ________    ___________    

    (Intercept)            7      1.31656     5.31688     0.00314819    
    AdSpend              0.6    0.0537484     11.1631    0.000100633    
    Region_South     4.66667      1.10805      4.2116     0.00839532    
    Region_East         -1.2      1.08033    -1.11077       0.317206    


Number of observations: 9, Error degrees of freedom: 5
Root Mean Squared Error: 1.31656
R-squared: 0.974675,  Adjusted R-Squared: 0.959481
F-statistic vs. constant model: 64.1453, p-value = 0.000206027

A terms matrix used directly as modelspec, instead of a keyword or a formula string. Weekly sales depend on temperature and humidity. Each row of the terms matrix is one term, and each column is the exponent of one predictor in that term -- here, both main effects plus their interaction.

 Temp     = [60;65;70;75;80;85;90];
 Humidity = [30;35;40;45;50;55;60];
 Sales    = [200;230;260;300;340;370;410];
 T_terms  = [0 0; 1 0; 0 1; 1 1];
 mdl = fitlm ([Temp, Humidity], Sales, T_terms)
mdl =

  Linear regression model:
      y ~ 1 + x1*x2

  Estimated Coefficients:

  4x4 table

                   Estimate        SE         tStat       pValue     
                   _________    _________    ________    ________    

    (Intercept)            0            0         NaN         NaN    
    x1              0.968254      1.03498    0.935532    0.402478    
    x2               3.24603      2.92901     1.10823    0.329908    
    x1:x2          0.0238095    0.0157935     1.50756    0.206151    


Number of observations: 7, Error degrees of freedom: 4
Root Mean Squared Error: 3.61873
R-squared: 0.998507,  Adjusted R-Squared: 0.997761
F-statistic vs. constant model: 1337.64, p-value = 2.22888e-06

Observation weights and an excluded observation used together. Ten observations follow a roughly linear trend, except one clear outlier. 'Exclude' leaves that observation out of the fit entirely, while 'Weights' gives the remaining observations unequal influence on the fit.

 x = [1;2;3;4;5;6;7;8;9;10];
 y = [10;13;15;40;22;25;29;33;35;39];
 w = [1;1;2;1;2;1;2;1;2;1];
 mdl = fitlm (x, y, 'Weights', w, 'Exclude', 4)
mdl =

  Linear regression model:
      y ~ 1 + x1

  Estimated Coefficients:

  2x4 table

                   Estimate       SE        tStat       pValue       
                   ________    ________    _______    ___________    

    (Intercept)      5.8865    0.468228    12.5719    4.64941e-06    
    x1              3.27301    0.073125    44.7591     7.2593e-10    


Number of observations: 9, Error degrees of freedom: 7
Root Mean Squared Error: 0.732374
R-squared: 0.996518,  Adjusted R-Squared: 0.996021
F-statistic vs. constant model: 2003.37, p-value = 7.2593e-10

Robust regression versus an ordinary fit, on data with a planted outlier. Twelve observations follow a linear trend with a small amount of noise, except one observation shifted far off the line. The ordinary fit is pulled toward the outlier; the robust fit, using iteratively reweighted least squares with the bisquare weighting function, downweights it instead.

 x = (1:12)';
 y = 3 + 2*x + 0.5*sin (x);
 y(10) = y(10) + 30;
 mdl_ols    = fitlm (x, y)
mdl_ols =

  Linear regression model:
      y ~ 1 + x1

  Estimated Coefficients:

  2x4 table

                   Estimate       SE        tStat        pValue      
                   ________    ________    ________    __________    

    (Intercept)      1.0006     5.30224    0.188712      0.854093    
    x1              2.69141    0.720433     3.73583    0.00387304    


Number of observations: 12, Error degrees of freedom: 10
Root Mean Squared Error: 8.61512
R-squared: 0.582575,  Adjusted R-Squared: 0.540833
F-statistic vs. constant model: 13.9564, p-value = 0.00387304
 mdl_robust = fitlm (x, y, 'RobustOpts', 'bisquare')
mdl_robust =

  Linear regression model (robust fit):
      y ~ 1 + x1

  Estimated Coefficients:

  2x4 table

                   Estimate       SE        tStat       pValue       
                   ________    ________    _______    ___________    

    (Intercept)     3.27409     2.66115    1.23033       0.246729    
    x1               1.9591    0.361579    5.41819    0.000293756    


Number of observations: 12, Error degrees of freedom: 10
Root Mean Squared Error: 4.32385
R-squared: 0.769188,  Adjusted R-Squared: 0.746107
F-statistic vs. constant model: 33.3253, p-value = 0.000179488

Selecting specific predictors and a specific response by name from a larger table, using the carsmall data set. 'ResponseVar' and 'PredictorVars' pick out exactly which columns of the table to use, regardless of how many other variables the table also contains.

 load carsmall
 T = table (Weight, Acceleration, MPG);
 mdl = fitlm (T, 'ResponseVar', 'MPG', ...
   'PredictorVars', {'Weight', 'Acceleration'})
mdl =

  Linear regression model:
      MPG ~ 1 + Weight + Acceleration

  Estimated Coefficients:

  3x4 table

                     Estimate          SE          tStat        pValue       
                    ___________    ___________    ________    ___________    

    (Intercept)         45.1546        3.46591     13.0282    1.62665e-22    
    Weight          -0.00824745    0.000598364    -13.7833    5.31651e-24    
    Acceleration       0.196941       0.147426     1.33586       0.184927    


Number of observations: 94, Error degrees of freedom: 91
Root Mean Squared Error: 4.11698
R-squared: 0.743159,  Adjusted R-Squared: 0.737514
F-statistic vs. constant model: 131.652, p-value = 1.37959e-27
 y =  [ 8.706 10.362 11.552  6.941 10.983 10.092  6.421 14.943 15.931 ...
        22.968 18.590 16.567 15.944 21.637 14.492 17.965 18.851 22.891 ...
        22.028 16.884 17.252 18.325 25.435 19.141 21.238 22.196 18.038 ...
        22.628 31.163 26.053 24.419 32.145 28.966 30.207 29.142 33.212 ...
        25.694 ]';
 X = [1 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5]';
 mdl = fitlm (X, y, 'linear', 'CategoricalVars', 1)
mdl =

  Linear regression model:
      y ~ 1 + x1

  Estimated Coefficients:

  5x4 table

                   Estimate      SE        tStat       pValue       
                   ________    _______    _______    ___________    

    (Intercept)          10    1.01775    9.82556    3.48093e-11    
    x1_2                  8    1.64108    4.87484    2.85812e-05    
    x1_3                  9    1.43932    6.25295    5.22937e-07    
    x1_4            11.0001    1.48984    7.38344    2.12795e-08    
    x1_5            19.0001    1.39877    13.5835    7.82092e-15    


Number of observations: 37, Error degrees of freedom: 32
Root Mean Squared Error: 2.87864
R-squared: 0.854819,  Adjusted R-Squared: 0.836672
F-statistic vs. constant model: 47.1038, p-value = 5.71708e-13
 popcorn = [5.5, 4.5, 3.5; 5.5, 4.5, 4.0; 6.0, 4.0, 3.0; ...
            6.5, 5.0, 4.0; 7.0, 5.5, 5.0; 7.0, 5.0, 4.5];
 brands = {'Gourmet', 'National', 'Generic'; ...
           'Gourmet', 'National', 'Generic'; ...
           'Gourmet', 'National', 'Generic'; ...
           'Gourmet', 'National', 'Generic'; ...
           'Gourmet', 'National', 'Generic'; ...
           'Gourmet', 'National', 'Generic'};
 popper = {'oil', 'oil', 'oil'; 'oil', 'oil', 'oil'; 'oil', 'oil', 'oil'; ...
           'air', 'air', 'air'; 'air', 'air', 'air'; 'air', 'air', 'air'};
 T = table (brands(:), popper(:), 'VariableNames', {'brands', 'popper'});
 mdl = fitlm (T, popcorn(:), 'interactions')
mdl =

  Linear regression model:
      y ~ 1 + brands*popper

  Estimated Coefficients:

  7x4 table

                                      Estimate        SE         tStat        pValue       
                                      _________    ________    _________    ___________    

    (Intercept)                         5.66667    0.215166      26.3363    5.49842e-12    
    brands_National                    -1.33333     0.30429     -4.38178    0.000893505    
    brands_Generic                     -2.16667     0.30429     -7.12039    1.21291e-05    
    popper_air                          1.16667     0.30429      3.83406     0.00237798    
    brands_National:brands_Generic            0           0          NaN            NaN    
    brands_National:popper_air        -0.333333    0.430331    -0.774597       0.453571    
    brands_Generic:popper_air         -0.166667    0.430331    -0.387298       0.705317    


Number of observations: 18, Error degrees of freedom: 12
Root Mean Squared Error: 0.372678
R-squared: 0.924242,  Adjusted R-Squared: 0.892677
F-statistic vs. constant model: 29.28, p-value = 2.50646e-06