Линейная регрессия с помощью Go

Линейная регрессия с помощью Go

Долгое время меня интересовала тема машинного обучения. Меня удивляло, как машины могут обучаться и прогнозировать безо всякого программирования — поразительно! Я всегда был очарован этим, однако никогда не изучал тему подробно. Время — ресурс скудный, и каждый раз, когда я пытался почитать о машинном обучении, меня заваливало информацией. Освоение всего этого казалось трудным и требовало много времени. Также я убедил себя, что у меня нет необходимых математических знаний даже для того, чтобы начать вникать в машинное обучение.

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

Начинаем

Начнём с создания простой модели, чтобы понять, из каких этапов стоит основной процесс обучения.

Допустим, нужно спрогнозировать цены на дома в округе Кинг, штат Вашингтон.

Сначала нужно найти датасет с реальной статистикой. На его основе мы будем создавать модель.

Он идёт в виде csv-файла с такой структурой:

Внутри файла есть всё необходимое. Каждый ряд содержит много информации, и придётся разобраться, что именно поможет нам прогнозировать цены на дома. Нам нужно:

  1. Выбрать модель.
  2. Разобраться в данных.
  3. Подготовить данные к работе.
  4. Обучить модель.
  5. Протестировать модель.
  6. Визуализировать модель.
1. Выбор модели

Воспользуемся одной из простейших популярных моделей — линейно-регрессионной.

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

Давайте подробнее рассмотрим линейную регрессию:

Этот график показывает взаимосвязь между двумя переменными.

Вертикальная ось (Y) отражает зависимую переменную — в нашем случае цены на дома. Горизонтальная ось (X) отражает так называемую независимую переменную — в нашем случае это могут быть любые другие данные из датасета, например bedrooms, bathrooms, sqft_living.

Круги на графике — y-значения для данного x-значения (y зависит от x). Красная линия — линейная регрессия. Эта линия проходит через все значения и может использовать для прогнозирования возможных значений y для данного x.

Наша цель — обучить модель строить красную линию для нашей задачи.

Напомним, что линейная функция имеет вид y = ax + b . Её нам и нужно найти. Точнее, нам нужно найти такие значения a и b , которые лучше всего удовлетворяют нашим данным.

2. Разбираемся с данными

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

Данные для линейно-регрессионной модели должны быть нормально распределены. То есть гистограмма данных должна иметь форму колокола.

Давайте построим график на основе наших данных и посмотрим, распределены ли они нужным образом. Для этого наконец-то напишем код!

    из стандартной библиотеки поможет нам загрузить датасет и разобрать его содержимое. поможет построить график.

Этот код открывает наш CSV и рисует гистограммы для всех колонок, за исключением ID и Date. Tак мы можем выбрать, какие колонки использовать для обучения модели:

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

Вот какой график выбрал я (все гистограммы):

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

Если что: Grad — это оценка уровня качества здания. Подробнее об уровнях качества зданий можно почитать здесь, в разделе BUILDING GRADE .

3. Подготавливаем данные

Итак, для обучения модели мы будем использовать скачанный датасет. Но как узнать, достаточно ли точная наша модель?

Давайте её протестируем, и для этого воспользуемся тем же датасетом. Чтобы один датасет пригодился для обучения и тестирования, разделим его на две части: одну для обучения, вторую для тестирования. Это нормальный подход.

Обучать будем на 80 % данных, а остальные 20 % возьмём для теста. Есть и другие устоявшиеся соотношения, но для выбора подходящего варианта, скорее всего, придётся действовать методом проб и ошибок.

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

Приведённый код генерирует два файла:

  • training.csv — содержит записи для обучения модели.
  • testing.csv — содержит записи для тестирования.
4. Обучаем модель

Теперь приступим к обучению. Для этого годятся разные пакеты, мы возьмём github.com/sajari/regression, в нём реализовано всё необходимое.

Конечно, можно написать всё с нуля, но пока не будем усложнять.

Сначала скачаем записи из training.csv , пройдём по ним и положим в модель данные из колонок Price и Grade .

Теперь обучим модель находить нашу линейную функцию.

После завершения исполнения получим формулу:

5. Тестируем модель

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

Протестируем формулу. Для этого возьмём созданный ранее файл testing.csv .

Хотя у нас есть тестовые данные, нам всё же нужны какие-то данные на выходе, по которым мы поймём, насколько точна формула. Для этого воспользуемся значением коэффициента детерминации.

Коэффициент детерминации говорит нам, при какой доле зависимых переменных мы сможем прогнозировать независимые переменные. В нашем случае — сколько цен на дома можно спрогнозировать на основе данных из колонки Grade.

Генерируемое значение коэффициента будет лежать в диапазоне от 0 до 1 (чем выше, тем лучше).

Вот код, генерирующий коэффициент детерминации:

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

Вот что у нас получилось:

Попробуем визуализировать нашу регрессию и попытаемся её улучшить.

6. Визуализируем модель

Для визуализации напишем ещё немного кода:

И наконец-то мы получили нашу первую линейную регрессию:

Если посмотреть внимательнее, то станет понятно, что синие кружки лучше всего укладываются на кривую линию, а не прямую.

Чтобы улучшить результат, можно попробовать заменить текущую линейную формулу параболической: y = ax + bx^2 + c .

И опять использовать колонку Grade для представления x-переменной, и новая формула будет выглядеть так:

Получим новую формулу:

Стало получше! Помните, нужно получить значение как можно ближе к 1.

Теперь обновим код, рисующий график:

Можно сделать ещё ряд улучшений, чтобы получить значение коэффициента детерминации ближе к 1, если хотите — поэкспериментируйте. Также можно попробовать улучшить модель, изменяя или комбинируя разные переменные.

Допустим, нас устраивает формула прогнозирования, начнём её использовать. Скажем, мы хотим узнать, сколько денег можно выручить на продаже дома в категории Grade 3 в округе Кинг. Вставим значение Grade в формулу и получим цену:

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

📎📎📎📎📎📎📎📎📎📎