Линейная регрессия — это самый простой алгоритм машинного обучения, и большинство алгоритмов являются развитием базовых алгоритмов. Эта статья посвящена линейной регрессии на очень простом языке.
Линейная регрессия
Включая одномерную линейную регрессию и множественную линейную регрессию, одномерная относится только к одному x и одному y. Иметь базовое представление о линейной регрессии через одномерную модель.
Одномерная линейная регрессия заключается в том, чтобы найти прямую линию в данных и подобрать данные с наименьшей ошибкой (потери).
Упомянутую выше ошибку можно выразить так, предполагая, что строка выглядит следующим образом:
В идеале все точки лежат на одной прямой. Сделайте шаг назад и надейтесь, что все точки находятся ближе всего к линии. Для простоты, возведя расстояние в квадрат, ошибка может быть выражена как:
i выше представляет i-е данные. Как правило, убыток усредняется как окончательный убыток.
Свести к минимуму ошибку
Найдите строку, которая лучше всего соответствует данным, т.е. минимизируйте ошибку.
Наименьших квадратов
В приведенной выше формуле неизвестны только m и b, поэтому можно посмотреть на квадратное уравнение последних m и b, и проблема нахождения Loss станет проблемой нахождения экстремальных значений. Подробного описания здесь нет.
Кроме того, частная производная каждой переменной равна 0, и получается решение системы уравнений.
Найдите m и b, чтобы получить искомую прямую.Градиентный спуск
Сегодня не было бы глубокого обучения без градиентного спуска. Метод наименьших квадратов можно выполнить за один шаг, а m и b можно получить напрямую. В большинстве формул невозможно просто вычислить напрямую. Градиентный спуск медленно приближается к оптимальной прямой через пошаговые итерации, поэтому требуется непрерывная оптимизация. Функциональный образ Утраты можно сравнить с чашей.
Минимальное требуемое значение находится на дне чаши, и вы можете свободно указать точку для спуска, то есть спускаться в самом быстром нисходящем направлении (градиент), определить размер шага каждого хода и количество ходов. приблизиться к оптимальному значению. Для достижения используется следующий алгоритм:инициализация:
def init_data():
data = np.loadtxt('data.csv', delimiter=',')
return data
def linear_regression():
learning_rate = 0.01 #步长
initial_b = 0
initial_m = 0
num_iter = 1000 #迭代次数
data = init_data()
[b, m] = optimizer(data, initial_b, initial_m, learning_rate, num_iter)
plot_data(data,b,m)
print(b, m)
return b, m
Оптимизатор выполняет градиентный спуск:
def optimizer(data, initial_b, initial_m, learning_rate, num_iter):
b = initial_b
m = initial_m
for i in range(num_iter):
b, m = compute_gradient(b, m, data, learning_rate)
# after = computer_error(b, m, data)
if i % 100 == 0:
print(i, computer_error(b, m, data)) # 损失函数,即误差
return [b, m]
Градиент рассчитывается для каждой итерации для обновления параметров:
def compute_gradient(b_cur, m_cur, data, learning_rate):
b_gradient = 0
m_gradient = 0
N = float(len(data))
#
# 偏导数, 梯度
for i in range(0, len(data)):
x = data[i, 0]
y = data[i, 1]
b_gradient += -(2 / N) * (y - ((m_cur * x) + b_cur))
m_gradient += -(2 / N) * x * (y - ((m_cur * x) + b_cur)) #偏导数
new_b = b_cur - (learning_rate * b_gradient)
new_m = m_cur - (learning_rate * m_gradient)
return [new_b, new_m]
Расчет стоимости убытка:
def computer_error(b, m, data):
totalError = 0
x = data[:, 0]
y = data[:, 1]
totalError = (y - m * x - b) ** 2
totalError = np.sum(totalError, axis=0)
return totalError / len(data)
Выполнить результат вычисления функции:
if __name__ == '__main__':
linear_regression()
Результат операции следующий:
0 3.26543633854
100 1.41872132865
200 1.36529867423
300 1.34376973304
400 1.33509372632
500 1.33159735872
600 1.330188348
700 1.32962052693
800 1.32939169917
900 1.32929948325
1.23930380135 1.86724196887
Видно, что с увеличением количества итераций функция Loss все ближе и ближе к минимальному значению, а m и b также все ближе и ближе к оптимальному решению.
Уведомление:
В приведенном выше методе ошибка минимизируется путем вычисления частной производной Loss. Вышеупомянутый метод должен достигать дна чаши в соответствии с самым быстрым методом спуска, когда известен уклон. Итак, как найти оптимальное решение, когда формулу очень сложно вычислить. В настоящее время вы можете использовать определение производной, чтобы найти частную производную, см. другую функцию.
def optimizer_two(data, initial_b, initial_m, learning_rate, num_iter):
b = initial_b
m = initial_m
while True:
before = computer_error(b, m, data)
b, m = compute_gradient(b, m, data, learning_rate)
after = computer_error(b, m, data)
if abs(after - before) < 0.0000001: #不断减小精度
break
return [b, m]
def compute_gradient_two(b_cur, m_cur, data, learning_rate):
b_gradient = 0
m_gradient = 0
N = float(len(data))
delta = 0.0000001
for i in range(len(data)):
x = data[i, 0]
y = data[i, 1]
# 利用导数的定义来计算梯度
b_gradient = (error(x, y, b_cur + delta, m_cur) - error(x, y, b_cur - delta, m_cur)) / (2*delta)
m_gradient = (error(x, y, b_cur, m_cur + delta) - error(x, y, b_cur, m_cur - delta)) / (2*delta)
b_gradient = b_gradient / N
m_gradient = m_gradient / N
#
new_b = b_cur - (learning_rate * b_gradient)
new_m = m_cur - (learning_rate * m_gradient)
return [new_b, new_m]
def error(x, y, b, m):
return (y - (m * x) - b) ** 2
В приведенных выше двух случаях количество итераций достаточно для аппроксимации оптимального решения. Полученные оптимальные решения соответственно таковы: 1: 1,23930380135 1,86724196887 2: 1,24291450769 1,86676417482
простое сравнение
В sklearn есть соответствующий метод для поиска линейной регрессии, который напрямую использует метод наименьших квадратов для поиска оптимального решения. Простая реализация для сравнения.
def scikit_learn():
data = init_data()
y = data[:, 1]
x = data[:, 0]
x = (x.reshape(-1, 1))
linreg = LinearRegression()
linreg.fit(x, y)
print(linreg.coef_)
print(linreg.intercept_)
if __name__ == '__main__':
# linear_regression()
scikit_learn()
Решение на данный момент такое: 1,24977978176 1,86585571. Можно показать, что приведенные выше результаты расчетов являются удовлетворительными, а лучшие результаты могут быть достигнуты путем последующей настройки параметров.
Исходный код и ссылка на данные:GitHub.com/Облачные водные билеты…
Спасибо и обратитесь к сообщению в блоге:Понимание линейной регрессии (с реализацией на чистом Python)
Градиентный спуск Градиентный спуск
Резюме градиентного спуска