crabbymetrics
  • Home
  • API
    • API Overview
    • Regression And GLMs
    • Survival / Event-Time
    • Causal Inference And Panels
    • Hypothesis Testing And Utilities
    • Transforms
    • Estimation Interfaces
  • Binding Crash Course
  • Regression And GLMs
    • OLS
    • ABC OLS
    • Anytime-Valid Confidence Sequences
    • Ridge
    • Bagged Polynomial Regression
    • Fixed Effects OLS
    • ElasticNet
    • Logit
    • Multinomial Logit
    • Poisson
    • MLE Prediction Interface
    • Survival / Recurrent Events
    • GMM
    • MEstimator Poisson
  • Causal Inference
    • Balancing Weights
    • EPLM
    • Average Derivative
    • Double ML And AIPW
    • Richer Regression
    • TwoSLS
    • Synthetic Control
    • Synthetic DID
    • Horizontal Panel Ridge
    • Matrix Completion
    • Interactive Fixed Effects
    • Staggered Panel Event Study
    • Joint Hypothesis Tests
  • Transforms
    • PCA And Kernel Basis
  • Ablations
    • Variance Estimators
    • Semiparametric Estimator Comparisons
    • Two-Period Semiparametric DID
    • Bridging Finite And Superpopulation
    • Panel Estimator DGP Comparisons
    • Same Root Panel Case Studies
    • Randomized Sketching And Least Squares
  • Optimization
    • Optimizers
    • GMM With Optimizers
  • Ding: First Course
    • Overview And TOC
    • Ch 1 Correlation And Simpson
    • Ch 2 Potential Outcomes
    • Ch 3 CRE And Fisher RT
    • Ch 4 CRE And Neyman
    • Ch 9 Bridging Finite And Superpopulation
    • Ch 11 Propensity Score
    • Ch 12 Double Robust ATE
    • Ch 13 Double Robust ATT
    • Ch 21 Experimental IV
    • Ch 23 Econometric IV
    • Ch 27 Mediation

Multinomial Logit Example

This page mirrors examples/multinomial_logit_example.py.

1 Fit A Multiclass Logit Model

import numpy as np
from pprint import pprint

from crabbymetrics import MultinomialLogit

np.set_printoptions(precision=4, suppress=True)
def softmax(x: np.ndarray) -> np.ndarray:
    x = x - x.max(axis=1, keepdims=True)
    exps = np.exp(x)
    return exps / exps.sum(axis=1, keepdims=True)


rng = np.random.default_rng(3)
n = 1000
k = 3
c = 3
coef = np.array(
    [
        [1.0, -0.5, 0.2],
        [-0.7, 0.9, -0.4],
        [0.2, -0.3, 0.8],
    ]
)
intercept = np.array([0.3, -0.2, 0.0])

x = rng.normal(size=(n, k))
logits = x @ coef.T + intercept
probs = softmax(logits)
y = np.array([rng.choice(c, p=probs[i]) for i in range(n)], dtype=np.int32)

model = MultinomialLogit(alpha=1.0, max_iterations=200)
model.fit(x, y)

print("true intercept:", intercept)
print("true coef:", coef)
pprint(model.summary())
true intercept: [ 0.3 -0.2  0. ]
true coef: [[ 1.  -0.5  0.2]
 [-0.7  0.9 -0.4]
 [ 0.2 -0.3  0.8]]
{'class_labels': array([0, 1], dtype=int32),
 'coef': array([[ 0.1539,  0.8659, -0.3601, -0.5272],
       [-0.4352, -0.9528,  0.9965, -1.2238]]),
 'converged': True,
 'inference_available': False,
 'iterations': 13,
 'objective': 802.6900174562887,
 'penalty': 1.0,
 'reference_class': 2,
 'se': None,
 'termination_reason': 'Solver converged',
 'vcov': None}

2 Prediction surfaces

For multinomial logit, predict_lin() returns one latent score per class, predict() returns class probabilities, and predict_label() returns the argmax class.

check = x[:5]
print("linear scores")
print(model.predict_lin(check))
print("probabilities")
print(model.predict(check))
print("labels")
print(model.predict_label(check))
linear scores
[[ 3.56   -4.499   0.939 ]
 [-0.0136 -0.0339  0.0475]
 [-1.4761  1.8966 -0.4205]
 [ 3.0722 -3.0084 -0.0638]
 [ 0.3186  0.0699 -0.3885]]
probabilities
[[0.9319 0.0003 0.0678]
 [0.3286 0.322  0.3494]
 [0.0303 0.8827 0.087 ]
 [0.9563 0.0022 0.0416]
 [0.44   0.3431 0.2169]]
labels
[0 2 1 0 0]