Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
Работа с платёжными картами через эквайринг ПАО Сбербанк. Программа выполняет операции:• Прием и возврат платежей через ...
Бесплатная, сетевая программа для просмотра справочника кодов банков (БИК). Есть возможность сортировки справочника по л...
Программа выполняет следующие операции: * Запрос на поиск реквизитов по наименованию, адресу, региону и ФИО; * Фильтр по...
Утилита для массового переименования файлов. ReNamer позволяет добавлять или изменять префиксы и постфиксы в именах файл...
Программа предназначена для автоматизации работы компьютерных клубов. Внимательно следит за работой администраторов, вед...

Введение в Machine Learning Studio

Текущий рейтинг: 0 (проголосовало 0)
 Посетителей: 610 | Просмотров: 700 (сегодня 0)  Шрифт: - +
По поводу того, что точно означает термин «машинное обучение» (machine learning, ML), единодушия нет. На мой взгляд, ML — это любая система, использующая данные, чтобы помочь в прогнозировании. Например, вы хотите спрогнозировать, кто победит в Суперкубке или на какую группу (кластер) людей будет больше всего похож новый клиент.

Написание ML-систем с нуля, используя C# или любой другой язык программирования, — восхитительная задача, но занимающая много времени, требующая специализированных знаний и зачастую трудная. Новая Microsoft Azure ML Studio (выпущена в июле 2014 г.) значительно упрощает и ускоряет создание ML-систем, а также делает их более эффективными. В этой статье я пошагово разберу законченный пример, который поможет вам получить представление о ML Studio и приступить к работе с ней.

Лучший способ понять, куда я клоню в этой статье, — изучить экранный снимок на рис. 1. На нем показан законченный эксперимент в ML Studio. Цель эксперимента — предсказать партийность (демократ или республиканец) члена палаты представителей США, основываясь на предыдущем электоральном поведении.

*
Рис. 1. Законченный эксперимент в Azure ML Studio

В верхней строке видно, что ML Studio выполняется в Internet Explorer — она является веб-приложением. Точнее, ML Studio — это клиентская часть сервиса Microsoft Azure Machine Learning. С этого момента для простоты я буду использовать термин «ML Studio» как в отношении клиентской части, так и серверной части в Azure. В строке адреса вы заметите, что я использую внутренний URL «passau.cloupapp.net». При разработке проект ML Studio имел кодовое название «Passau», и вы можете встретить этот термин в документации. К тому времени, когда вы будете читать эту статью, на azure.microsoft.com появится общедоступный URL для ML Studio.

Применение ML Studio для создания ML-систем примерно аналогично использованию Visual Studio для создания исполняемых программ, хотя не следует слишком сильно полагаться на эту аналогию. Чтобы задействовать Visual Studio, вы можете либо купить ее, либо скачать бесплатную пробную версию. В случае ML Studio с вас взимают плату за пользование сервисом, но потом еще появятся варианты, позволяющие бесплатно ознакомиться с этой системой. Точные детали подвержены частым изменениям — постоянные изменения условий являются, по моему мнению, одним из главных недостатков работы с облачными системами. Я предпочитаю установить продукт на своем настольном компьютере, где любые изменения будут исключительно моим решением. В совершенно новом мире облачных вычислений вы вынуждены иметь дело с рабочей средой, где изменения больше не находятся под вашим полным контролем.

В ML Studio три основные рабочие области. Слева вы видите элементы с именами вроде Saved Datasets, Data Input and Output и Machine Learning. Это категории, и если вы их раскроете, то обнаружите специфические элементы, которые можно перетаскивать на центральную область дизайнера. Это весьма похоже на Toolbox в Visual Studio, откуда вы можете перетаскивать UI-элементы в рабочую область дизайнера. Однако модули ML Studio, как правило, представляют то, что можно рассматривать как методы, т. е. заранее написанный код, который выполняет ту или иную задачу ML.

Центральная область ML Studio называется экспериментом. Это аналогично редактору Visual Studio — место, где вы делаете большую часть работы. На рис. 1 эксперимент назван Voting Experiment. Название эксперимента — приблизительный аналог имени решения Visual Studio. Прямоугольные блоки являются модулями, которые были перемещены на поверхность дизайна. Например, модуль с меткой «Voting data» — это источник необработанных данных, а модуль с меткой «Logistic Regression Binary Classification Model» (метка частично обрезана) — используемый базовый алгоритм ML.

Извилистые линии определяют потоки ввода-вывода между модулями. Если честно, мое первое впечатление как разработчика было не совсем положительным: «Вот как замечательно. Извилистые линии. Мне не нравятся извилистые линии. Это не настоящее программирование». Но я довольно быстро адаптировался к визуальному стилю ML Studio создания систем и теперь стал их сторонником.

В правой части ML Studio показываются детали того, что выбрано в данный момент в основной рабочей области. На рис. 1, где выбран модуль Logistic Regression Binary Classification Model (его границы выделены полужирным), информация в правой части, такая как «Optimization tolerance» со значением 1.0E-07, относится конкретно к этому модулю. Информацию в правой части можно считать значениями параметров (или значениями аргументов в зависимости от вашей точки зрения) выбранного модуля или метода.

Вы можете запустить эксперимент, щелкнув значок Run в нижней строке. Это в какой-то мере эквивалентно нажатию клавиши F5 в Visual Studio для запуска программы под отладчиком. По мере того как завершается каждый модуль, ML Studio ставит зеленую галочку на модуле. Вы также увидите значок Save, но по умолчанию ML Studio автоматически сохраняет ваш эксперимент каждые несколько секунд: работа в облаке может быть опасна из-за таких проблем, как внезапный разрыв сетевого соединения.

В следующих разделах я пошагово разберу создание эксперимента на рис. 1, чтобы вы смогли воспроизвести его. Проделав это, вы получите твердый фундамент для дальнейшего (самостоятельного) исследования ML Studio или для изучения документации. В этой статье предполагается, что вы владеете навыками программирования хотя бы на начальном уровне (чтобы понять аналогии между ML Studio и Visual Studio и терминологию), но ничего не знаете о ML Studio или машинном обучении (machine learning).

Получение результатов?

Если вы новичок в ML Studio, то, по-видимому, хотите понять, где искать вывод эксперимента. Оказывается, типичный эксперимент в ML Studio часто имеет несколько мест вывода. Итоговый, так сказать, вывод показан на рис. 2. Я выкинул центральную секцию, чтобы просматривать изображение было немного удобнее.

*
Рис. 2. Результаты эксперимента в Azure ML Studio

Чтобы увидеть эти результаты, я щелкнул правой кнопкой мыши крайний справа модуль эксперимента Score Model и выбрал из контекстного меню команду Visualize. Появилось отдельное окно с результатами, показанными на рис. 2. А пока взгляните на нижнюю часть, которая напоминает:

unknown-party  y  n  y  n . . y  n  democrat    0.0013
unknown-party  y  y  y  y . . n  n  republican  0.7028
Вполне допустимо сказать, что все эксперименты ML Studio начинаются с некоторых данных и необходимости ответить на один или более вопросов.

Этот вывод указывает, что после создания модель прогнозирования получила два новых элемента данных. Первый (с unknown party) — это данные для гипотетического члена Палаты представителей, который проголосовал за законопроект, относящийся к детям, страдающим физическими недостатками (в столбцах есть заголовки, если вы присмотритесь к ним повнимательнее), против законопроекта по водопользованию и т. д. вплоть до голосования против законопроекта, относящегося к Южной Африке. Модель, созданная ML Studio, предсказывает, что гипотетический представитель является демократом. Второй элемент данных относится к гипотетическому представителю, который голосовал за первые восемь законопроектов и против вторых восьми законопроектов; модель предсказывает, что данное лицо является республиканцем.

Подготовка данных

Теперь, когда вы понимаете цель демонстрационного эксперимента, вам будет проще разобраться в том, как создается эксперимент. Вполне допустимо сказать, что все эксперименты ML Studio начинаются с некоторых данных и необходимости ответить на один или более вопросов. Здесь демонстрационные данные являются общеизвестным (по крайней мере, для сообщества ML) эталонным набором данных, часто называемым Congressional Voting Records Data Set (или UCI Voting Data Set, поскольку основное местонахождение этого файла — на сервере, поддерживаемом Университетом Калифорнии, город Ирвайн). Исходные данные (простой текстовый файл с именем house-votes-84.data) можно найти поиском по Интернету.

Первые четыре строки исходных данных выглядят так:

republican,n,y,n,y,y,y,n,n,n,y,?,y,y,y,n,y
republican,n,y,n,y,y,y,n,n,n,n,n,y,y,y,n,?
democrat,?,y,y,?,y,y,n,n,n,n,y,n,y,y,n,n
democrat,n,y,y,n,?,y,n,n,n,n,y,n,y,n,n,y
...

Всего в файле 435 разделенных запятыми строк данных — по одной для каждого из 435 членов Палаты представителей США в 1984 г. Первый столбец (поле) — партия (party), где значением может быть демократ или республиканец (в тот период других партий или независимых членов не было). Следующие 16 элементов в каждой строке представляют голос «за» (y), «против» (n) или пропущенный (missing vote) (?).

ML Studio может считывать данные напрямую из Web или из Azure Storage, но я предпочитаю создавать собственное хранилище данных. Для этого я скопировал текстовый файл в Notepad на своей локальной машине, а затем добавил заголовки столбцов на основе описания файла на веб-сайте UCI:

political-party,handicapped-infants, . . ,south-africa
republican,n,y,n,y,y,y,n,n,n,y,?,y,y,y,n,y
republican,n,y,n,y,y,y,n,n,n,n,n,y,y,y,n,?
democrat,?,y,y,?,y,y,n,n,n,n,y,n,y,y,n,n
...

Когда пишешь ML-код с нуля, работа с заголовками столбцов может оказаться весьма раздражающей, поэтому заголовки часто выкидываются из файлов данных. Но в случае ML Studio заголовки столбцов проще использовать, чем опускать; кроме того, они облегчают понимание данных. Я переименовал локальный файл в VotingRawWithHeader.txt и сохранил на своем компьютере. Если вы хотите использовать те же заголовки, что и я, то можете взять примененный мной файл данных из пакета исходного кода, сопутствующего этой статье.

После перехода на начальную страницу ML Studio я щелкнул категорию Datasets в левой секции. В основной рабочей области ML Studio отображает список встроенных наборов данных, например Iris Two Class Data и Telescope Data. Большинство из этих наборов данных, которые вы видите изначально, являются более-менее общеизвестными эталонными наборами (многие из репозитария UCI), и их можно использовать для исследования ML Studio. В нижнем левом углу ML Studio я нашел значок New и щелкнул его.

В этот момент я мог выбрать либо новый Dataset, либо новый Experiment, поэтому указал Dataset, а затем щелкнул значок From Local File. Это привело к появлению диалогового окна, показанного на рис. 3. С помощью кнопки Browse я выбрал локальный файл, назвал набор данных как «Voting data», выбрал тип «Generic CSV file with a header (.csv)» и ввел краткое описание этого набора данных.

*
Рис. 3. Создание нового набора данных

Я щелкнул галочку OK, и ML Studio загрузил и сохранил локальный файл в Azure Storage. Вернувшись в представление Datasets в ML Studio, я обновил страницу, и теперь электоральные данные (voting data) появились наряду с демонстрационными наборами данных. Заметьте, что в используемой мной предварительной версии ML Studio удалить какой-либо Dataset нельзя. Поэтому настоятельно советую при исследовании ML Studio создать один набор данных с обобщенным названием вроде Dummy Data. Потом, когда вам понадобится другой набор данных, используйте параметр This is a new version of an existing dataset, чтобы рабочее пространство ML Studio не оказалось перегруженным «осиротевшими» наборами данных, которые нельзя удалить.

Создание эксперимента

Чтобы создать эксперимент, я щелкнул значок New в левом нижнем углу ML Studio, а затем выбрал Experiment. Далее в секции на левой стороне я щелкнул категорию Saved Datasets и прокрутил список до элемента Voting Data (только что созданного мной) и перетащил его в секцию дизайнера. Вверху области дизайна я ввел заголовок: Voting Experiment. В этот момент вы могли бы щелкнуть правой кнопкой мыши нижний узел вывода модуля Voting Data и выбрать команду Visualize для проверки корректности своего набора данных.

Многие разработчики, в том числе я, впервые приступая к работе с ML, серьезно недооценивают, сколько усилий требуется для манипуляций над источником данных перед применением ML-алгоритмов. Типичные задачи включают переупорядочение столбцов данных, удаление ненужных столбцов, обработка недостающих значений, кодирование нечисловых данных и разделение данных на обучающие и проверочные наборы. С точки зрения разработчика, в случае эксперимента с электоральными данными эти задачи могут быть выражены в коде примерно так:

string[][] rawData = LoadData("VotingRawWithHeader.txt");
rawData = ProcessMissing(rawData, '?', 'n');
rawData = SwapColumns(rawData, 0, 16);
double[][] data = Encode(rawData);
double[][] trainData;
double[][] testData;
MakeTrainTest(data, 0.80, out trainData, out testData);

На рис. 4 показано увеличенное изображение первых четырех модулей ML Studio, выполняющих эти задачи. Во многих сценариях ML наиболее распространенный подход к обработке недостающих значений заключается в простом удалении всех строк с элементами данных, в которые недостает одного или более значений, и ML Studio предоставляет такую возможность. Однако в случае с электоральными данными я исходил из предположения, что отсутствующий голос был на самом деле голосом «против». Поэтому для модуля Missing Values Scrubber в правой секции я указал, что все недостающие значения («?») должны заменяться значениями «n».

*
Рис. 4. Обработка данных

Модуль Project Columns позволяет указать любые столбцы, которые вы хотите исключить. В данном случае я выбрал команду Select all columns. ML Studio анализирует ваши данные и делает обоснованные предположения, являются значения столбцов строковыми категориальными или числовыми данными. Модуль Metadata Editor позволяет переопределять предположения ML, а также указывать столбец Label, т. е. предсказываемую переменную. Я выбрал столбец political-party (именно здесь здорово помогают заголовки столбцов) и задал, что он будет столбцом Label. Остальные 16 столбцов я оставил как столбцы Feature (предиктор).

В случае с электоральными данными я исходил из предположения, что отсутствующий голос был на самом деле голосом «против».

Модуль Split именно это и делает, разделяя данные на обучающий набор, который используется для создания модели ML, и проверяющий набор, который применяется для оценки точности модели. Здесь я задал 0.8 в секции параметров модуля, поэтому обучающий набор будет включать 80% от 435 элементов (348 элементов), а проверочный набор — остальные 20% (87 элементов). Модуль Split также имеет булев параметр с именем Stratified split. Работая с ML Studio, вы определенно будете встречать параметры, смысл которых непонятен. Значок с изображением знака вопроса в нижнем правом углу открывает доступ к ML Studio Help.

Обучение модели

Модель ML можно рассматривать как набор информации (как правило, числовых значений, называемых весовыми), которые используются для генерации вывода и прогнозов. Обучение модели — это процесс поиска набора таких весовых значений, чтобы, когда они представляются вместе с входными данным из обучающего набора (в данном случае 16 голосов «за» и «против»), вычисленные выходные значения (демократ или республиканец) близко соответствовали известным выходным значениям в обучающих данных. После определения этих весовых значений конечная полученная модель может быть представлена с помощью проверочных данных. Точность модели на проверочных данных (процент правильных прогнозов) дает вам примерную оценку того, насколько хорошо модель будет работать с новыми данными, где настоящий вывод не известен.

В случае с демонстрационными электоральными данными подход с написанием кода к обучению мог бы выглядеть примерно так:

int numFeatures = 16;
LogisticModel lm = new LogisticModel(numFeatures);
int maxEpochs = 10000;
lm.Train(trainData, maxEpochs);

На рис. 5 показан увеличенное изображение эквивалентных модулей ML Studio, относящихся к обучению. В этой демонстрации модуль Train Model принимает модуль Logistic Regression Binary Classification Model как ввод. В отличие от других соединений это не является настоящим потоком данных; на самом деле оно задает, какую именно модель ML следует задействовать. Альтернативы Logistic Regression Binary Classification включают модули Averaged Perceptron Binary, Boosted Decision Tree Binary и Neural Network Binary Classifiers.

*
Рис. 5. Обучение модели

Как же узнать, какая модель вам нужна? Поскольку вывод для прогнозирования имеет два возможных значения (democrat или republican), вам требуется двоичная модель. Но к ML существуют десятки подходов, и, вероятно, самая трудная часть в использовании ML Studio заключается в исследовании всех за и против различных классификаторов ML. Аналогия для разработчика с Visual Studio — в Microsoft .NET Framework есть десятки структур данных, таких как обобщенная Dictionary, HashSet и обобщенная Queue, и ваша обязанность знать, что именно делает каждая структура данных. Точно так же вы должны изучить классификаторы ML.

У модуля Logistic Regression имеются некоторые параметры, которые вы вряд ли сразу поймете; к ним относятся, в том числе, Optimization tolerance, L1 regularization weight и Memory size for L-BFGS. И вновь разбираться с этими параметрами вы будете самостоятельно. К счастью, ML Studio предлагает качественно подобранные значения по умолчанию для большинства параметров модулей. Я согласился со всеми значениями по умолчанию для параметров, кроме одного: для Random number seed я задал нулевое значение.

В модуле Train Model вы должны сообщить ML Studio, какой столбец обучающих данных является столбцом Label, т. е. какой столбец содержит прогнозируемую переменную. Выбрав модуль Train Model, я щелкнул кнопку селектора столбцов Launch в секции параметров модуля и указал в раскрывающемся списке вариант pick-by-name, а затем ввел политическую партию. Я мог бы использовать индекс столбца (1), поскольку политическая партия — это первый столбец (индексы в ML Studio отсчитываются от 1, а не от 0, как привыкли все разработчики). Заметьте, что задание столбца Label для модуля Train Model обязательно, даже если вы делаете это в Metadata Editor.

Оценка модели

После обучения демонстрационной модели следующими этапами являются передача модели обучающих и проверочных данных, вычисление результатов и расчет точности вычисленных результатов (против известных результатов). В коде это могло бы выглядеть следующим образом:

lm.ComputeOutputs(trainData); // оценка
double trainAccuracy = lm.Accuracy(trainData); // совпадения
lm.ComputeOutputs(testData); // оценка
double testAccuracy = lm.Accuracy(testData); // совпадения

На рис. 6 показано увеличенное изображение релевантных модулей подсчета совпадений (scoring) и оценки (evaluating). Два модуля Score Model принимают два входных потока. Первый ввод — это обученная модель (эта информация нужна для вычисления результатов), а второй — либо обучающий, либо проверочный набор (необходимые входные данные). Результаты этих двух модулей передаются модулю Evaluate Model, который рассчитывает точность.

*
Рис. 6. Подсчет совпадений и оценка модели

На рис. 7 приведены результаты в модуле Evaluate Model. Обратите внимание на верхнюю правую часть, где выбран второй из двух элементов Dataset (он выделен); это означает, что результаты получены для проверочных данных. Самая важная часть результата — значение Accuracy, равное 0.989. Вспомните, что проверочный набор составляет 20% от 435 элементов исходных данных, или 87 элементов. Модель Logistic Regression правильно предсказала принадлежность к политической партии для 86 из 87 тестовых элементов. В результатах модуля Evaluate Model много и другой информации. Например, график называется Receiver Operating Characteristic (ROC). На нем по оси Y откладывается процент истинно положительных результатов (true positives, TPR) (правильных предсказаний), а по оси X — процент ложно положительных результатов (false positives, FPR) (неправильных предсказаний).

*
Рис. 7. Точность модели на проверочных данных

Прогнозирование

Как только модель в ML Studio создана и оценена, ее можно использовать для прогнозирования на основе данных с неизвестными результатами (выходными значениями). Я хотел предсказать принадлежность к политической партии гипотетического члена Палаты представителей, который голосовал «yes», «no», «yes», «no», и т. д. по 16 законодательным проектам, и второго представителя, голосовавшего за первые восемь законопроектов и против остальных восьми.

Не просто инструмент

Приложение Azure ML Studio совместно со своим серверным механизмом, сервисом Microsoft Azure Machine Learning (ML), является гораздо большим, чем простой клиентский инструмент, описанный в этой короткой статье. С точки зрения разработчика, ML Studio радикально упрощает создание систем прогнозирования. Но она предлагает дополнительные возможности, не столь очевидные на первый взгляд.

Одна из важных областей, не охваченных в этой статье, — способность Azure ML создавать и публиковать веб-сервисы простым перетаскиванием и несколькими щелчками. Azure ML автоматически обрабатывает развертывание, подготовку пропускной способности, балансировку нагрузки, автоматическое масштабирование и мониторинг работоспособности. Один из клиентов, использовавших предварительную версию, оценил, что с помощью Azure ML его компания смогла создать бизнес-решение (систему обнаружения попыток мошенничества), потратив на него лишь малую долю того, во что обходится использование коммерческого аналитического ПО.

Azure ML поддерживает R — популярный язык программирования в области научных исследований данных. Сотни существующих R-модулей с открытым исходным кодом можно напрямую копировать в систему Azure ML.

ML Studio обеспечивает также коллективную работу. Эксперимент можно легко поделить между несколькими людьми. Я сам воспользовался этой функциональностью, и это было гораздо эффективнее, чем обычное обсуждение по электронной почте.

Azure ML дает преимущества не только разработчикам и исследователям в области данных. «Развертывание продвинутых средств аналитики — дело трудное, — сказал Джозеф Сайрош (Joseph Sirosh), вице-президент Microsoft по связям с корпорациями в области управления информацией и машинного обучения. — На предприятиях устали платить высокую цену, нанимать дорогостоящие таланты и месяцами ждать результатов. Возможность быстрой разработки аналитических моделей и их развертывание без этих узких мест меняет правила игры в целой отрасли. Azure ML позволяет предприятиям раскрыть ценность своих данных и строить системы, которые уменьшают затраты, способствуют повышению доходов и лучше служат своим конечным клиентам».

Один из подходов мог бы заключаться в создании и загрузке нового ML Studio Dataset и последующего подсчета совпадений так же, как в случае обучающего и проверочного наборов данных. Но для ограниченного объема данных подходит более интерактивный подход: использование модуля Enter Data (рис. 8), который позволяет вручную вводить данные.

*
Рис. 8. Ввод новых данных для прогнозирования

Формат данных в модуле должен точно соответствовать формату данных, применяемых для обучения модели, поэтому требуются заголовки столбцов. Вывод от модуля Enter Data объединяется с выводом от модуля Train Model. После выполнения эксперимента можно увидеть результаты, щелкнув кнопку Visualize модуля Score Model, как было показано ранее на рис. 2.

Одна из самых интересных функций ML Studio — возможность написания собственных модулей на C#.

Если вы делали прогнозы, используя процедурный язык программирования, то код мог бы быть примерно таким:

string[] unknown = new string[] { "party", "y", "n", "y", . . "n" };
double result = lm.ComputeOutput(unknown);
if (result < 0.5)
  Console.WriteLine("Predicted party is democrat");
else
  Console.WriteLine("Predicted party is republican");

И вновь некоторая информация ML Studio скорее всего покажется слегка загадочной. Вспомните, что прогнозы включают два концевых числовых значения:

unknown-party  y  n  y . . y  n  democrat    0.0013
unknown-party  y  y  y . . n  n  republican  0.7028

Оказывается, в случае Logistic Regression Binary Classification выходное значение ниже 0.5 указывает первый класс (демократ в этом примере), а выходное значение выше 0.5 — второй (республиканец). Учтите, что в ML Studio подобно Visual Studio много средств и генерируется колоссальное количество информации. Со временем вы поймете, что означают различные части этой информации. Просто используйте систему и разбирайтесь с каждой частью по очереди, а не пытайтесь освоить все сразу, зарывшись в документацию.

Никакого кода?!

В этой статье я поверхностно обрисовал ML Studio, но дал достаточно информации, чтобы вы смогли воспроизвести эксперимент с электоральными данными и ознакомиться с этой системой. Вы наверняка заметили, что в этой статье не было сказано ни слова о кодировании. Никакого кода? Вот еще! Одна из самых интересных функций ML Studio — возможность написания собственных модулей на C#, и я расскажу об этом в будущих статьях. У меня такое предчувствие, что ML Studio соберет вокруг себя экосистему, в которой разработчики пишут изощренные, специализированные модули и делают их доступными как на коммерческой основе, так и по различным каналам, таким как проекты с открытым исходным кодом и блоги.

Автор: Джеймс Маккафри  •  Иcточник: msdn.microsoft.com  •  Опубликована: 22.09.2015
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:   Machine Learning Studio.


Оценить статью:
Вверх
Комментарии посетителей RSS

Чтобы оставить комментарий, зарегистрируйтесь или войдите с учетной записью социальной сети.