Интерпретация R в квадрате | R-квадрат линейной регрессии

Машинное обучение включает в себя множество статистических данных. В следующей статье мы рассмотрим концепцию R-Squared, которая полезна при выборе функций.

Корреляция (также известная как «R») - это число от 1 до -1, где значение +1 означает, что увеличение x приводит к некоторому увеличению y, -1 означает, что увеличение x приводит к уменьшению y. , а 0 означает, что между x и y нет никакой связи. Как и корреляция, R² показывает, как связаны две вещи. Однако мы склонны использовать R², потому что его легче интерпретировать. R² - это процент отклонения (т.е. варьируется от 0 до 1), объясняемый соотношением между двумя переменными.

Последнее звучит довольно запутанно, поэтому давайте рассмотрим пример. Предположим, мы решили построить график зависимости между зарплатой и стажем работы. На последующем графике каждая точка данных представляет человека.

Мы можем вычислить среднее или среднее значение, взяв сумму всех индивидов в выборке и разделив ее на общее количество индивидов в выборке.

Дисперсия всего набора данных равна сумме расстояния между каждой точкой данных и средним квадратом. Разница возводится в квадрат так, что точки ниже среднего не компенсируются точками выше среднего.

var(mean) = sum(pi - mean)²

Теперь предположим, что мы взяли тех же людей, но на этот раз мы решили построить график зависимости между их зарплатой и ростом.

Обратите внимание, как средняя зарплата остается неизменной независимо от того, что мы принимаем за независимую переменную. Другими словами, мы можем использовать другие аспекты жизни людей как x, но зарплата останется прежней.

Предположим, что мы использовали линейную регрессию, чтобы найти наиболее подходящую линию.

Тогда значение можно выразить как:

R² = (var(mean) - var(line)) / var(mean)

где var (среднее) - это отклонение от среднего, а var (line) - это отклонение по отношению к строке.

Как мы упоминали ранее, дисперсию можно рассчитать, взяв сумму разницы между индивидуальной заработной платой и средним квадратом.

Используя ту же логику, мы можем определить вариацию вокруг оранжевой линии.

Предполагая, что мы получили следующие значения дисперсии линии и среднего.

Мы можем рассчитать по формуле, описанной ранее.

Значение R² означает, что отклонение вокруг линии на 96% меньше среднего. Другими словами, связь между заработной платой и стажем работы составляет 96% вариации. Иными словами, многолетний опыт является хорошим показателем заработной платы, потому что, когда годы опыта растут, увеличивается и зарплата, и наоборот.

Код

Давайте посмотрим, как можно использовать R² для оценки модели линейной регрессии. Для начала импортируйте следующие библиотеки.

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import seaborn as sns
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression
sns.set()

Мы будем использовать следующий набор данных. Если вы хотите продолжить, скопируйте его содержимое в файл csv.

YearsExperience,Salary
1.1,39343.00
1.3,46205.00
1.5,37731.00
2.0,43525.00
2.2,39891.00
2.9,56642.00
3.0,60150.00
3.2,54445.00
3.2,64445.00
3.7,57189.00
3.9,63218.00
4.0,55794.00
4.0,56957.00
4.1,57081.00
4.5,61111.00
4.9,67938.00
5.1,66029.00
5.3,83088.00
5.9,81363.00
6.0,93940.00
6.8,91738.00
7.1,98273.00
7.9,101302.00
8.2,113812.00
8.7,109431.00
9.0,105582.00
9.5,116969.00
9.6,112635.00
10.3,122391.00
10.5,121872.00

Мы загружаем данные в нашу программу с помощью pandas и строим их с помощью matplotlib.

df = pd.read_csv('data.csv')
plt.scatter(df['YearsExperience'], df['Salary'])

Затем мы обучаем модель линейной регрессии на наших данных о зарплате.

X = np.array(df['YearsExperience']).reshape(-1, 1)
y = df['Salary']
rf = LinearRegression()
rf.fit(X, y)
y_pred = rf.predict(X)

Мы можем просмотреть наиболее подходящую линию, созданную нашей моделью, выполнив следующие строки.

plt.scatter(df['YearsExperience'], df['Salary'])
plt.plot(X, y_pred, color='red')

Затем мы вычисляем R², используя формулу, описанную в предыдущем разделе.

def r2_score_from_scratch(ys_orig, ys_line):
    y_mean_line = [ys_orig.mean() for y in ys_orig]
    squared_error_regr = squared_error(ys_orig, ys_line)
    squared_error_y_mean = squared_error(ys_orig, y_mean_line)
    return 1 - (squared_error_regr / squared_error_y_mean)
def squared_error(ys_orig, ys_line):
    return sum((ys_line - ys_orig) * (ys_line - ys_orig))
r_squared = r2_score_from_scratch(y, y_pred)
print(r_squared)

Вместо того, чтобы каждый раз реализовывать его с нуля, мы можем использовать функцию sklearn r2_score.

r2_score(y, y_pred)