Пост на этой неделе будет немного отличаться от обычного. Хотя мы обычно говорим здесь о Cyber, сегодня мы немного углубимся в алгоритмы машинного обучения, а именно, как реализовать модель линейной регрессии, которая позволит нам прогнозировать цены на дома на основе одной переменной (размер на 1000 квадратных футов). ). Начнем?

Введение

Существует два основных метода обучения моделей машинному обучению: обучение с учителем и обучение без учителя.

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

Или в регрессионной модели (также другом типе обучения с учителем) мы предоставляем входные данные (скажем, размер дома на 1000 кв. футов) и соответствующее ему целевое значение ( стоимость дома). Используя эту информацию, алгоритм может правильно предсказать цену дома за пределами тренировочного набора, просто принимая входные данные (размер дома).

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

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

Начало работы

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

В частности, мы будем использовать модель линейной регрессии. Модель линейной регрессии обычно «рисует» линию прямо посередине набора данных и пытается делать прогнозы на основе этой линии.

Нам нужно знать несколько уравнений, чтобы реализовать это:

Уравнение модели линейной регрессии = f(x)=w*x + b илиf w,b = w*x + b

Это уравнение — то, что нарисует линию в середине данных.

Уравнение функции стоимости = J(x) = 1/2m* mΣi=1 (f(x)^(i) -y^( я))²

Это уравнение вычисляет стоимость нашей модели линейной регрессии. То есть он сообщает нам о несоответствии между нашими предсказанными значениями (ŷ или значениями, которые предсказывает модель) и нашими целевыми значениями (значениями, которые мы явно ввели в алгоритм).

Алгоритм градиентного спуска

Это позволит нам снизить стоимостьJ(x) за счет постоянного повторения значений w и b до тех пор, пока стоимость не станет минимальной. .

повторять до сходимости (то есть до тех пор, пока каждая будущая итерация не окажет минимального влияния на значения w и b) {

w = w- α (скорость обучения) * 1/m *mΣi=1( f(x)^(i) — y^(i))x^(i)

b = w- α (скорость обучения)* 1/m *mΣi=1( f(x)^(i) — y^(i))

}

Реализация

Я буду использовать Java в качестве языка программирования и BlueJ в качестве среды IDE. Вы можете использовать Python или любой другой удобный для вас язык. Используемый синтаксис зависит от используемого языка.

Во-первых, я создам новый класс с именем PricePredictor.

Далее я назначу несколько полей классу PricePredictor, а также создам конструктор.

x_train – это массив, содержащий входные значения размера дома на 1000 кв. футов.

y_train — это массив, содержащий целевые значения цены дома.

1,0 кв. Футов будет стоить 300,0 долларов, а 2,0 — 500,0 долларов (теоретически).

wиз w*x+b

bиз w*x+b

m — это переменная, представляющая количество строк в обучающем наборе. Я присваиваю значение m как x_train.length, которое возвращает количество элементов в этом массиве (2).

Поскольку мы не знаем оптимальных значений w и b, чтобы иметь модель линейной регрессии, которая идеально соответствует данным, мы инициализируем w и b равными 0 в качестве отправной точки.

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

Далее я буду реализовывать общедоступный двойной метод с именем CostFunction, который будет представлять нашу функцию стоимости J(x) = 1/2m* mΣi=1 (f (x)^(i) -y^(i))².

Сначала я создаю переменную с именем cost и инициализирую ее значением 0.

Затем я запускаю цикл for, в котором i начинается с 0 и заканчивается на m-1 (что по существу составляет m раз).

Я присваиваю переменной f_wb значение w*x_train[i] + b, где i представляет номер итерации.

f_wb – это значение нашего прогноза для признака x^(i), учитывая, что w и b в настоящее время равны 0.

Затем я присваиваю cost_i (f_wb — y_train[i])².

cost_i представляет стоимость между прогнозируемым значением (f_wb при x^(i) и w=0 и b=0) и фактическим целевым значением (y_train при i) в квадрате.

Наконец, для каждой итерации я добавляю cost_i к переменной cost.

После завершения всех итераций и выхода из цикла я создаю переменную с именем total_cost, умножаю cost на 1/2m и присваиваю ей значение, как в уравнении.

Затем я дорабатываю этот метод, заставляя его возвращать переменную total_cost.

Далее мы вычислим частные производные для функции стоимости J как по w, так и по b. В частности, мы будем находить значения операций в скобках и жирным шрифтом. Метод GradientValues будет иметь параметры w и b и будет возвращать массив типа double.

w = w- α *( 1/m * mΣi=1( f(x)^(i) — y^(i))x^(i))

b = w- α* (1/m * mΣi=1( f(x)^(i) — y^(i)))

Инициализируйте dj_dw и dj_db равными 0.

Создайте цикл for, как и в предыдущем методе, который будет выполняться m раз.

f_wb = w*x_train[i] + b для получения предсказанного значения или ŷ.

cost_i, чтобы получить разницу между ŷ и целевыми значениями (y).

dj_dw_i даст нам производную для функции стоимости J конкретно по параметру w (поскольку он умножается на x_train[i]), в то время как мы можем просто использовать cost_iв качестве производной для функции стоимости J по параметру b.

Затем мы можем добавить эти значения в dj_dw и dj_db соответственно.

Как только мы вышли из цикла, мы можем умножить его на (1/м), как в уравнении.

Затем я создам массив gv типа double, сохраню в нем dj_dw и dj_db и верну gv, поэтому что я могу использовать эти значения позже.

Далее метод GradientFinal возвращает массив типа double с параметрами int inters (итерации) и alpha (скорость обучения).

Мы начнем с цикла for, который будет повторять междувременами. Внутри цикла мы вызовем созданный ранее метод GradientValues, чтобы получить производные функции стоимости J по отношению к w и b, ранее сохраненным в массиве, и присвоить их gv.

Теперь мы обновим значения w и b, как в уравнении.

w = w- (alpha * gv[0] (наша производная для функции стоимости J по отношению к w, которая хранится в gv)

b= b- (alpha* gv[1] (наша производная для функции стоимости J по отношению к b, которая хранится в gv)

После того, как цикл был выполнен inters количество раз, давайте выйдем из цикла, а затем сохраним эти недавно обновленные значения в новом массиве с именем gf и вернем его.

Итак, мы проделали всю эту работу, и мы не уверены, все ли правильно или нет. Давайте проверим это, создав новый класс с именем tester.

В этом классе я создал метод void с именем testgf:

Я создам новый экземпляр PricePredictor, вызову метод GradientFinal с 10 000 итераций и скоростью обучения (альфа) 1,0e-2 или примерно 0,010.

Затем я пройдусь по всем значениям в массиве gf, чтобы получить оптимизированные значения w и b для нашей модели линейной регрессии, и распечатаю их.

Как видите, оптимизированное значение для w составляет примерно 199,992, а для b — 100,0011 после 10 000 итераций. Давайте подставим эти значения в наше уравнение, чтобы увидеть, получим ли мы наши целевые результаты.
f(x) = w*x+b
300= w*(1,0) + b ›› 300 = (199,99)*1 + (100,011) = 300
500= w* (2,0) + b ›› 500 = (199,99)*2 + (100,011) = 499,997 (в основном 500, если округлить в большую сторону).

Поздравляем! Теперь мы узнали значения для w и b, которые сделают нашу модель линейной регрессии очень подходящей для данных.

Наконец, давайте создадим метод, который будет работать как мини-программа, и объединим все эти концепции:

В этой программе мы запросим у пользователя размер дома на 1000 квадратных футов, вызовем GradientFinal для расчета оптимальных значений w и b, подставим эти значения, предскажем цену дома и распечатаем ее. Если пользователь вводит что-то отличное от числа, мы покажем сообщение об ошибке и позволим пользователю повторить попытку.
Давайте запустим его и посмотрим, как это выглядит:

Я введу 1,2 в качестве своего размера, а затем 1 и 2 (которые были нашими целевыми значениями).

Как видите, мы получаем прогнозируемую цену в 340 долларов. Мы знаем, что это правильно, потому что когда мы вводим 1 или 2, предсказанные значения совпадают с нашими целевыми значениями.

Давайте попробуем использовать некоторые нецифровые символы:

Как видите, подсказка просто перезапускается, как и планировалось. Теперь давайте выйдем из программы, набрав «EXIT».

Как видите, программа остановилась и мы получаем сообщение «Увидимся в следующий раз».

Поздравляем! Вы только что реализовали модель одномерной линейной регрессии с использованием Java для прогнозирования цен на жилье в зависимости от размера.

Если вам нужна более предсказуемая и применимая модель, вам придется изменить код так, чтобы вы использовали обучающий набор с реальными данными, а также добавить дополнительные переменные (количество ванных комнат, напольное покрытие и т. д.), которые будут способствовать к окончательной цене, кроме размера дома. Этот учебник демонстрирует лишь приблизительный план того, как вы будете его реализовывать.

Большое спасибо DeepLearning.AI и Standford за создание специализации машинного обучения. Этот учебник в значительной степени вдохновлен им (хотя в исходном курсе используется Python вместо Java).

Хотите узнать больше? Посещать:

https://www.coursera.org/specializations/machine-learning-introduction