Azure Machine Learning: розробка сервісів машинного навчання та їх використання в мобільному додатку

Висловлюємо велике спасибі за підготовку статті Євгена Григоренка, Microsoft Student Partner, @evgri243) за допомогу в написанні цієї статті. Інші наші статті по темі Azure можна знайти по тегу azureweek
Машинне навчання – одна з найпопулярніших областей Computer Science, хоча в той же час одна з найбільш избегаемых серед розробників. Основна причина цього в тому, що теоретична частина машинного навчання вимагає глибокої математичної підготовки, яку багато хто воліють відразу ж забути по закінченні університетського навчання. Але необхідно розуміти, що крім теоретичних основ, існує також і практична сторона, яка виявляється значно простіше для освоєння і щоденного використання. Мета цієї роботи – ліквідувати розрив між програмістами та спеціалістами по обробці даних і показати, що використання машинного навчання в своїх додатках може бути досить простим завданням. У статті викладається вся послідовність кроків, необхідна для побудови моделі прогнозування ціни автомобіля залежно від його характеристик з подальшим її використанням в мобільному додатку Windows 10 Mobile.

Що таке Azure ML?

Якщо коротко, то Azure Machine Learning – це:
  • хмарне рішення, що дозволяє побудова і використання складних моделей машинного навчання в простій і наочній формі;
  • екосистема, призначені для розповсюдження та монетизації готових алгоритмів.
Більше інформації про Azure ML ви можете знайти далі в цій статті, а також перейшовши по посилання

Чому саме Azure ML?
Тому, що Azure Machine Learning – один з найпростіших інструментів для використання машинного навчання, прибирає вхідний бар'єр для всіх, хто вирішує використовувати його для своїх потреб. З Azure ML більше не треба бути математиком.

Логічний процес побудови алгоритму машинного навчання



  1. Визначення мети. Всі алгоритми машинного навчання марні без явно-певної мети проведення експерименту. В даній лабораторній роботі мета – це передбачення ціни автомобіля на основі набору характеристик, наданих кінцевим користувачем.
  2. Збір даних. Під час цього етапу формується вибірка даних, необхідна для подальшого навчання моделі. В даному випадку будуть використовуватися дані репозитарію машинного навчання університету Каліфорнії.
    archive.ics.uci.edu/ml/datasets/Automobile
  3. Підготовка даних. На цьому етапі проводиться підготовка даних шляхом формування характеристик, видалення викидів і поділу вибірки на навчальну та тестову.
  4. Розробка моделі. В процесі розробки моделі проводитися вибір одного або декількох моделей даних і відповідних алгоритмів навчання, які на думку розробника повинні будуть дати необхідний результат. Часто цей процес поєднаний з паралельним дослідженням ефективності декількох моделей і візуальним аналізом даних з метою відшукання будь-яких закономірностей.
  5. Навчання моделі. Під час навчання алгоритм навчання здійснює пошук прихованих закономірностей у вибірці даних з метою відшукання способу передбачення. Сам процес пошуку визначається обраною моделлю і алгоритмом навчання.
  6. Оцінка моделі. Після того як модель навчена необхідно дослідити її прогностичні характеристики. Найчастіше для цього її проганяють на тестовій вибірці і оцінюють отриманий рівень помилки. Залежно від цього і вимог до точності модель може бути прийнята в якості підсумкової, так і проведено повторне навчання після додавання нових вхідних характеристик або навіть зміни алгоритму навчання.
  7. Використання моделі. В разі успішного тестування навченої моделі настає стадія її використання. І це той випадок, коли Azure ML стає незамінний, даючи всі необхідні інструменти для публікації, моніторингу та монетизації алгоритмів


Побудова прогностичної моделі

Для початку відвідайте посилання , в пункті меню Products виберіть Analytics і натисніть Machine Learning. Або скористайтесь прямим посиланням.



На сторінці, що відкрилася, натисніть Get Started now.

Для роботи з Azure ML вам необхідна активна підписка Microsoft Azure. Якщо вона у вас вже є, то просто увійдіть у Microsoft Management Portal, інакше – попередньо зареєструйте безкоштовну обліковий запис, перейшовши за посилання.

Після успішної авторизації ви опинитеся на головній сторінці Azure ML Studio – середовищі, де буде відбуватися вся подальша робота.



Завантаження даних

В першу чергу необхідно завантажити навчальну вибірку. Для цього перейдіть за посилання і завантажте на свій комп'ютер файл imports-85.data, що містить вибірку даних по автомобілям.
Для завантаження цього файлу в Azure ML Studio натисніть на New у нижній частині сторінки і в панелі виберіть Dataset і From Local File. У меню завантаження вкажіть шлях до завантажений файл, назва і тип виберіть Generic CSV File with no header (.hn.csv).



Створення нового експерименту

Для того щоб створити новий експерименту виберіть New -> Experiment -> Blank Experiment. В результаті буде створена нова робоча область експерименту з панеллю інструментів праворуч.



Визначення вибірки даних

Раніше завантажені дані повинні бути відображені в розділі Saved Datasets ліворуч. Виберіть та перетягніть в будь-яке місце робочого простору, наприклад, туди, куди вказує стрілка Drag Items Here.



Зверніть увагу, що джерело даних має точку з'єднання у формі гуртка, яка використовується для підключення його до інших компонентів.

Підготовка даних

При розробці моделей машинного навчання хорошою практикою є перевірка попередніх результатів експерименту після кожної зміни. Тому натисніть правою кнопкою миші на точку з'єднання і виберіть Visualize. В результаті з'явиться вікно, що дає загальне уявлення про даних та їх розподіл.



Як можна помітити, у вибірці є проблема – відсутні значення у другому стовпці. Це може створити небажаний ефект в процесі навчання і значно погіршити якість моделі. Але, на щастя, ці значення характеризує страхові витрати і слабко пов'язані з ціною автомобіля, а тому їх можна видалити. Крім усього іншого в стовпців відсутні імена, що значно ускладнює роботу з ними.

Для виправлення проблеми з іменами з групи Data Transformation/Manipulation перенесіть на робочу поверхню Metadata Editor.

Перетягніть вихід (знизу) вибірки даних на вхід (зверху) нового компонента, щоб з'єднати їх. Тепер натисніть на нього, щоб відкрити вікно налаштувань праворуч. Metadata Editor дозволяє змінити метаінформацію одного або декількох стовпців, включаючи тип або назва. Відкрийте майстер вибору стовпців натисканням на Launch column selector. Щоб вибрати всі стовпці, в полі Begin With виберіть All columns, видаліть рядок уточнення вибору натисканням на знак “-“ праворуч і підтвердіть натисканням на галочку.

У полі New column names панелі налаштувань введіть нові імена стовпців через кому, які можна знайти у файлі import-85.names за раніше наводилася посиланням. Значення поля повинно бути наступним:

symboling,normalized-losses,make,fuel-type,aspiration,num-of-doors,body-style,drive-wheels,engine-location,wheel-base,length,width,height,curb-weight,engine-type,num-of-cylinders,engine-size,fuel-system,bore,stroke,compression-ratio,horsepower,peak-rpm,city-mpg,highway-mpg,price

Для того, щоб побачити результат роботи компонента, натисніть на Run знизу і візуалізуйте вихід Metadata Editor описаним раніше способом.



Тепер видалимо normalized-losses. Для цього перетягніть в робочу область Project Columns з тієї ж групи, з'єднайте його з Metadata Editor і перейдіть до налаштувань. Знову виберіть майстер вибору рядків і в цей раз виберіть всі рядки за винятком normalized-losses, зробивши налаштування, аналогічні наведеним на малюнку нижче.



Запустіть експеримент і візуалізуйте результат, щоб переконатися, що другий стовпець пропав з вибірки.

На жаль, є ще стовпці, в яких відсутні значення. Але їх не багато, а тому можна обмежитися лише відкиданням неповних рядків. Для цього виберіть Missing Value смуги навігації і з'єднайте його з Project Columns. У полі For missing values змініть значення на Remove entire row. Запустіть, візуалізуйте і переконайтеся, що рядки з порожніми значеннями пропали.



Залишився останній питання, яке необхідно відповісти на етапі підготовки: всі характеристики впливають на ціну автомобіля? На даному етапі можна обмежитися наступним невеликим числом показників, список яких наведено нижче. Надалі ви завжди зможете додати нові та перевірити гіпотезу про їх достатності, порівнявши точність отриманих моделей.

make,body-style,wheel-base,engine-size,horsepower,peak-rpm,highway-mpg,num-of-cylinders,price

Додайте новий Project Columns і виберіть наведені вище стовпці.



На закінчення переконайтеся, що підготовка даних виконується успішно, запустивши експеримент та візуалізовано результат.

Розбиття вибірки

Тепер дані готові до використання в процесі навчання. Але в машинному навчанні можливий ефект, що отримав назву «перенавчання», – заучування моделлю даних без узагальнення. Така поведінка веде до неможливості адекватного прогнозування на скільки-небудь відрізняються даних. Для обробки цієї ситуації вибірку прийнято розділити на навчальну та тестову щодо близькому до 3:1. Остання з них ніяк не бере участь в процесі навчання і після закінчення використовується для оцінки помилки передбачення. Якщо ця помилка значно відрізняється в більшу сторону від помилки на навчальній вибірці, значить, спостерігається описаний вище ефект.

Для створення тестової вибірки перенесіть на робочу область експерименту і з'єднайте з останнім Project Columns компонент Split Data з групи Data Transformation/Sample and Split. Встановіть частку рядків на першому виході дорівнює 0.75 і переконайтеся, що встановлено прапорець Randomize Split.

Навчання моделі лінійної регресії

Першим ділом перенесіть з панелі інструментів компоненти Linear Regression, Model Train, Score Model і Evaluate Model. Model Train – універсальний компонент, що дозволяє навчання будь-якої моделі на будь навчальної вибірки. Для налаштування нашого конкретного випадку під'єднайте перший (лівий) вихід Split Data і вихід Linear Regression до відповідних входів Model Train. У налаштуваннях Model Train в якості цільового значення (outcome column) вкажіть price. Тепер модель готова до навчання.

Але, крім самого навчання, важливо дізнатися результат навчання. Компонент Score Model дозволяє обчислити вихід навченої моделі на довільній вибірці і розрахувати результат передбачення. З'єднайте вихід Model Train, що містить навчену модель, з відповідним входом Score Model, а в якості вибірки даних на інший вхід подайте тестову вибірку з другого виходу Split Data. Вихід Score Model з'єднайте з будь-яким з входів Evaluate Model для того, щоб розрахувати числові характеристики якості навчання. У результаті повинна вийти процес, аналогічний представленому на малюнку.



Запустіть модель і візуалізуйте результат виконання Evaluate Model.



Коефіцієнт детермінації вказує, як добре лінія регресії описує вихідні дані. Прийняті їй значення варіюються від 0 до 1, де одиниці відповідає абсолютна точність. В нашому випадку коефіцієнт дорівнює 82%. Чи Хороший це результат чи ні – прямо залежить від постановки задачі і певної толерантності до помилки. Для випадку передбачення ціни автомобіля 82% — відмінний результат. Якщо ви хочете поліпшити спробуйте додати інші стовпці Project Columns або спробувати принципово інший алгоритм. Наприклад, Poisson Regression. Останнє може бути досягнуто шляхом простої заміни компонента лінійної регресії на пуасонову. Але більш цікавий підхід – це зібрати з елементів паралельне навчання і підключити результат до другого виходу Evaluate Model, що дозволить в зручній формі порівняти результати навчання обох моделей.



Виконайте модель і візуалізуйте результат. Як видно з результату, дані значно краще описуються моделлю лінійної регресії, а тому є всі підстави обрати саме її в якості підсумкової.



Клікніть правою кнопкою миші по компоненту Model Train, який відповідає лінійної регресії і виберіть Save as Trained Model. Це дозволить використовувати отриману модель в будь-яких інших експериментах без необхідності повторного навчання.

Публікація веб-сервісу

Для публікації сервісу виберіть компонент Model Train, який відповідає лінійної регресії та натисніть Set Up Web Service. У меню, виберіть Predictive Web Service [Recommended] та зачекайте, поки Azure ML створить новий експеримент, оптимізований для потреб сервісу. Видаліть автоматично створені компоненти Web Service Input і Web Service Output – ми створимо їх пізніше після невеликої підготовки.

На даний момент елемент Score Model повторює на виході всі вхідні стовпці, а передбачуваним значенням дає назву Score Labels. Це необхідно виправити.

Для цього перенесіть з панелі інструментів на робочу поверхню два вже знайомих компонента: Project Columns і Metadata Editor. І з'єднайте їх в послідовності зображеної на малюнку нижче. У налаштуваннях Project Columns виберіть тільки один стовпець Score Labels, і використовуючи Metadata Editor перейменуйте його в price.

На закінчення необхідно додати вхід і вихід створюваного сервісу. Для цього додайте в експеримент Web Service Input і Web Service Output. З'єднайте перший з входом Score Model, а другий з виходом Metadata Editor. У налаштуваннях обох елементів змініть назву на «input» і «prediction», відповідно.

Запустіть модель ще раз, натиснувши на Run, і по закінченні валідації опублікуйте сервіс натисканням Deploy Web Service.



Тестування сервісу

Після натискання на Deploy Web Service ви будете перенаправлені на сторінку з інформацією про тільки що створеному сервісі. Посилання під API HELP PAGE містять досить докладний опис з інформацією про вміст вхідного і вихідного JSON пакетів, а також приклад коду консольного додатка, що дає уявлення про спосіб використання.



Для інтерактивного дослідження натисніть на Test і у вікні, введіть значення для кожного вхідного параметра. Наприклад, ті, що вказані нижче, і натисніть галочку, щоб відправити тестовий запит.

audi sedan 99.8 four 109 102 5500 30 13950



Розробка програми

На закінчення розглянемо процес розробки мобільного додатку, що використовує Azure ML в ролі back-end сервісу. Спочатку створіть новий проект універсального додатка Windows. Для цього у відкритому Visual Studio 2015 виберіть File — > New -> Project… У вікні, перейдіть на вкладку Windows в меню зліва виберіть Blank App (Universal Windows). У полі назви введіть AzureMLDemo і натисніть OK. У разі необхідності готовий проект може бути знайдений на GitHub.



Після певної підготовки Visual Studio відкриє новий проект універсального додатка. Переконайтеся, що у полі процесорної архітектури праворуч від Debug зазначено x86, і правіше виберіть одну з мобільних віртуальних машин в якості середовища запуску. Наприклад, Mobile Emulator 10.0.10240.0 720p 5 inch 1GB.

Тепер можна перейти до написання самого додатка. У меню Solution Explorer подвійним клацанням відкрийте MainPage.xaml. Опис мови розмітки XAML графічного інтерфейсу виходить за межі цієї роботи, тому просто замініть відкривається і закривається теги <Grid ...> код нижче.

<ScrollViewer Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden">
<StackPanel>
<TextBlock Text="Estimate the price of your dream car"
Style="{ThemeResource TitleTextBlockStyle}"
TextAlignment="Center" HorizontalAlignment="Center"
Margin="5,20,5,5" TextWrapping="WrapWholeWords"/>
<Border Margin="5 10" BorderBrush="LightGray" BorderThickness="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Авто"/>
<ColumnDefinition Width=".*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>

<TextBlock Text="Make" Grid.Row="0" Grid.Column="0"
VerticalAlignment="Center" HorizontalAlignment="Right"
Margin="5"/>
<TextBox Name="tbxMake" Text="Audi" Grid.Row="0" Grid.Column="1"
Grid.ColumnSpan="2" VerticalAlignment="Center"
HorizontalAlignment="Stretch" Margin="5"/>

<TextBlock Text="Body Style" Grid.Row="1" Grid.Column="0"
VerticalAlignment="Center" HorizontalAlignment="Right"
Margin="5"/>
<TextBox Name="tbxBodyStyle" Text="Sedan" Grid.Row="1"
Grid.Column="1" Grid.ColumnSpan="2"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
Margin="5"/>

<TextBlock Text="Wheel Base" Grid.Row="2" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<Slider Name="slWheelBase" Value="99" Grid.Row="2" Grid.Column="1" 
Minimum="86" Maximum="121" StepFrequency="1" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5,5,3,5"/>
<TextBlock Name="tbWheelBase" Grid.Row="2" Grid.Column="2" 
Text="{x:Bind slWheelBase.Value, Mode=OneWay}" 
VerticalAlignment="Center" Margin="2,5,5,5"/>

<TextBlock Text="Number of Cylinders" Grid.Row="3" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<TextBox Name="tbxNumberOfCylinders" Text="Four" Grid.Row="3" 
Grid.Column="1" Grid.ColumnSpan="2" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5"/>

<TextBlock Text="Engine Size" Grid.Row="4" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<Slider Name="slEngineSize" Value="109" Grid.Row="4" Grid.Column="1" 
Minimum="61" Maximum="326" StepFrequency="1" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5,5,3,5"/>
<TextBlock Name="tbEngineSize" Grid.Row="4" Grid.Column="2" 
Text="{x:Bind slEngineSize.Value, Mode=OneWay}" 
VerticalAlignment="Center" Margin="2,5,5,5"/>

<TextBlock Text="Horsepowers" Grid.Row="5" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<Slider Name="slHorsepowers" Value="102" Grid.Row="5" Grid.Column="1" 
Minimum="48" Maximum="288" StepFrequency="1" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5,5,3,5"/>
<TextBlock Name="tbHorsepowers" Grid.Row="5" Grid.Column="2" 
Text="{x:Bind slHorsepowers.Value, Mode=OneWay}" 
VerticalAlignment="Center" Margin="2,5,5,5"/>

<TextBlock Text="Peak PRM" Grid.Row="6" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<Slider Name="slPeakRPM" Value="5500" Grid.Row="6" Grid.Column="1" 
Minimum="4150" Maximum="6600" StepFrequency="1" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5,5,3,5"/>
<TextBlock Name="tbPeakRPM" Grid.Row="6" Grid.Column="2" 
Text="{x:Bind slPeakRPM.Value, Mode=OneWay}" 
VerticalAlignment="Center" Margin="2,5,5,5"/>

<TextBlock Text="Highway MPG" Grid.Row="7" Grid.Column="0" 
VerticalAlignment="Center" HorizontalAlignment="Right" 
Margin="5"/>
<Slider Name="slHighwayMPG" Value="30" Grid.Row="7" Grid.Column="1" 
Minimum="16" Maximum="54" StepFrequency="1" 
VerticalAlignment="Center" HorizontalAlignment="Stretch" 
Margin="5,5,3,5"/>
<TextBlock Name="tbHighwayMPG" Grid.Row="7" Grid.Column="2" 
Text="{x:Bind slHighwayMPG.Value, Mode=OneWay}" 
VerticalAlignment="Center" Margin="2,5,5,5"/>
</Grid>
</Border>
<Button Name="btnGetEstimate" Grid.Row="2" Content="Get estimate" 
HorizontalAlignment="Center"/>
<TextBlock Name="tbResult" TextAlignment="Left" Margin="10 5" 
TextWrapping="Wrap"/>
</StackPanel>
</ScrollViewer>


Незважаючи на всю позірну складність цей код створює досить просту розмітку, необхідну для введення даних. Кожен елемент вводу одного з параметрів моделі має назву начебто tbxMake, txbBodyStyle і т. п. Під ними знаходиться кнопка Get Estimate, що відповідає за відправлення повідомлення до сервісу Azure ML, а завершується все елементом tbResult, який і буде поміщатися результат виклику.

Запустіть програму, натиснувши на Debug -> Start Debugging, щоб переконатися, що все було зроблено правильно, проект компілюється і запускається. Перевірте, що зміна положення слайдерів призводить до відповідної зміни чисельного значення праворуч від них.

Зупиніть сесію налагодження натисканням на Debug -> Stop Debugging.

Визначення програмної логіки

Тепер необхідно визначити код обробки натиснення на кнопку Get Estimate. В Solution Explorer розгорніть MainPage.xaml і клацніть двічі по MainPage.xaml.cs, щоб відкрити Code-behind файл графічного інтерфейсу.

Насамперед слід підключити декілька необхідних бібліотек. Для цього клікніть правою кнопкою миші по імені проекту і виберіть Manage Nuget Packages… В меню зробіть пошук за WebApi.Сlient і встановіть пакет з назвою Microsoft.AspNet.WebApi.Client.



Після цього додайте в початок файлу наступні додаткові оголошення using:

using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Threading.Tasks;
</source
Наступним кроком додайте в клас MainPage кілька полів, що містять необхідну інформацію для підключення до сервісу.

<source lang="cs">
public sealed partial class MainPage : Page
{
const string _apiKey = @"<your API key>";
const string _requestUri = @"Your key";

Ключ доступу можна знайти на сторінці вашого Dashboard сервісу, а адресу запиту на сторінці допомоги REQUEST/RESPONSE, посилання на яку наведено трохи нижче.




Наступним кроком додамо допоміжну функцію, яка буде здійснювати запит до сервісу Azure ML. Згідно з документацією, наведеною на тій же сторінці допомоги REQUEST/RESPONSE для отримання відповіді ми повинні виконати наступну послідовність дій: сформувати запит, відправити його в бік сервісу POST-запиту протоколу HTTP і обробити відповідь.
Створіть функцію CallAzureML, що приймає на вхід значення всіх параметрів моделі і повертає значення типу float c оцінкою ціни. Async Task тут відповідає реалізації патерну async/await, значно спрощує роботу з асинхронними викликами в додатку (додаткова інформація може бути знайдена тут).

private async Task<float> CallAzureML(string make, string bodyStyle, double wheelBase, 
string numberOfCylinders, int engineSize,
int horsepowers, int peakRPM, int highwayMPG)
{

}

Також для спрощення роботи з JSON ми будемо використовувати бібліотеку Newtonsoft.Json. Відмітною її особливістю є те, що вона дозволяє взаємодіяти з JSON-об'єктами через зручну абстракцію у вигляді звичайних об'єктів рівня .NET. Помістіть в початок методу наступний код.

var requestBody = new
{
Inputs = new Dictionary<string, object>()
{
{
"input",
new
{
ColumnNames = new string[] {"make", "body-style",
"wheel-base", "num-of-cylinders", 
"engine-size", "horsepower", 
"peak-rpm", "highway-mpg", 
"price"},
Values = new string[,] {
{ make, bodyStyle, wheelBase.ToString(), 
numberOfCylinders, engineSize.ToString(), 
horsepowers.ToString(), peakRPM.ToString(), 
highwayMPG.ToString(), "0" } }
}
}
},
GlobalParameters = new Dictionary<string, int>()
};

Тут структура JSON-об'єкта запиту відтворюється за допомогою анонімного класу і повністю (з урахуванням регістру) повторює структуру очікуваного запиту. Для порівняння приклад такого запиту зі сторінки REQUEST/RESPONSE представлений нижче.


{
"Inputs": {
"input": {
"ColumnNames": [ "make", "body-style", “wheel-base", "num-of-cylinders",
"engine-size", "horsepower", "peak-rpm", "highway-mpg",
"price" ],
"Values": [
[ "value", "value", "0", "value", "0", "0", "0", "0", "0" ],
[ "value", "value", "0", "value", "0", "0", "0", "0", "0" ]
]
}
},
"GlobalParameters": {}
}

Наступним кроком є виконання запиту до самого сервісу. Для цього додайте наступний код в розроблюваний метод.

try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer", _apiKey);
client.BaseAddress = new Uri(_requestUri);

var response = await client.PostAsJsonAsync("", requestBody);

if (response.IsSuccessStatusCode)
{
// succeeded
throw new NotImplementedException();
}
else
{
// failed
throw new NotImplementedException();
}
}
}
catch (Exception e)
{
throw;
}


Першим справах створюється HTTP-клієнт і встановлюється вся інформація необхідна для успішного підключення до сервісу в Azure ML: адреса і ключ доступу. Далі здійснюється POST-запит у бік сервісу з JSON-об'єктом, створеним раніше. Успішність виклику перевіряється за кодом стану HTTP.

Замініть код в області зазначеної коментарем succeeded на поданий нижче. В ньому послідовно відбувається отримання відповіді сервера у вигляді рядка, її розбір в динамічний об'єкт за допомогою конвертера Newtonsoft.Json з подальшим витяганням інформації про ціну. Приклад відповіді сервера для порівняння може бути знайдений в розділі «Тестування сервісу».

var responseContent = await response.Content.ReadAsStringAsync();
var val = JsonConvert.DeserializeObject<dynamic>(responseContent);

float? price = (float)val?.Results?.prediction?.value?.Values[0][0];
if (price == null)
throw new InvalidDataException("Response message has unknown format" + 
" or is empty.");

return (float)price;

У разі помилкового стану метод повинен повернути максимум інформації. Тому як і в минулому випадку у вигляді рядка витягується вміст запиту, але в цей раз він послідовно перетворюється в об'єкт і назад в рядок. Це необхідно для того, щоб додати відступи, що дозволяє більш зручне читання його вмісту. Замініть код в області, відміченої коментарем failed на наведений нижче.

var responseContent = await response.Content.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject(responseContent);
var formattedResponseContent =
JsonConvert.SerializeObject(responseObject, Formatting.Indented);

var message = String.Format("Server returned status code {0} with message {1}", 
response.StatusCode, formattedResponseContent);

throw new InvalidDataException(message);

Метод виклику до Azure ML можна вважати завершеним. Як можна помітити його реалізація досить проста, хоча за нею і будує цілий процес реалізації статистичної моделі даних, алгоритму навчання та способу оцінки довільного оцінки вхідного вектора. Досить складні математичні теорії вміщаються в пару рядків програмного коду.
На закінчення необхідно реалізувати обробник події натискання кнопки Get estimate. Першим ділом перейдіть в MainPage.xaml і додайте в XML-тег кнопки GetEstimate інформацію про оброблювачі подій.

<Button ... Click="GetEstimate_Click"/>

Поверніться в MainPage.xaml.cs і створіть відповідний метод. Він викликає створений раніше метод для звернення до сервісу Azure ML і встановлює результат в tbResult.

private async void GetEstimate_Click(object sender, RoutedEventArgs e)
{
try
{
var price = await CallAzureML(tbxMake.Text, tbxBodyStyle.Text, 
slWheelBase.Value, tbxNumberOfCylinders.Text, 
(int)slEngineSize.Value, (int)slHorsepowers.Value, 
(int)slPeakRPM.Value, (int)slHighwayMPG.Value);
tbResult.Text = String.Format("You are lucky!\n" +
"Today it is as cheap as {0:c}. Don't miss your chance!", price);
}
catch (Exception ex)
{
// Shows error in result TextBlock
tbResult.Text = String.Format("Oops! Something went wrong.\n" +
"This can be helpful:\n{0}", ex.ToString());
}
}

Все, додаток готове. Запустіть його і поекспериментуйте з оцінкою вартості автомобіля при різних наборах характеристик.



Висновок

Azure Machine Learning – це новий високопродуктивний інструмент для роботи з алгоритмами машинного навчання. Можливо, це навіть єдина середовище, яке дозволяє так легко опублікувати свої алгоритми у вигляді окремого сервісу і надалі використовувати їх в своїх додатках. У цій роботі використовувався один з найпростіших алгоритмів навчання – алгоритм лінійної регресії. У Azure ML доступні ще десятки інших, створених вченими для самих різних цілей. І найважливіше, що для їх використання зовсім немає необхідності бути математиком. Достатньо з допомогою компонентів зібрати необхідний процес обробки даних, провести кілька експериментів і в разі успіху опублікувати все у вигляді сервісу.
Ось ще кілька вибірок даних, на яких можна поекспериментувати:


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.