«Как по нотам!» или Машинное обучение (Data science) на C# с помощью Accord.NET Framework

МЕНЮ


Искусственный интеллект. Новости
Поиск

ТЕМЫ


Внедрение ИИНовости ИИРобототехника, БПЛАТрансгуманизмЛингвистика, обработка текстаБиология, теория эволюцииВиртулаьная и дополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информации

RSS


RSS новости

Авторизация



Новостная лента форума ailab.ru

Вчера после публикации статьи zarytskiy «Какой язык программирования выбрать для работы с данными?» я понял, что .net в целом и C# в частности не рассматривается, как инструмент для машинного обучения и анализа данных. Не то, чтобы для этого совсем не было объективных причин, но все же надо восстановить справедливость и потратить пару минут на рассказ о фреймворке Accord.NET.

Итак, в прошлой статье цикла, посвящённого обучению Data Science с нуля, мы с вами разбирали вопрос создания своего собственного набора данных и обучение моделей из библиотеки scikit-learn (Python) на примере задачи классификации спектров излучения ламп и дневного света.

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

Для начала надо отметить, что машинное обучение, Python и C# я знаю одинаково плохо, ну то есть почти никак, поэтому данная статья вряд ли подарит читателю, какой-то виртуозный код или особо ценную информацию. В прочем мы такую цель и не ставим, ведь правда?

Фрагменты кода и данные, как и прежде можно взять на GitHub

Часть 1. Прелюдия

Вкратце напомню о чем шла речь в прошлой статье:

С помощью открытого проекта Spectralworkbench (Public Lab), я собрал для вас небольшую коллекцию спектров дневного света, люминесцентных ламп и светодиодных ламп предположительно различных оттенков белого света и с различным качеством цветопередачи. В наборе содержалось по 30 обучающих образцов каждого класса и по 11 контрольных соответственно.

Дальше после долгих моих разглагольствований мы наконец приступили к непосредственно машинному обучению и в итоге обучили: классификаторы RandomForestClassifier и LogisticRegression, в том числе с подбором параметров, также побаловались с отображением признаков в двухмерном виде с помощью T-SNE и PCA, под конец попробовали сделать кластеризацию данных с помощью DBSCAN, ну а завершила статью моя эпичная битва с компьютером, которую я к сожалению проиграл с результатом в пару % точности предсказания.

Часть 2. Ария

Итак, беглый поиск в Интернете говорит, о том, что Accord.NET один из самых популярных в экосистеме .Net, видимо по тому, что в первую очередь заточен под C#, хотя есть и другие, например, Angara (заточена под F#). Безусловно платформа позволяет запускать фреймворки на всех языках .Net (ну или точно подавляющем большинстве языков).

Первое, что бросается в глаза, это все же на порядок меньшая популярность фреймворка по сравнению с решениями на Python или R, как следствие полагаться придется на примеры и документацию, документация, для новичка могла бы быть и побольше разжёвана, а примеры в основном встречаются в виде уже собранных проектов, которые хорошо бы открывать в Visual Studio. После целого моря информации по машинному обучению c Питоном, это немного отталкивает, видимо именно поэтому в данном случае я ограничился только классификацией (SVM) и отображением признаков с помощью PCA.

Итак, нам понадобится MS Visual Studio (у меня была 2015) или MonoDevelop (например, для Linux).

В принципе можно воспользоваться инструкцией для быстрого старта, а можно поверить мне на слово. Пример буду приводить для Visual Studio:

  1. Создаём новое консольное приложение.
  2. Добавляем ссылку на сборку System.Windows.Forms.dll, она нам пригодится для отображения графиков.
  3. Добавляем пакеты NuGet: Accord, Accord.Controls, Accord.IO, Accord.MachineLearning, Accord.Statistics (часть из них итак добавиться сама, когда один потянет другие)
  4. Начинаем «кодить»

Открываем Program.cs и добавляем пространства имен:

using System; using System.Linq; using Accord.Statistics.Models.Regression.Linear; using Accord.Statistics.Analysis; using Accord.IO; using Accord.Math; using System.Data; using Accord.MachineLearning.VectorMachines.Learning; using Accord.Math.Optimization.Losses; using Accord.Statistics.Kernels; using Accord.Controls; 

Дальше для простоты все запихнем в базовый класс

  class Program     {         static void Main(string[] args)         { 

Итак:

Читаем данные, к сожалению удобной библиотеки, Pandas у нас нет, но есть аналоги (хоть и менее удобные на мой взгляд).

Один из минусов, это опять-таки не очевидность, я собрал пару «велосипедов» прежде чем понял, что Accord предлагает свое решение для обработки csv или xsls при желании.

//This is a program for demonstrating machine              //learning and classifying the spectrum of light sources using .net              //read data (If you use linux do not forget to correct the path to the files)             string trainCsvFilePath = @"data	rain.csv";             string testCsvFilePath = @"data	est.csv";             DataTable trainTable = new CsvReader(trainCsvFilePath, true).ToTable();             DataTable testTable = new CsvReader(testCsvFilePath, true).ToTable();             // Convert the DataTable to input and output vectors (train and test)             int[] trainOutputs = trainTable.Columns["label"].ToArray<int>();             trainTable.Columns.Remove("label");             double[][] trainInputs = trainTable.ToJagged<double>();             int[] testOutputs = testTable.Columns["label"].ToArray<int>();             testTable.Columns.Remove("label");             double[][] testInputs = testTable.ToJagged<double>();   

Собственно, обучаем модель классификатора, если вам уже впиталась в душу терминология scikit-learn, то по началу будет не привычно. Но в принципе все должно быть понятно в teacher запихиваем класс модели, потом обучаем ее на данных, потом вызываем предсказание меток (напомню: 0 – светодиод, 1 – лампа, — 2 дневной свет)

             // training  model SVM classifier             var teacher = new MulticlassSupportVectorLearning<Gaussian>()             {                 // Configure the learning algorithm to use SMO to train the                 //  underlying SVMs in each of the binary class subproblems.                 Learner = (param) => new SequentialMinimalOptimization<Gaussian>()                 {                     // Estimate a suitable guess for the Gaussian kernel's parameters.                     // This estimate can serve as a starting point for a grid search.                     UseKernelEstimation = true                 }             };              // Learn a machine             var machine = teacher.Learn(trainInputs, trainOutputs);              // Obtain class predictions for each sample             int[] predicted = machine.Decide(testInputs); 

Дальше распечатаем данные (результат будет, чуть позже на картинке)

// print result             int i = 0;             Console.WriteLine("results - (predict ,real labels)");             foreach (int pred in predicted)             {                  Console.Write("({0},{1} )", pred, testOutputs[i]);                 i++;             }              //calculate the accuracy             double error = new ZeroOneLoss(testOutputs).Loss(predicted);              Console.WriteLine("
 accuracy: {0}", 1 - error); 

Ну и финальный аккорд — трансформируем данные с помощью PCA и выведем диаграмму рассеяния

            // consider the decrease in the dimension of features using PCA             var pca = new PrincipalComponentAnalysis()             {                 Method = PrincipalComponentMethod.Center,                 Whiten = true             };              pca.NumberOfOutputs = 2;             MultivariateLinearRegression transform = pca.Learn(trainInputs);             double[][] outputPCA = pca.Transform(trainInputs);              // print it on the scatter plot             ScatterplotBox.Show(outputPCA, trainOutputs).Hold();              Console.ReadLine(); 

Ну вот, что получилось в итоге:

Давайте сравним с тем что поучилось в прошлой статье для
Логистической регрессии с подобранными параметрами
(предсказание, факт):
[(0, 0), (0, 0), (0, 0), (2, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (2, 0), (1, 1), (1, 1), (1, 1), (1, 1), (2, 1), (2, 1), (1, 1), (1, 1), (1, 1), (1, 1), (2, 1), (2, 2), (2, 2), (2, 2), (0, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2)]
accuracy on test data: 0.81818

как видите результат сопоставим.

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

Часть 3. Финал.

Давайте подведем итоги. Понятно, что опыта у меня мало, чтобы судить объективно, так что буду субъективен.

1. По началу после Python, возврат к .Net и этому фреймворку «вымораживал» жутко. К динамической типизации и удобным манипуляциям с данными быстро привыкаешь. Также раздражали другие названия моделей и то, что их чертовски много и для всего реализован свой класс (ну что поделать такова парадигма C#)

2. Качать проекты целиком не хотелось, а примеры к описанию классов «куцые» в итоге разбор даже того, что я вам сюда выложил, отнял у меня больше времени, чем бы хотелось, с мульти-классовой классификацией я так толком и не разобрался, в scikit-learn, оно как-то намного лучше из коробки выходит.

3. С другой стороны — модель показала такую же точность и даже не пришлось перебирать параметры, думаю и cлучайный лес тоже бы сошелся, если бы я не поленился разобраться с его реализациями.

4. Где это применять? Ну по всей видимости, во-первых, в приложениях, базирующихся на Windows Forms – технологии безусловно почетной и заслуживающей уважения, но уже давно устаревшей и MS не развиваемой, с другой стороны я не пробовал, но вполне возможно, что Аккорд подцепится к универсальным приложениям Windows и тогда с его помощью можно будет решать задачи машинного обучения и анализа данных в малых устройствах под управлением Windows IoT.

5. Если кого интересует кроссплатформенность, то да — она есть! Не поленился поставил себе на вторую систему (Mint) MonoDevelop и проверил, проект собирается и запускается, а значит и под MacOS должно тоже пойти.

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

Ну всё, на этом все обещания, которые я дал в статье «Паровозик, который смог!» или «Специализация Машинное обучение и анализ данных», глазами новичка в Data Science» — выполнены, так что могу ненадолго уйти на покой с чистой совестью.

Всем успехов и хороших выходных!

Источник: habrahabr.ru