суббота, 18 января 2014 г.

Итак, у нас есть много плохих данных…

Каких данных? Ну вы в курсе. Они все в каком-то странном формате, у половины не заполнена часть полей, а в конце файла с этими данными вообще меняется схема. И похоже, верные ADO и SQLServer нам тут больше не помошники, потому что… Потому что schemaless! Потому что создание пары сотен полей для каждой таблицы – это не то, чем мы бы хотели заниматься. К тому же, нам же не нужны собственно эти данные. Нам нужны выводы, которые мы сделаем, основываясь на них. Мы хотим графики, тренды, представление на логарифмической шкале, движимое среднее и все остальные штуки, которые позволят понять, что, собственно, вокруг происходит.


Итак, мы хотим попробовать анализировать какие-нибудь данные, и желательно побольше. Или желательно реальные? Или хорошо понятные? Или те, для которых возможна хорошая визуализация? Или все вместе?
Вот капля в море того, на что можно обратить внимание:
http://www.briandunning.com/sample-data/ - много данных - за денежку. Бесплатно - жалкие 500 записей. Данные однообразные, чистые, интереса представляют мало.
http://ftp.freedb.org/pub/freedb/- FreeDb - база музыкальных дисков, очень грязная. Есть парсер для RavenDB от Ayende: https://github.com/ayende/XmcdParser/. У меня вся база распарсилась в 3,5 миллиона достаточно сложных (с большой вложенностью) документов, индексируется крайне неохотно. Врет как сивый мерин, тем и интересна. Вот, например, получившиеся у меня результаты агрегации выпущенных музыкальных дисков по годам (первая колонка – год, вторая – количество дисков, выпущенных в этом году):

Оказывается, в 208 г. н.э. музыкальная индустрия уже была достаточно развита. И еще тут один диск из будущего. Ну а что?
Зато вот такая выборка, кажется, имеет некоторый смысл и показывает какую-никакую динамику:

 
Очень хороший выбор для экспериментов, за исключением странного исходного формата. Но мы же не боимся трудностей?
https://data.cityofchicago.org/Public-Safety/Crimes-2001-to-present/ijzp-q8t2 - Chicago city portal, данные о преступлениях с 2001 года до наших дней. Кнопка Export позволяет выбрать из нескольких форматов для загрузки. CSV весит около 1,3 Гб. 
Сейчас мучаю именно этот сет из-за большого простора для возможно анализа, относительной легкости парсинга и большого количества разнородной информации в каждом документе. 
http://www.microsoft.com/en-us/download/details.aspx?id=23654 - легендарные Northwind и Pubs, которые можно использовать в качестве источника данных для Raven. Данные очень чистые, предназначены для упражнений по SQL, поэтому большого интереса для анализа не представляют. Да и нереальные, поэтому что там можно анализировать?
http://www.tableausoftware.com/public/community/sample-data-sets#medals - несколько небольших датасетов. Датасеты чистые, интерес представляет разве что Medals Won by Olympic Athletes:
1) Оно легко превращается в документы (хм, да собственно почти что угодно легко превращается в документы),
2) Оттуда можно вытащить немало разнородной информации не только об атлетах, но и о странах, которые они представляли, и вообще об Олимпийских играх начиная с 2000 года (Сидней). Меняется ли общее количество медалей, разыгрываемых на Олимпийских играх? Пойду проверю.
В качестве упражнений можно использовать идеи для анализа, приведенные на той же странице.
Плохо тут то, что данные в xlsx, с которым надо еще уметь работать. Но все возможно, если очень хочется. 
Внизу той же страницы есть несколько ссылок на другие открытые источники данных, но, к сожалению, без конкретных инструкций и даже часто без прямых ссылок, только сайты. 
http://archive.ics.uci.edu/ml/index.html - репозитории для машинного обучения. Очень много всего. Данные, в основном, очень специфичны, и поэтому что-то с ними делать просто неинтересно. Ну какую информацию можно извлечь из датасета “SkillCraft1 Master Table Dataset Data Set”? Для наших целей не подходит.
http://www.theguardian.com/news/datablog/interactive/2013/jan/14/all-our-datasets-index - Газета Guardian делится своими датасетами на любой вкус. Есть про экономику, политику, спорт, общество. Есть просто прекрасные, вроде "Doctor Who villains & monsters since 1963". Или вот шикарный, про День сурка. Можно загрузить в CSV (отлично!). 
В заключение хочу поделиться несколькими шишками, набитыми в процессе работы с похожими датасетами в RavenDb на С#:
1) Для достаточно больших данных (например, FreeDb или про преступления в Чикаго) парсинг может занять вечность, сильно упираясь в IO. Мне приемлемых результатов в парсинге FreeDb удалось достичь, только запустив Raven на SSD и расположив исходный файл на ram-диске (в запакованном виде он не очень большой, около 2,5 Гб. Document store с несколькими индексами у меня занимает больше 8 Гб).
2) Одна из особенностей работы с такими большими данными состоит в том, что невозможно предсказать, какие ошибки в этих данных ждут нас впереди. К тому же, датасеты, как правило, настолько большие, что даже бегло просмотреть их совершенно невозможно, к тому же в CVS долго не посмотришь. Поэтому:
Для беглого просмотра данных я использую Sublime Text (http://www.sublimetext.com/). Помимо того, что это просто совершенный текстовый редактор, он еще и достаточно хорош в работе с действительно большими файлами. По крайней мере, текстовые файлы в несколько гигабайт он хотя бы способен открыть и приемлемо в них искать.
CSV удобно читать по строчке через StreamReader используя следующий паттерн:
while ((line = reader .ReadLine()) != null ) { try { this.ParseItInSomeWay(); } catch { this.DoSomethingOnError(); } }


Я обычно не пытаюсь делать что-нибудь вроде File.ReadAllText(), это не работает, значительная часть сетов просто не влезет в память вашего процесса.

3) Количество ошибок в реальных датасетах не поддается никакой оценке. Поэтому ваш парсер будет падать. Будет часто падать. Раздражающе часто. Поэтому я использую следующий подход: 

- Я пишу парсер, который хорошо работает на нескольких первых записях. Тестирую на маленьком сете (этих же первых записях, спасибо Sublime Text за возможность их открыть), добавляю несколько наивных юнит-тестов для парсера.
- Затем я запускаю парсер на реальном сете, не добавляя запись результатов в хранилище. В первые несколько минут парсер выдает ряд ошибок; я исправляю парсер, учитывая эти ошибки и добавляю юнит-тесты, проверяющие парсинг строк, содержащих эти ошибки. 
- Потом я добавляю логику в обработчик эксепшнов (см. паттерн выше), которая записывает строки, где парсер сломался, в отдельный файл и запускаю парсер на весь датасет, включая запись результатов в хранилище документов.
- После того, как парсинг прошел (или в процессе, тут уж кто как любит), я анализирую строки, которые не получилось распарсить, исправляю парсер, добавляю тесты и на эти случи. Затем парсер запускается логе ошибок, то есть на тех строках, которые не получилось распарсить в прошлый раз. Повторяется до тех пор, пока в логе неудачных попыток парсинга не останется ничего, или останутся только совсем непонятные или явно ошибочные строки. Их можно игнорировать. 

Итак, сегодня мы посмотрели на то, где можно взять немножко… (Немножко? Никого не интересует немножко!) несколько миллионов записей по самым разным темам. В следующий раз посмотрим, как можно анализировать плохо структурированные данные используя RavenDB на примере, скажем, задач об обладателях медалей Олимпиады. А там, может быть, ковырнем и какой-нибудь более реальный датасет на предмет интересных выводов об окружающей действительности.
Пара ссылок с куда большей коллекцией свободных данных для экспериметов:
http://www.mysqlperformanceblog.com/2011/02/01/sample-datasets-for-benchmarking-and-testing/
http://www.sqlservercentral.com/Forums/Topic1014209-391-1.aspx
Каждый найдет что-нибудь по интересам.

Комментариев нет:

Отправить комментарий