Определение линейной регрессии
Линейная регрессия (Linear regression) — это математическая модель, предполагающая, что зависимость между переменными можно описать линейной функцией. В основе ее работы лежит поиск таких весов и смещений, при которых предсказания, опирающиеся на обучающие данные, будут максимально точными.
Если имеется одна независимая переменная, то линейная регрессия называется простой (парной) — ее можно представить в виде уравнения y=β0+β1x1, а если их несколько — множественной, тогда уравнение имеет вид y=β0+β1x1+β2x2+...+βnxn+ϵ, где:
- y — целевая переменная (то, что нужно предсказать);
- x1,…,xn — независимые переменные;
- β1,…,βn — веса независимых переменных;
- β0 — смещение модели;
- ϵ — шум.
Также существует несколько условий, невыполнение которых приводит некорректному и даже бесполезному результату — они называются допущениями линейной регрессии.
- Линейная зависимость. Изменения независимых переменных должны изменять целевую пропорционально этим изменениям. Другими словами, связь между независимыми и зависимой переменной должна быть линейной. Если связь нелинейная, то лучше выбрать другие методы, например, полиномиальную регрессию.
- Отсутствие мультиколлинеарности. Независимые переменные не должны зависеть друг от друга линейно, так как мультиколлинеарность делает оценки коэффициентов нестабильными, в результате чего работа модели становится сильно зависимой от выборки.
- Гомоскедастичность. Для всех значений независимых переменных дисперсия остатков должна быть одинаковой.
- Отсутствие внешних переменных. Переменные, которые сильно влияют на целевую переменную, должны быть включены в модель.
- Наличие вариации. Независимые переменные должны иметь какое-то различие значений, если этого нет, то выявить связь между изменениями двух переменных невозможно, а значит, полезность модели будет низкой.
- Целевая переменная должна быть непрерывной, а независимые — могут быть непрерывными или категориальными.
- Наблюдения не должны зависеть друг от друга.
Таким образом, важно учитывать и следовать допущениям, а когда это невозможно — выбирать другие методы, либо преобразовывать данные.
Способы обучения и оценка моделей
Рассмотрим два способа обучения:
- аналитическое решение (нормальное уравнение): w=(XTX)−1XTy, где w — это вектор оптимальных весов, содержащий веса для каждого признака и смещение. Этот способ неэффективен при большом количестве признаков, так как сложность операции (XTX)−1 равна O(n3), где n — количество признаков;
- итеративная оптимизация (градиентный спуск и его модификации). Этот метод работает по следующему алгоритму:
- Инициализация весов и смещения нулевыми значениями.
- Модель делает прогноз на основе текущих значений параметров.
- Вычисление функции потерь, обновление весов и смещения на основе ее градиента.
- Описанный процесс повторяется до тех пор, пока функция потерь будет значительно уменьшаться (либо пока не будет достигнуто пороговое значение, либо пока не будет достигнуто максимальное установленное количество итераций).
В реальных моделях метод градиентного спуска приоритетен, так как он эффективнее работает с большим количеством признаков, а также позволяет настроить скорость обучение, количество итераций и другие показатели.
Существует несколько метрик оценки точности регрессии:
- средняя квадратическая ошибка (MSE, Mean Squared Error). Этот показатель описывает, насколько предсказанные значения отличаются (отклоняются) от истинных, при этом отклонение возводится в квадрат, а значит, чем это отклонение больше, тем больше оно влияет на итоговое значение MSE. Чем меньше средняя квадратическая ошибка, тем выше точность работы модели;
- коэффициент детерминации (R2). Этот показатель определяет, насколько модель соответствует данным, на которых она построена, и рассчитывается, как единица вычесть долю дисперсии, которую модель не объяснила. Идеальное значение коэффициента детерминации — это 1, в реальности же хорошим показателем является значение, близкое к единице. R2 равный нулю означает, что связь между переменными отсутствует: между ними нет линейной зависимости.
Эти метрики могут использоваться как оценки точности конкретной модели, так и для сравнения двух моделей между собой. При этом важно учитывать, что коэффициент детерминации — это не всегда корректный показатель для сравнения моделей с различным числом параметров.
Сферы применения линейной регрессии
В теории линейная регрессия может применяться в любой области, однако можно выделить несколько наиболее распространенных сфер применение.
- Маркетинговая аналитика. Здесь метод может использоваться для анализа влияния различных факторов, например, сезон, цена или маркетинговая активность на состояние продаж компании в целом или же отдельного ее продукта. Результаты этого анализа служат для предприятий фундаментом при принятии решений. Также в маркетинге метод применяется для прогнозирования поведения целевой аудитории компании, например, если взять за основу группу факторов, которые использовались при сегментации.
- Машинное обучение. В этой области метод используется для предсказания одного параметра на основе известного параметра или группы параметров. Также здесь метод является основой для других, более сложных применяемых концепций, например, полиномиальная регрессия, регуляризация, ансамблевое обучение и другие.
- Экономика. Линейная регрессия применяется для прогнозирования экономического состояния стран или регионов, уровня инфляции, динамики развития рынков; для анализа рынка труда, уровня доходов населения. Это лишь часть вариантов использования метода в экономической сфере.
- Различные направления наук. В таком случае метод тоже используется для поиска закономерностей. Самый простой пример: поиск зависимости между образованием и доходами населения в социологии.
Таким образом, линейная регрессия может использоваться во всех сферах, где проводятся исследования, связанные с проверкой гипотез и поиском взаимосвязей между различными факторами.
Пример использования в Python
В качестве примера рассмотрим код для поиска зависимости дохода человека от его возраста и опыта работы (то есть предполагается, что доход зависит от возраста и опыта линейно):
# Импорт нужных библиотек
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error, r2_score
# Генерация данных: 30 возрастов в диапазоне 20-60 и годы опыта в диапазоне 15-30
np.random.seed(0)
ages = np.random.randint(20, 60, 30)
experience = np.random.randint(1, 15, 30)
# income (доход) рассчитывается как линейная функция от возраста и опыта
# np.random.normal() добавляет шум для того, чтобы сделать данные реалистичными
income = 30000 + 500 * ages + 2000 * experience + np.random.normal(0, 5000, 30)
X = np.column_stack((ages, experience))
y = income # Целевая переменная
# Деление на обучающую (первые 20) и тестовую (10 последних) выборки
X_train, X_test = X[:20], X[20:]
y_train, y_test = y[:20], y[20:]
# Реализация на основе матричного метода
class MatrixLinearRegression:
def fit(self, X, y):
X = np.insert(X, 0, 1, axis=1)
self.weights = np.linalg.inv(X.T @ X) @ X.T @ y
# predict() предсказывает значения y с учетом весов
def predict(self, X):
X = np.insert(X, 0, 1, axis=1)
return X @ self.weights
# Реализация на основе градиентного спуска
class GradientDescentLinearRegression:
# learning_rate определяет, насколько веса могут измениться за одну итерацию, epochs — их количество
def __init__(self, learning_rate=0.01, epochs=10000, tol=1e-6):
self.learning_rate = learning_rate
self.epochs = epochs
self.tol = tol
self.weights = None
def fit(self, X, y):
self.mean = np.mean(X, axis=0)
self.std = np.std(X, axis=0)
X = (X - self.mean) / self.std
X = np.insert(X, 0, 1, axis=1)
n_samples, n_features = X.shape
self.weights = np.zeros(n_features)
previous_loss = float('inf')
for epoch in range(self.epochs):
y_pred = X @ self.weights # Прогноз
gradient = -(2 / n_samples) * X.T @ (y - y_pred)
self.weights -= self.learning_rate * gradient # Обновление весов
loss = mean_squared_error(y, y_pred)
if epoch % 1000 == 0:
print(f"Epoch {epoch}: Loss = {loss:.4f}")
if abs(previous_loss - loss) < self.tol:
print(f"Converged at epoch {epoch}: Loss = {loss:.4f}")
break
previous_loss = loss
def predict(self, X):
X = (X - self.mean) / self.std # Нормализация тестовых данных
X = np.insert(X, 0, 1, axis=1)
y_pred = X @ self.weights
return y_pred
# Выбор метода (необязательная часть, здесь представлена для демонстрации работы кода)
method = input("Метод обучения (matrix/gradient): ").strip().lower()
if method == "matrix":
model = MatrixLinearRegression()
model.fit(X_train, y_train)
print("Матричный метод")
elif method == "gradient":
model = GradientDescentLinearRegression(learning_rate=0.01, epochs=10000, tol=1e-6)
model.fit(X_train, y_train)
print("Метод градиентного спуска")
else:
raise ValueError("Здесь нет такого метода!")
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
# Вычисление средней квадратической ошибки
mse = mean_squared_error(y_test, y_pred)
print(f"R2: {r2:.2f}")
print(f"MSE: {mse:.2f}")
# Далее устанавливаются различные параметры визуализации
plt.figure(figsize=(10, 6))
# Начальные данные
plt.scatter(ages, income, color="blue", label="Data", alpha=0.7)
# Прогноз
plt.scatter(ages[20:], y_pred, color="red", label="Prediction", alpha=0.9)
sorted_indices = np.argsort(ages)
ages_sorted = ages[sorted_indices]
X_sorted = X[sorted_indices]
# Линия регрессии
y_all_pred = model.predict(X_sorted)
plt.plot(ages_sorted, y_all_pred, color="green", label="Regression line")
# Детали оформления графика
plt.xlabel("Age", fontsize=12)
plt.ylabel("Income", fontsize=12)
plt.title("Linear regression", fontsize=14)
plt.legend(fontsize=10)
plt.grid(alpha=0.3)
plt.show()
В данном случае оба метода покажут хорошие значения коэффициента детерминации и примерно равные показатели средней квадратической ошибки, графики также будут идентичны.