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

Основные материалы

Прежде чем приступить к собственно алгоритмам машинного обучения, я хотел создать оболочку вокруг структуры std::vector, а также какую-то структуру для многомерных данных, чтобы имитировать библиотеки Python NumPy и Pandas. Создание этих структур позволило мне легко загружать и изменять данные с помощью простых операторов без необходимости избыточных циклов повсюду, а также читать и анализировать CSV-файл. К сожалению, на данный момент нет поддержки парсинга строк для горячего кодирования, поэтому на данный момент только числовые значения. Вот фрагмент класса Серия, который я создал.

который выводит следующее

Test 1
<Series size=(3), objects=[10, 12, 14]>
Test 2
<Series size=(5), objects=[25, 25, 25, 25, 25]>
Test 3
<Series size=(7), objects=[1, 1.41421, 1.73205, 2, 2.23607, 2.44949, 2.64575]>

Теперь у нас есть поддержка векторного и скалярного умножения, что нам очень поможет! Я также создал класс DataFrame, который использует класс Series для хранения значений, сопоставленных со строковым ключом, аналогичным структуре Pandas DataFrame, вот пример ниже.

Подобно классу Series, DataFrame использует преимущества таких функций, как перегрузка операторов, чтобы сделать вещи простыми и даже Pythonic в использовании. Приведенный выше фрагмент кода имеет вывод…

DataFrame info
<DataFrame size=(8, 128)>
Prices
<Series size=(128), objects=[114300, 114200, 114800, 94700, 119800, 114600, 151600, 150700, 119200, 104000, 132500, 123000, 102600, 126300, 176800, 145800, 147100, 83600, 111400, 167200, 116200, 113800, 91700, 106100, 156400, 149300, 137000, 99300, 69100, 188000, 182000, 112300, 135000, 139600, 117800, 117100, 117500, 147000, 131300, 108200, 106600, 133600, 105600, 154000, 166500, 103200, 129800, 90300, 115900, 107500, 151100, 91100, 117400, 130800, 81300, 125700, 140900, 152300, 138100, 155400, 180900, 100900, 161300, 120500, 130300, 111100, 126200, 151900, 93600, 165600, 166700, 157600, 107300, 125700, 144200, 106900, 129800, 176500, 121300, 143600, 143400, 184300, 164800, 147700, 90500, 188300, 102700, 172500, 127700, 97800, 143100, 116500, 142600, 157100, 160600, 152500, 133300, 126800, 145500, 171000, 103200, 123100, 136800, 211200, 82300, 146900, 108500, 134000, 117000, 108700, 111600, 114900, 123600, 115700, 124500, 102500, 199500, 117800, 150200, 109700, 110400, 105600, 144800, 119700, 147900, 113500, 149900, 124600]>

Машинное обучение с линейной регрессией

Убрав эти классы, пришло время приступить к написанию нашего первого алгоритма машинного обучения, линейной регрессии. Линейная регрессия — это довольно простой алгоритм, использующий взвешенную сумму для прогнозирования значений. В то время как запись для линии на декартовом графике может выглядеть как y = mx+b, в машинном обучении запись (учет нескольких входных данных или функций) немного отличается.

Это значение y в начале — это то, что мы хотим предсказать, а эти множественные w перед x можно рассматривать как наклон, но с этого момента мы будем называть их весами. . Эта причудливая заглавная буква B в конце может рассматриваться как точка пересечения с осью y и известна как bias. Конечная цель состоит в том, чтобы каким-то образом обновить вес[ы] и смещение до тех пор, пока эта функция не станет достаточно точной с помощью итеративного процесса, называемого Градиентный спуск.

Я создал класс под названием LinearRegressor, который имеет функции fit() и Predict(), которые очень похожи на интерфейсы, которые Python использует для фреймворков машинного обучения, таких как scikitlearn или xgboost. Магия подгонки правильных данных, делающих модель точной, будет заключаться в функции fit(). Как видно из определения заголовка ниже, класс LinearRegressor также имеет частные свойства для хранения весов и смещения.

Функция подбора данных принимает значения x или функции в виде вектора ряда, где ряд — это столбец значений, а параметр «y» — это всего лишь один ряд уже правильных данных из любого набора данных. Кроме того, есть несколько вспомогательных методов для получения весов и смещения. Из-за общей сложности алгоритма в C++ я не буду объяснять его построчно, а расскажу об общей концепции.

https://github.com/rmiguelkelly/mlpp