Перейти к содержимому

R2 Score

R2 Score, или коэффициент детерминации, показывает, насколько модель лучше простого прогноза средним значением.

Сначала сравним модель не с идеалом, а с очень простой базовой стратегией. Эта стратегия вообще не смотрит на признаки и всегда отвечает одним числом — средним значением целевой переменной.

Пусть мы предсказываем цену квартиры по площади. Самый простой прогноз — всегда отвечать средней ценой по всем известным квартирам.

uses MLABC, PlotML;
begin
var df := DataFrame.FromCsvText('''
Площадь,Цена
35,4.8
42,5.7
50,7.9
58,7.9
65,8.2
72,10.4
80,10.5
90,12.5
''');
var X := df.ToMatrix(['Площадь']);
var y := df.ToVector('Цена');
var yMean := y.Mean;
Plot.Title := 'Прогноз средним значением';
Plot.XLabel := 'Площадь';
Plot.YLabel := 'Цена';
Plot.Points(X.Col(0), y);
// Горизонтальная линия: y = среднее значение цены
Plot.Line(0.0, yMean, Colors.Gray);
var totalError := 0.0;
var n := X.RowCount;
for var i := 0 to n - 1 do
begin
var x1 := X[i, 0];
Plot.LineGraph(
[x1, x1],
[y[i], yMean],
Colors.Gray,
thickness := 1.5);
totalError += (y[i] - yMean)**2;
end;
Println('Среднее значение:', yMean:0:2);
Println('Общая ошибка среднего:', totalError:0:2);
end.

Вывод:

Среднее значение: 8.49
Общая ошибка среднего: 45.95

На графике синие точки — настоящие значения. Серая горизонтальная линия — прогноз средним значением.

Прогноз средним значением для R2

Вертикальные серые отрезки показывают ошибки прогноза средним. Для R2 важны не сами длины этих отрезков, а сумма их квадратов:

SStotal=i=1n(yiyˉ)2SS_{total} = \sum_{i=1}^{n}(y_i - \bar{y})^2

В нашем примере:

SStotal=45.95SS_{total} = 45.95

Это знаменатель в формуле : он показывает, насколько сильно настоящие значения отличаются от своего среднего. В классической литературе его часто обозначают SStot, а здесь мы используем более понятное имя SStotalSS_{total}.

После обучения модели мы получаем её предсказания:

pred=(pred1,pred2,,predn)pred = (pred_1, pred_2, \ldots, pred_n)

Для модели считается сумма квадратов её ошибок:

SSmodel=i=1n(yipredi)2SS_{model} = \sum_{i=1}^{n}(y_i - pred_i)^2

Тогда:

R2=1SSmodelSStotalR^2 = 1 - \frac{SS_{model}}{SS_{total}}

Или полностью:

R2=1i=1n(yipredi)2i=1n(yiyˉ)2R^2 = 1 - \frac{ \sum_{i=1}^{n}(y_i - pred_i)^2 }{ \sum_{i=1}^{n}(y_i - \bar{y})^2 }

Теперь обучим линейную регрессию. Красная линия на графике — предсказания модели.

uses MLABC, PlotML;
begin
var df := DataFrame.FromCsvText('''
Площадь,Цена
35,4.8
42,5.7
50,7.9
58,7.9
65,8.2
72,10.4
80,10.5
90,12.5
''');
var X := df.ToMatrix(['Площадь']);
var y := df.ToVector('Цена');
var model := new LinearRegression;
model.Fit(X, y);
Plot.Title := 'Линейная регрессия';
Plot.XLabel := 'Площадь';
Plot.YLabel := 'Цена';
Plot.Points(X.Col(0), y);
var line := model.RegressionLine;
Plot.Line(line.K, line.B, Colors.Red);
var yPred := model.Predict(X);
var yMean := y.Mean;
var modelError := 0.0;
var totalError := 0.0;
var n := X.RowCount;
for var i := 0 to n - 1 do
begin
var x1 := X[i, 0];
Plot.LineGraph(
[x1, x1],
[y[i], yPred[i]],
Colors.Gray,
thickness := 1.5);
modelError += (y[i] - yPred[i])**2;
totalError += (y[i] - yMean)**2;
end;
Plot.Points(X.Col(0), yPred, Plot.PaletteColor(0), size := 5);
var r2 := 1 - modelError / totalError;
Println('Ошибка модели:', modelError:0:2);
Println('R2:', r2:0:3);
end.

Вывод:

Ошибка модели: 2.05
R2: 0.955
Ошибки линейной модели для R2

Теперь вертикальные отрезки показывают ошибки уже не до среднего значения, а до линии модели. Их сумма квадратов называется ошибкой модели. В классической литературе её часто обозначают SSres, а здесь мы используем более понятное имя SSmodelSS_{model}.

SSmodel=2.05SS_{model} = 2.05

Подставим оба значения в формулу:

R2=12.0545.950.955R^2 = 1 - \frac{2.05}{45.95} \approx 0.955

Это означает, что линейная модель объясняет примерно 95.5% разброса цен в этих данных.

R² близко к 1 модель хорошо объясняет данные
R² около 0 модель примерно как прогноз средним
R² меньше 0 модель хуже прогноза средним

Если ошибки модели намного меньше ошибок прогноза средним, дробь в формуле маленькая, и близко к 1.

Если модель ошибается примерно так же, как прогноз средним, дробь близка к 1, и около 0.

отвечает на вопрос:

Насколько наша модель уменьшила сумму квадратов ошибок по сравнению с самым простым прогнозом — всегда отвечать средним значением?