Online Statsmodels Compiler

Run statsmodels code in your browser. Fit linear and logistic regressions, use R-style formulas and forecast with ARIMA.

Python
# Performing simple linear regression with statsmodels

import numpy as np
import statsmodels.api as sm

# Sample data: Hours studied and Exam scores
hours_studied = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
exam_scores = np.array([51, 55, 60, 68, 72, 75, 78, 82, 85, 88, 90, 92, 94, 96, 97, 98, 99, 100, 101, 102])

# Adding a constant for the intercept term
X = sm.add_constant(hours_studied)

# Creating the model
model = sm.OLS(exam_scores, X)

# Fitting the model
results = model.fit()

# Making predictions
hours = 10  # Predicting the exam score for someone who studied 10 hours
predicted_score = results.predict([1, hours])  # The first element is the constant term
print(f"Predicted exam score for someone who studied {hours} hours: {predicted_score[0]}\n")

# Printing the summary of the model
print(results.summary())
Predicted exam score for someone who studied 10 hours: 82.85413533834586

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.922
Model:                            OLS   Adj. R-squared:                  0.917
Method:                 Least Squares   F-statistic:                     211.8
Date:                Mon, 28 Sep 2026   Prob (F-statistic):           2.14e-11
Time:                        09:55:02   Log-Likelihood:                -57.815
No. Observations:                  20   AIC:                             119.6
Df Residuals:                      18   BIC:                             121.6
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const         56.9368      2.134     26.687      0.000      52.454      61.419
x1             2.5917      0.178     14.552      0.000       2.218       2.966
==============================================================================
Omnibus:                        3.416   Durbin-Watson:                   0.153
Prob(Omnibus):                  0.181   Jarque-Bera (JB):                2.165
Skew:                          -0.603   Prob(JB):                        0.339
Kurtosis:                       1.930   Cond. No.                         25.0
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

statsmodels fits statistical models and reports them the way a statistics course expects: coefficients with standard errors, p-values and confidence intervals. It covers linear and logistic regression, ANOVA, time series models and many statistical tests, and it accepts R-style formulas such as "score ~ hours". Researchers and students use it to explain a relationship, not only to predict it. This page is an online statsmodels compiler: the code runs in your browser, so you can try it without installing anything. Run the example first, then paste any snippet below into a new cell to try it.

What the example does

The example fits a straight line to the exam scores of 20 students. sm.add_constant() adds a column of ones to the hours, which gives the model an intercept. sm.OLS() sets up an ordinary least squares model and .fit() estimates it: the line is 56.94 + 2.59 × hours. results.predict([1, hours]) takes the same two columns, a 1 for the constant and then the hours, and returns an array: 82.85 for 10 hours. results.summary() prints the full table. R-squared is 0.922, and the x1 row (the hours) holds the slope with its standard error, p-value and 95% confidence interval (2.22 to 2.97).

Fit a model with a formula

statsmodels.formula.api takes a pandas DataFrame and a formula, and adds the intercept for you. The scores rise quickly at first and slowly later, so this adds a squared term with I(hours ** 2):

import pandas as pd
import statsmodels.formula.api as smf

df = pd.DataFrame({
    "hours": range(1, 21),
    "score": [51, 55, 60, 68, 72, 75, 78, 82, 85, 88,
              90, 92, 94, 96, 97, 98, 99, 100, 101, 102],
})

linear = smf.ols("score ~ hours", data=df).fit()
curved = smf.ols("score ~ hours + I(hours ** 2)", data=df).fit()

print(curved.params.round(3))
print("R-squared:", round(linear.rsquared, 3), "->", round(curved.rsquared, 3))
print("AIC:", round(linear.aic, 1), "->", round(curved.aic, 1))

R-squared rises from 0.922 to 0.997, and AIC (lower is better) falls from 119.6 to 59.0. For a text column, C(column) fits one coefficient per category, measured against the first.

Get predictions with intervals

get_prediction() with summary_frame() gives each prediction with two 95% intervals:

import pandas as pd
import statsmodels.formula.api as smf

df = pd.DataFrame({
    "hours": range(1, 21),
    "score": [51, 55, 60, 68, 72, 75, 78, 82, 85, 88,
              90, 92, 94, 96, 97, 98, 99, 100, 101, 102],
})
model = smf.ols("score ~ hours + I(hours ** 2)", data=df).fit()

new = pd.DataFrame({"hours": [5, 10, 15]})
prediction = model.get_prediction(new).summary_frame(alpha=0.05)
print(prediction.round(1))

mean_ci bounds the average score of all students who study that long. obs_ci bounds the score of one new student, so it is wider.

Run a logistic regression

For a yes-or-no outcome, smf.logit() models the probability of a 1. Here 200 simulated students pass more often the longer they study:

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf

rng = np.random.default_rng(seed=1)
hours = rng.uniform(0, 10, 200)
chance = 1 / (1 + np.exp(-(hours - 5)))          # true pass probability
df = pd.DataFrame({"hours": hours, "passed": rng.binomial(1, chance)})

model = smf.logit("passed ~ hours", data=df).fit(disp=0)
print(model.params.round(3))
print("Odds ratio per hour:", np.exp(model.params["hours"]).round(2))
print(model.predict(pd.DataFrame({"hours": [2, 5, 8]})).round(2))

The coefficients are log-odds, so np.exp() turns the slope into an odds ratio: each extra hour multiplies the odds of passing by about 3. predict() returns probabilities, and disp=0 hides the optimizer's progress message.

Forecast a time series with ARIMA

ARIMA takes a series with a date index and an order of (p, d, q): autoregressive terms, differences and moving-average terms. trend="t" adds a drift:

import numpy as np
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA

rng = np.random.default_rng(seed=3)
months = pd.date_range("2023-01-01", periods=36, freq="MS")
steps = rng.normal(3, 8, 36)             # random steps, 3 up on average
sales = pd.Series(200 + np.cumsum(steps), index=months, name="sales")

model = ARIMA(sales, order=(1, 1, 0), trend="t").fit()
forecast = model.get_forecast(steps=6)
table = forecast.conf_int()
table["forecast"] = forecast.predicted_mean
print(table.round(1))

The forecast grows by about 3 a month, the drift in the data. The 95% interval from conf_int() widens the further ahead it looks.

Good to know

  • sm.OLS fits no intercept unless you call sm.add_constant(). Without it, the example's line is forced through zero and the slope jumps from 2.59 to 6.76. Formulas add the Intercept themselves.
  • sm.OLS(y, X) takes the outcome first, the reverse of scikit-learn's fit(X, y).