Лучшие датасеты для машинного обучения и анализа данных

Время улучшений!

Будем использовать Bagging. Очень кратко этот подход можно описать так: берутся несколько моделей, обучаются независимо, а затем все модели голосуют за результат. И тут могут быть различные варианты реализации: либо все модели имеют одинаковую «цену» голоса, либо у их голосов есть какие-то веса. Предсказанием метамодели считается усредненный результат.

В sklearn есть модуль , в котором представлено несколько алгоритмов для реализации ансамблей. Наш случай — классификация, используем :

Ансамбли оперируют базовыми моделями. В случае sklearn, базовая модель — сущность, реализующая методы . В зависимости от вида ансамбля, будут нужны различные реализации функций этой сущности. Для нашего случая необходимо описать метод (для обучения модели), функцию , выдающую вероятность каждого класса (для того, чтобы метамодель смогла по вероятностям оценивать уверенность базовых классификаторов и присваивать их голосам большие или меньшие веса), и функцию (которая выдает номер класса), чтобы было удобно оценивать качество модели.

Ради понятности буду описывать каждую часть кода отдельно, потом их просто нужно «склеить» в один класс.

Конструктор класса базовой модели. Из тех граблей, на которые я успел наткнуться, стоит отметить именование параметров и их типы.

Во-первых, если вы не хотите переписывать функции клонирования объекта базового классификатора (а придется переписывать аж 2 функции — и ), то нужно давать аргументам в конструкторе те же имена, что и присваиваемым переменным класса. То есть, если вы подаете в конструктор параметр , то в методе вы должны объявить переменную .

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

Самое интересное: метод . По сути, он работает как и обучение нашей первой нейросети — пропускаем данные, считаем Loss, делаем обратное распространение ошибки. Вот только вопрос: как нам понять, какое количество эпох надо обучать модель? Первым решением может являться задание определенного количество эпох до обучения. Например, 200 (как в первой модели). Но это может привести к переобучению, а может и к недообучению. Второе решение — смотреть, как изменяется accuracy нашей модели. У первой нейросети можно заметить, что в конце accuracy держится примерно на одном уровне несколько эпох подряд. Тогда мы можем остановить обучение, если модель уже на протяжении нескольких () эпох не улучшает свое качество (то есть accuracy изменяется не более, чем на ).

Теперь будем делать функцию для предсказания вероятностей классов. По сути — так же пропускаем данные, только не считаем Loss, а записываем все в какой-нибудь массив:

Простая и относительно красивая функция:

Итак, протестируем наш новоиспеченный классификатор:

Все готово для создания ансамбля.

Теперь можно с помощью уже реализованной функции оценить accuracy нашего ансамбля:

Google Trends

Curated by: GoogleExample data set: «Cupcake» search results
This is one of the widest and most interesting public data sets to analyze. Google’s vast search engine tracks search term data to show us what people are searching for and when. You can explore statistics on search volume for almost any search term since 2004. Enter in any search term, or a handful of search terms, and click the download button to analyze the data outside of the Trends website.

There are a variety of filters to narrow down trends according to location (worldwide or by country), various time ranges, categories, or even specific search types (web vs image vs YouTube search results). You can easily see what topics are popular at the moment and what is currently trending on the Trends homepage. Google also highlights several interesting examples of trends with data visuals on that homepage.

If you’re interested in more Google data, check out Google Finance, Google Public Data, and Google Scholar.

Естественные языки

Корпус данных веб-страниц объемом более 540 терабайт — состоит из более 5 миллиардов веб-страниц. Этот набор данных свободно доступен на Amazon S3.

Yelp — сайт для поиска на местном рынке услуг, например, ресторанов или парикмахерских, с возможностью добавлять и просматривать рейтинги и обзоры этих услуг. За долгие годы работы накопил огромное количество данных от пользователей сервиса. Набор данных включает в себя 4 700 000 отзывов на 156 000 компаний от более 1 000 000 пользователей.

Набор данных представляет собой коллекцию текста из более чем 100 млн словоупотреблений, извлеченных из проверенных Хороших и Избранных статей Википедии.

Этот набор новостных статей CNN содержит 120 000 пар вопросы + контекст/ответы. Вопросы написаны людьми на естественном языке. На вопросы могут отсутствовать ответы, а ответы могут быть многоязыковыми. Набор данных Maluuba разработан, чтобы помочь создать «умных» чат-ботов, которые могут поддерживать принятие решений в сложных условиях.

Базовые данные, состоящие из пар (вопросы + контекст/ответы), извлеченных из детских книг, доступных в рамках Проекта Гутенберг, направленного на создание и распространение электронной универсальной библиотеки. Проект, основанный в 1971 году, предусматривает оцифровку и сохранение в текстовом формате различных произведений мировой литературы — в основном это тексты, находящиеся в свободном доступе на всех популярных мировых языках. Для бесплатной загрузки доступно более 53 000 документов.

Датасет анализа тональности «комментариев» в Twitter. Содержит 1 578 627 твитов с указанием положительных и отрицательных настроений.

Речь

Всеобъемлющий словарь звуковых событий. 632 класса аудиособытий и коллекция из 2 084 320 голосовых 10-секундных отрезков из видео на YouTube (более 5 тысяч часов аудиозаписей).

Датасет англоязычной речи, содержащий стенограммы 40 телефонных переговоров на английском языке. Данные 2000 HUB5 English сосредоточены на разговорной речи по телефону с конкретной задачей транскрипции речи в текст.

Аудиозаписи 1495 выступлений на TED с полной расшифровкой.

Операция join

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

Это лучше продемонстрировать на примере с КТ-снимками. Загружаем координаты и размеры раковых новообразований и формируем из них 3-мерные маски.

Загружаем КТ-снимки и применяем к ним маски, чтобы выделить только раковые области.

В вы указываете датасет. Благодаря чему в следующий -метод (в данном примере в ) в качестве первого аргумента будут передаваться батчи из этого датасета. И не какие попало батчи, а ровно те, которые и нужны. Например, если текущий батч из содержит снимки 117, 234, 186 и 14, то и присоединяемый батч с масками также будет относиться к снимкам 117, 234, 186 и 14.

Естественно, метод должен быть написан с учетом данного аргумента, ведь его можно передать и явно, без предварительного ‘а. Причем в -методе можно уже не задумываться об индексах и идентификаторах элементов батча — вы просто к массиву снимков применяете массив масок.

И снова отмечу, что никакие загрузки и вычисления, ни с изображениями, ни с масками не будут запущены, пока вы не вызовете

Собираем все вместе

Итак, посмотрим как будет выглядет полный workflow data science проекта.

  1. Создаем индекс и датасет
  2. Выполняем препроцессинг и сохраняем обработанные снимки

  3. Описываем подготовку и аугментацию данных для модели

  4. Формируем тренировочные батчи и обучаем модель

  5. Проверяем качество модели

Вот такая вот удобная библиотека, которая помогает значительно быстрее разрабатывать понятный код высокого качества, повторно использовать ранее созданные модели со сложным препроцессингом данных и даже разрабатывать production-ready системы.

А теперь вопрос: что еще стоит добавить в библиотеку? чего вам остро не хватает при работе с данными и моделями?

Компьютерное зрение

Открытость данных для машинного обучения — это как бесплатное электричество для рынка электрокаров. Поэтому большой вклад в процесс получения новых датасетов вносят исследовательские группы, которые не гонятся за прямой финансовой выгодой. Так, международная группа исследователей, в которую вошли ученые из Стэнфордского университета, а также представители компании Yahoo и Snapchat, разработала новую базу данных Visual Genom и алгоритм оценки изображений, которые позволят системам искусственного интеллекта понимать, что происходит на снимках. Все изображения в базе Visual Genome маркируются таким образом, чтобы содержать информацию обо всех объектах на снимке, их особенностях и связях.

Ранее исследователи из Стэнфордского университета представили датасет ImageNet, который содержит более миллиона изображений, маркированных по содержанию представленного на снимке события. У многих компаний, создающих API для работы с изображениями, в REST-интерфейсах используются лейблы, подозрительно похожие на 1000-категорийную иерархию WordNet из ImageNet.

MIAS (Mammographic Image Analysis Society)

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

Landsat-8 — это спутник дистанционного зондирования Земли, выведенный на орбиту в 2013 году. Спутник собирает и сохраняет многоспектральные изображения среднего разрешения (30 метров на точку). Данные Landsat-8 доступны с 2015 года вместе с некоторыми выборочными снимками 2013–14 годов. Все новые снимки Landsat-8 появляются каждый день буквально через несколько часов после их создания.

База данных рукописного написания цифр, имеющая подготовленный набор обучающих значений, в размере 60 000 изображений для обучения и 10 000 изображений для тестирования. Цифры, взятые из набора образцов Бюро переписи населения США (с добавлением тестовых образцов, написанных студентами американских университетов), нормализованы по размеру и имеют фиксированный размер изображения. Эта база является стандартом, предложенным Национальным институтом стандартов и технологий США с целью калибровки и сопоставления методов распознавания изображений.

Следующая ступень эволюции для тех, кто прошел рукописные цифры. Этот датасет включает в себя 74 000 изображений различных символов (алфавит, цифры и т.д.).

Данные биометрического распознавания (фронтальное изображение лица), полученные с помощью движка с открытым исходным кодом.

Номера домов из Google Street View. 73 257 номеров для обучения, 26 032 номера для тестирования и 531 131 несколько менее сложный образец, чтобы использовать в качестве дополнительных учебных данных.

Global Health Observatory data

Curated by: World Health Organization (WHO)Example data set: Universal access to reproductive health
As part of their core goal for better health information worldwide, the World Health Organization makes their data on global health publicly available through the Global Health Observatory (GHO). The GHO acts as a portal with which to access and analyze health situations and important themes.

The various data sets are organized according to themes, such as mortality, health systems, communicable and non-communicable diseases, medicines and vaccines, health risks, and so on. The WHO’s health statistics are to go-to source for global health information and is also used in the work of the US Centers for Disease Control and Prevention.

Датасеты для машинного обучения

Компьютерное зрение

  • . Один из самых больших общедоступных наборов воздушных снимков земли. Он содержит изображения различных сцен со всего мира, аннотированных с помощью ограничительных рамок.
  • . Большой датасет аннотированных изображений.
  • . Датасет изображений для новых алгоритмов, организованный в соответствии с иерархией WordNet, в которой сотни и тысячи изображений представляют каждый узел иерархии.
  • . Датасет изображений, разбитых по сценам и категориям с частичной разметкой данных.
  • . Крупномасштабный датасет для обнаружения и сегментации объектов.
  • . 100 разных объектов, изображённых под каждым углом в круговом обороте.
  • . Датасет с ~100 тыс. подробно аннотированных изображений.
  • . Коллекция из 9 миллионов URL-адресов к изображениям, «которые были помечены метками, охватывающими более 6000 категорий» под лицензией Creative Commons.
  • . Набор из 13 000 размеченных изображений лиц людей для использования приложений, которые предполагают использование технологии распознавания лиц.
  • . Содержит 20 580 изображений из 120 пород собак.
  • . Датасет для распознавания интерьера зданий. Содержит 15 620 изображений и 67 категорий.

Анализ тональности текста

  • . Немного устаревший датасет, который содержит отзывы на товары с Amazon.
  • . Староватый, относительной небольшой (25 000 отзывов к фильмам) датасет для бинарного анализа тональности.
  • . Стэнфордский датасет для анализа тональности.
  • . Популярный датасет с 160 000 твитов с удалёнными смайликами.
  • . Набор данных из Twitter об авиакомпаниях США, датируемый февралём 2015 года, разделённый на положительные, негативные и нейтральные твиты.

Обработка естественного языка

  • . Датасет с вопросами-ответами, позволяющий создавать системы для ответов на вопросы более понятным способом.
  • . Данные электронной почты от высшего руководства Enron.
  • . Содержит около 35 млн отзывов с Amazon за 18 лет. Данные включают информацию о продукте и пользователе, оценки и сам текст отзыва.
  • . Коллекция слов из Google Книги.
  • . Коллекция из 681 288 постов с Blogger. Каждый блог содержит как минимум 200 вхождений часто используемых английских слов.
  • . Датасет, состоящий из веб-страниц, которые удовлетворяют следующим двум условиям: каждая из них содержит хотя бы одну ссылку на Википедию и текст её якоря совпадает или похож на заголовок целевой страницы.
  • . Аннотированный список электронных книг проекта «Гутенберг».
  • . Датасет с 1.3 миллионами пар текстовых файлов, записанных с дебатов 36-го Канадского Парламента.
  • . Архив с более чем 200 000 вопросов с телевикторины Jeopardy.
  • . Архив из более чем 480 000 рецензий с Rotten Tomatoes.
  • . Датасет, состоящий из 5574 спам-смс на английском.
  • . Датасет от Yelp, содержащий более 5 млн отзывов.
  • . Большой датасет спам-писем.

Автопилоты

  • . На данный момент это самый большой датасет для автопилотов. Он содержит более 100 000 видео с более чем 1100 часами записей вождения в разное время дня и в различных погодных условиях.
  • . Большой датасет для распознавания 26 семантически разных объектов вроде машин, велосипедов, пешеходов, зданий, уличных фонарей и т. д.
  • . Более семи часов езды по шоссе. Датасет включает информацию о скорости машины, ускорении, угле поворота руля и GPS-координатах.
  • . Более ста повторений одного маршрута по Оксфорду, заснятого в течение года. В датасет попали разные комбинации погодных условий, трафика и пешеходов, а также более длительные изменения вроде дорожных работ.
  • . Большой датасет, содержащий записи ста уличных сцен в 50 городах.
  • . Более 10 000 аннотаций тысяч разных светофоров в Бельгии.
  • . Датасет с дорожными знаками, светофорами, распознанными средствами передвижения и траекториями движения.
  • . Датасет с 24 000 аннотированных светофоров.
  • . Ещё один датасет для распознавания светофоров.
  • . Датасет для распознавания светофоров, пешеходов и дорожной разметки.

Медицинские данные

MIMIC-III. Датасет с обезличенными данными о состоянии здоровья ~40 000 пациентов, находящихся на интенсивной терапии. Он включает демографические данные, показатели жизнедеятельности, лабораторные анализы, лекарства и многое другое.

Оригинал:

Перевод статьи

P.S. Поскромнее, но зато отечественные

Что такое датасет для Data Mining и из чего он состоит

Dataset для машинного обучения – это обработанная и структурированная информация в табличном виде. Строки такой таблицы называются объектами, а столбцы – признаками. Различают 2 вида признаков :

  • независимые переменные – предикторы;
  • зависимые переменные – целевые признаки, которые вычисляются на основе одного или нескольких предикторов.

Признаковое описание характерно для задач классификации, когда имеется выборка – конечное множество объектов, для которых известно, к каким классам они относятся. Классовая принадлежность остальных объектов неизвестна. В процессе машинного обучения строится модель, способная классифицировать произвольный объект из исходного множества . Практический смысл задач классификации состоит в предсказании возможных исходов на основе совокупности входных переменных, например, диагностика заболеваний, предварительная оценка эффективности месторождений полезных ископаемых, кредитный скоринг, распознавание речи, прогнозирование оттока клиентов (Churn Rate) и т.д.

В зависимости от варианта задачи классификации, целевой признак может выглядеть по-разному :

  • один столбец с двоичными значениями (1/0, TRUE/FALSE и пр.): двухклассовая классификация (binary classification), когда каждый объект принадлежит только одному классу;
  • несколько столбцов с двоичными значениями: задача классификации с пересекающимися классами (multi-label classification), когда один объект может принадлежать нескольким классам;
  • один столбец с действительными значениями: регрессионный анализ, когда прогнозируется одна величина;
  • несколько столбцов с действительными значениями: задача множественной регрессии, когда прогнозируется несколько величин.

Задачи классификации описываются признаками

SqlDataAdapter и DataSet

Последнее обновление: 31.10.2015

Ранее для получения данных мы использовали объект SqlDataReader, с помощью которого построчно можно перебрать ответ от сервера базы данных.
Но есть и другой способ, который демонстрирует использование объектов SqlDataAdapter и DataSet. DataSet представляет хранилище данных, с которыми можно работать независимо от наличия подключения, а SqlDataAdapter заполняет
DataSet данными из БД.

Для получения данных через объект SqlDataAdapter необходимо организовать подключение к БД и выполнить команду SELECT. Есть несколько
способов создания SqlDataAdapter:

SqlDataAdapter adapter = new SqlDataAdapter();
SqlDataAdapter adapter = new SqlDataAdapter(command);
SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
  • Можно использовать конструктор без параметров, а команду SELECT и подключение установить позже

  • Можно передать в конструктор объект SqlCommand

  • Можно в конструкторе установить sql-выражение SELECT и объект SqlConnection

  • Можно в конструкторе установить sql-выражение SELECT и строку подключения

Рассмотрим, как получить данные в DataSet через SqlDataAdapter. Для работы с DataSet особенно удобно использовать элементы
управления, которые могут заполняться из внешнего источника данных, например, DataGridView в Windows Forms. Поэтому создадим новый
проект по типу Windows Forms Application.

Добавим на единственную форму в проекте элемент DataGridView и определим следующий код формы:

using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace AdoNetWinFormsApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=usersdb;Integrated Security=True";
            string sql = "SELECT * FROM Users";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
				// Создаем объект DataAdapter
                SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
                // Создаем объект Dataset
                DataSet ds = new DataSet();
                // Заполняем Dataset
                adapter.Fill(ds);
                // Отображаем данные
                dataGridView1.DataSource = ds.Tables;
            }
        }
    }
}

В конструкторе формы в DataGridView загружаются данные. Для загрузки данных создается объект SqlDataAdapter, который принимает объект подключения и sql-выражение SELECT.
Затем создается объект DataSet и с помощью метода в него загружаются данные. Дальше происходит установка источника
данных для DataGridView:

dataGridView1.DataSource = ds.Tables;

В качестве источника устанавливается одна из таблиц в DataSet. Каждая таблица представляет объект DataTable, и в DataSet может быть определено
несколько таких таблиц. Но в данном случае при выборке в DataSet есть только одна таблица, которую мы можем получить из коллекции Tables по индексу.

НазадВперед

Каким бывает dataset: типы выборок

Первичный набор исходных данных принято называть генеральной совокупностью. Процесс формирования выборок из генеральной совокупности называется порождение данных . Выборка – это конечное подмножество элементов генеральной совокупности, изучив которое можно понять поведение исходного множества. Например, генеральная совокупность состоит из 150 тысяч посетителей сайта, а в выборку попали 250 из них.

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

  • для непосредственного обучения модели нужна обучающая выборка (training sample), по которой производится настройка (оптимизация параметров) алгоритма;
  • для оценки качества модели используется тестовая (контрольная) выборка (test sample), которая, в идеальном случае, не должна зависеть от обучающей;
  • для выбора наилучшей модели машинного обучения понадобится проверочная (валидационная) выборка (validation sample), которая также не должна пересекаться с обучающей.

Выборки бывают разные: обучающие, контрольные и валидационные

Где искать датасеты

  • . Dataset Search позволяет по ключевому слову искать датасеты по всей Сети.
  • . Площадка для соревнований по машинному обучению с множеством интересных датасетов. В можно найти разные нишевые экземпляры — от до  и .
  • . Один из старейших источников датасетов в Сети и первое место, куда стоит заглянуть в поиске интересных датасетов. Хотя они добавляются пользователями и потому имеют различную степень «чистоты», большинство из них очищены. Данные можно скачивать сразу, без регистрации.
  • . Датасеты для компьютерного зрения, разбитые по категориям. Доступен поиск.
  • . Коллекция датасетов, предоставленная университетом Карнеги Меллон.

Тестирование нейронной сети

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

Задача его — рисовать точки, отражая эпохи.
Что ж, запустим тренировку нашей модели и посмотрим на результат.

Проверим эффективность модели на тестовой выборке.

Результат: 506/506 — 0s — loss: 36201.9241 — mae: 66.5216 — mse: 36201.9219

MSE в 45430.1133 долларов оставляет нас со среднеквадратическим отклонением в 190.27 долларов. Многовато.

Теперь проведем обучение и тестирование сети на данных, содержащих выходы транзакций.

Результат: 506/506 — 0s — loss: 24382.0926 — mae: 48.5508 — mse: 24382.0918

MSE в 24382.0918 долларов значит, что среднеквадратическое отклонение сократилось до 156.15 долларов, что, конечно, не сказка, но улучшение налицо.

Момент истины. Произведем прогнозирование и нарисуем как соотносятся предсказанные значения цен закрытия с реальными ценами.

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

Итого

  • Атрибуты – это то, что написано в HTML.
  • Свойства – это то, что находится в DOM-объектах.

Небольшое сравнение:

Свойства Атрибуты
Тип Любое значение, стандартные свойства имеют типы, описанные в спецификации Строка
Имя Имя регистрозависимо Имя регистронезависимо

Методы для работы с атрибутами:

  • – проверить на наличие.
  • – получить значение.
  • – установить значение.
  • – удалить атрибут.
  • – это коллекция всех атрибутов.

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

  • Нужен нестандартный атрибут. Но если он начинается с , тогда нужно использовать .
  • Мы хотим получить именно то значение, которое написано в HTML. Значение DOM-свойства может быть другим, например, свойство – всегда полный URL, а нам может понадобиться получить «оригинальное» значение.

Выводы

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

Автокодировщики — очень мощный инструмент для детектирования аномалий. Что еще можно попробовать с ними? Есть вариант использовать VAE, у которого латентное пространство (те самые 4 нейрона) является нормальным распределением. Тогда можно классифицировать примеры по этому пространству. Также существуют CVAE, которые используют какой-то дополнительный признак для генерации из скрытого признакового пространства. Например, это может быть метка класса, размер цифры, максимальное значение в распределении и т.д.

Очень близко к автоенкодерам находятся GAN’ы, где есть целая модель (дискриминатор), позволяющая обнаружить семплы не из обучающей выборки. Тогда достаточно хорошо натренировать пару генератора и дискриминатора (что в действительности непросто).

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

Немного обо мне

Меня зовут Евгений, Data science’ом я занимаюсь уже полтора года. Сейчас в большей степени погружаюсь в Computer vision, но также интересуюсь нейротехнологиями. (Соединить искусственные и натуральные нейронные сети — моя мечта!) Этот пост создан благодаря нашей команде — FARADAY Lab. Мы — начинающие российские стартаперы и готовы делиться с Вами тем, что узнаем сами.

Удачи c:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector