В этом руководстве: Как читать CSV-файл в Rust? Как реализовать линейную регрессию? Давайте запачкаем руки и узнаем больше о rusty_machine.



Добро пожаловать в самый первый учебник по изучению Rust и применению этого фантастического языка программирования в машинном обучении.

Что вы узнаете в конце этого урока?

  • Как прочитать CSV-файл с помощью вашей пользовательской функции в Rust
  • Как написать код на Rust для работы с данными, определяя разделение поездов и тестов, а также создавая векторы и матрицы
  • Ознакомьтесь с нашим первым пакетом ML Rust: rusty_machine

Следите за новостями о следующем приключении, в котором мы расширим это руководство с помощью smartcore - еще одного мощного пакета ML Rust.

Линейная регрессия: что это такое?

Линейная регрессия - широко используемая модель от эпидемиологии до финансов и астрономии. Теория линейной регрессии относится к семейству обобщенных линейных моделей (GLM). Если вы хотите углубиться в математику, представленную ниже, просто взгляните на это введение в GLM и их приложения. Основная цель GLM - подобрать точки входных данных, которые подчиняются квазинормальному распределению и представляют постоянство дисперсии. Учитывая эти предположения, мы можем создать модель, которая прогнозирует новые точки данных при некоторых начальных условиях, максимизируя логарифмическую вероятность. Это приводит нас к модели линейной регрессии, которая соответствует заданному распределению с линейной аппроксимацией плюс / минус систематические ошибки.

CSV Reader: узнайте, как работать с CSV-файлами в Rust

Теперь, когда мы знаем модель, мы можем начать понимать, как работать с входными данными: https://github.com/Steboss/ml_and_rust/tree/master/regression/datasets

Как всегда, первым делом нужно создать новый пакет с cargo:

cargo new read_csv

В папке src мы можем переименовать main.rs в reader.rs, чтобы использовать этот пакет как внешнюю библиотеку для нашего кода регрессии. Чтобы создать эту библиотеку, мы создадим основной код Rust для анализа и чтения файла csv, а затем настроим файл Cargo.toml.

Чтобы разобрать csv-файл в Rust, мы можем следовать рис.1.

Первая функция, которую мы напишем, - это read_housing_csv, где будет считываться входной csv. Объявление этой функции определяет имя функции, тип пути к файлу и тип возвращаемого значения:

Таким образом, функция видима, pub, это функция fn, а вход - это путь impl AsRef<Path>, который поступает из импорта use std::path::Path;, и возвращается вектор HousingDataset. Ядро этой функции находится между строками 95–98, где мы собираемся обработать все строки файлов и отобразить их:

Каждая строка обрабатывается функцией read_single_line, которая создает новый вектор типа HousingDataset. Реализация типа HousingDataset выполняет грубую работу по синтаксическому анализу значений входных файлов. Во-первых, мы собираемся определить функцию для разворачивания каждой строки (30–34):

Это отличный пример, чтобы понять, как переносить текст в Rust и использовать команду map. По сути, мы берем входной вектор строк, v мы перебираем каждый элемент с iter(), затем мы определяем map. map принимает в качестве входных данных переменную с разделителями |, которая выполняет операцию с каждым элементом данного вектора, в данном случае parse().unwrap(). Если вы знакомы с Python, это похоже на lambda(x: do something) Наконец, все результаты должны быть собраны, поэтому мы добавляем .collect() - как в PySpark.

После анализа этих элементов мы можем связать каждый векторный элемент со структурой pub struct HousingDataset (строка 8). Как объясняется в нашем введении в Rust, это идеальный случай, чтобы увидеть и узнать, как создавать новый тип данных и реализовывать функциональные возможности с присущей им реализацией.

Для struct HousingDatasettype мы можем реализовать две дополнительные функции: pub fn train_features и pub fn train_target для разделения функций обучения и целевой функции. В первом случае мы возвращаем вектор с плавающей запятой с Vector<f64>, а для цели мы возвращаем просто с плавающей точкой f64 Строки 52–74 позволяют понять, как создать простой вектор и как работать с простыми функциями в Rust.

Теперь давайте настроим файл Cargo.toml. В этом файле мы должны определить все зависимости и функции кода. В этом случае я добавил в качестве зависимостей serde и serde_derive, чтобы разрешить сериализацию кода - мы вернемся к этому, но вы, возможно, заметили в коде reader.rs что-то вроде [derive(Debug)].. Наконец, мы будем использовать read_csv в качестве внешней библиотеки для нашей основная функция линейной регрессии. Таким образом, мы должны добавить ключевое слово [lib] в файл toml:

Здесь мы определяем имя этой библиотеки, которая будет использоваться для вызова функции позже, и путь к коду. Это означает, что в нашем основном коде мы импортируем эту функцию как read_csv::read_housing_csv, где read_csv - имя библиотеки, а read_housing_csv - основная функция для чтения csv файла.

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

Как и раньше, первым делом мы можем создать новый пакет cargo:

cargo new rust-regression

Здесь мы реализуем линейную регрессию с rusty_machine. Хотя название звучит не очень хорошо, rusty_machine - это пакет машинного обучения для Rust с большим количеством алгоритмов, уже реализованных и готовых к использованию. Поскольку мы собираемся использовать внешнюю библиотеку, первый вопрос: где мы получаем внешние библиотеки в Rust? И как их установить?

Любая библиотека в Rust называется crate. Здесь www.crates.io вы можете найти все ящики, которые вам нужны для конкретного пакета. Например, мы можем искать rusty-machine:

Щелкните rusty-machine, и вам будет предложено перейти на страницу со всеми подробностями об этом пакете, а также о процедуре «Установить»:

Как видите, для установки пакета вам просто нужно скопировать rusty-machine = "0.5.4" в свой Cargo.toml! Вуаля

Дополнительно в Cargo.toml мы можем добавить зависимость к созданной read_csv библиотеке. Это очень просто, как вы можете видеть в нашем последнем файле Cargo.toml, нам просто нужно использовать относительный путь к файлу:

Теперь давайте реализуем линейную регрессию. В каталоге src создайте новый файл с именем linear_regression.rs Во-первых, нам нужно импортировать все соответствующие rusty_machine функции, а также нашу read_csv библиотеку:

Как видите, в отличие от Python, rusty_machine требуются определенные типы для определения Matrix и Vector. Кроме того, в rusty_machine, когда мы импортируем rusty_machine::learning__lin_reg::LinRegressor, мы будем импортировать структуру линейной регрессии, единственный метод которой - train_with_optimization. Чтобы иметь полную функциональность для линейной регрессии, нам необходимо импортировать соответствующую черту - вы помните черту? Вы видите, насколько они важны сейчас? - что заставит нас использовать функции train и predict. Для этого нам нужно импортировать: use rusty_machine::learning::SupModel; который реализует признак для модели struct Наконец, стоит упомянуть, что в rusty_machine уже закодировано несколько метрик, поэтому мы вычисляем качество линейной регрессии, подходящей для neg_mean_squared_error ( здесь для справки ).

Второй шаг - реализовать часть предварительной обработки. В следующих уроках мы будем иметь дело с методами предварительной обработки, а сейчас давайте познакомимся с чтением входного файла и разделением данных на обучающие и тестовые наборы:

Вот несколько важных моментов, которые следует зафиксировать в уме:

  • как вы можете видеть, векторы входных данных имеют атрибут split_at, который пригодится для разделения массива
  • из вектора входных данных мы создаем векторы x_train, y_train, x_test, y_test путем плоского отображения переменных поезда и отображения целевых.
  • rusty_machine ХОЧЕТ свои собственные типы данных, поэтому нам нужно преобразовать x_train, y_train, x_test, y_test в rusty_machine::Matrix и rusty_machine::Vector. Время от времени это может быть довольно утомительно

Наконец, давайте реализуем модель, сделаем прогнозы и получим показатель mse:

Обратите внимание на концепцию владения в действии, где мы передаем по ссылке наши входные переменные. Затем, как объяснялось выше, мы должны преобразовать наши прогнозы и y_test векторы в формат Matrix, чтобы neg_mean_squared_error их прочитал rusty_machine. Это то, чего хочет rusty_machine, и это замечательное отличие, например, по сравнению с Python.

Самый последний шаг к воплощению всего в жизнь - это создание основного main.rs для нашего кода. Поскольку эта задача относительно проста, нам просто нужно импортировать модуль линейной регрессии и запустить его. Вот так просто:

Поскольку main.rs и linear_regression.rs находятся в одной папке, мы можем импортировать наш код как модуль с mod

ГОТОВЫ, УСТОЙЧИВЫЙ, ИДТИ: ЗАПУСТИТЕ СВОЙ ПЕРВЫЙ КОД РЖАВНИ ML!

Теперь у нас есть все готово для запуска нашего кода. Первым делом перейдите в папку rust-regression и введите cargo run. Это запустит cargo, прочитает Cargo.toml, установит зависимости и скомпилирует наш код. Если все пойдет хорошо, вы должны увидеть Cargo.lock файл, который запомнил мне pom.xml файл на Java со всеми установленными зависимостями и target папку без кода компиляции. Кроме того, cargo run запустит наш main.rs, и вы увидите окончательный результат, подобный этому:

Если вы достаточно довольны, вы можете собрать весь пакет с cargo build, который будет выполнять дальнейшую оптимизацию нашего кода, и вуаля!

Ваш первый код ML на Rust готов :) 🎊🎊🎊

На данный момент все! На первый взгляд это не так уж много, но для вас это значительный шаг вперед в изучении Rust и применении его в машинном обучении!

Если у вас возникнут вопросы или комментарии, напишите мне по электронной почте: [email protected].

Или вы можете связаться со мной в Instagram: https://www.instagram.com/a_pic_of_science/