information_coefficient

Defined in fynance.metrics

information_coefficient(pred, real, *, method='spearman', axis=0)[source]

Information Coefficient between a prediction and a realized outcome.

The Information Coefficient (IC) is the correlation between a forecast and what actually happened — a predict-then-rule guardrail measuring how much signal a prediction carries. With method='spearman' (default) it is the rank-IC: a rank correlation that rewards getting the ordering right while ignoring the magnitude/shape of the relationship, which is the relevant quantity when the prediction is used to rank assets. With method='pearson' it is the ordinary linear correlation.

The two inputs must be aligned: pred[i] is the forecast for the outcome real[i].

Parameters:
prednp.ndarray[dtype, ndim=1 or 2]

Predictions/forecasts (e.g. a model score). Same shape as real.

realnp.ndarray[dtype, ndim=1 or 2]

Realized outcomes (e.g. forward returns). Same shape as pred.

method{‘spearman’, ‘pearson’}, optional

'spearman' (default) for the rank-IC, 'pearson' for the linear IC.

axis{0, 1}, optional

Axis indexing the samples to correlate over. For 2-D inputs, axis=0 correlates across the second dimension per row (cross-sectional IC per bar, shape (T,)) and axis=1 correlates across the first dimension per column (time-series IC per asset, shape (N,)). Ignored for 1-D inputs. Default is 0.

Returns:
float or np.ndarray[np.float64, ndim=1]

The IC. A scalar for 1-D inputs, a 1-D array for 2-D inputs. Entries are np.nan (never an exception) where fewer than two valid pairs remain or either side has zero variance.

See also

sharpe, sortino

Notes

For two aligned samples the IC is

\[IC = corr(g(pred),\ g(real))\]

where \(g\) is the identity for method='pearson' and the rank transform for method='spearman' (Spearman = Pearson on ranks). Index pairs where either side is NaN are dropped before the computation.

Shape contract. For 1-D inputs (T,) the IC is a scalar computed over the whole sample. For 2-D panel inputs (T, N) the default (axis=0) is the cross-sectional IC per bar: at each time step the prediction is correlated against the realization across the N assets, returning one IC per bar with shape (T,). This is the ranking use-case — at each rebalancing bar, “did the assets I ranked highest actually do best?”. Pass axis=1 to instead correlate along the time axis per asset, returning shape (N,) (the per-asset time-series IC).

References

Examples

A perfect monotonic prediction has a rank-IC of 1, even when the relationship is non-linear (only the ordering matters):

>>> import numpy as np
>>> real = np.array([1., 2., 3., 4., 5.])
>>> pred = real ** 3
>>> float(information_coefficient(pred, real))
1.0
>>> round(float(information_coefficient(pred, real, method='pearson')), 4)
0.9431

A panel returns one cross-sectional IC per bar — here the ranking is correct on the first bar and inverted on the second:

>>> pred = np.array([[1., 2., 3.], [1., 2., 3.]])
>>> real = np.array([[1., 2., 3.], [3., 2., 1.]])
>>> information_coefficient(pred, real)
array([ 1., -1.])