вторник, 25 мая 2010 г.

RDF vs. неRDF на примере геоданных в контексте BeAware

Одной из исходный целей создания BeAware было попробовать с пользой применить технологии из стека Semantic Web (на фоне разочарования от трехлетнего внедрения семантики туда, где она, по большому счету, не нужна). Предлагаю рассмотреть вопрос актуальности применения RDF-массивов Linked Data по сравнению с другими формами представления данных.

На текущий момент в формате Linked Data опубликовано огромное число массивов данных. Интересно, что для большинства из них исходной является реляционная форма представления, и два крупнейших массива геоданных: GeoNames и LinkedGeoData, не являются исключениями. Так, GeoNames ежедневно публикуется в виде CSV-дампов, которые отлично ложатся на реляционную модель, а LinkedGeoData является RDF-представлением данных OpenStreetMap, которые доступны в разных неRDF форматах. Встает вопрос: какую пользу мы можем извлечь за счет перевода данных в RDF? Я не буду останавливаться на теоретических аспектах этого вопроса (предполагается, что читатель с ними знаком), а опишу конкретные юзкейсы, которые стали/станут нам доступны за счет использования RDF.

Начнем с небольшого введения в то, как мы докатились до такой жизни пришли к идее совместного использования двух таких разных массивов геоданных в одном проекте: GeoNames для поиска городов (и вышележащих сущностей), а LinkedGeoData - для поиска объектов внутри города.

На начальном этапе казалось, что нужды использовать GeoNames нет, ведь LinkedGeoData содержит информацию не только об объектах, но и о городах, странах и т. д. Однако ввиду ориентации OSM на контент, а не на контекст, города (об областях, штатах и т. д. и говорить не приходится) размечены очень плохо: нет ни того богатства локализованных имен, ни четкой иерархии, что есть в GeoNames.

Итак, решение принято: используем GeoNames для первого "измерения" места проведения события - города. Однако вопрос, что использовать: реляционное или RDF представление, все еще был актуальным. В ходе одного из обсуждений в гуглгруппе GeoNames Prateek Jain дал мне ссылку на научную работу, соавтором которой он является. Эта статья открыла мне глаза на довольно очевидную вещь: как можно играюче обрабатывать транзитивные иерархии GeoNames-сущностей (например, город->район->область->страна) за счет движка логического вывода. Действительно, вряд ли какое-то средство справится с этим лучше, чем заточенный под подобного рода задачи движок логического вывода (бай-бай, рекурсивные SQL-запросы).

Еще одним аргументом за RDF-версию GeoNames была возможность интеграции с геополитической онтологией. На текущий момент, в GeoNames не представлены объединения стран вроде Евросоюза (хотя работа в этом направлении ведется), а мы планируем реализовать геофильтрацию по подобным сущностям. А в геополитической онтологии уже содержатся Country Groups - надо лишь реализовать маппинг к странам GeoNames.

Выбор между LinkedGeoData и "чистым" OpenStreetMap тоже был не из сложных.

Во-первых, ввиду того, что LinkedGeoData ориентирован не на показ карт, а на обработку запросов, LinkedGeoData поставляется не только в полной версии, но и в урезанной - LinkedGeoData Elements. Урезанная версия не содержит малоинтересные объекты (хайвеи, висячие элементы и др.) и содержит в 25 раз меньше триплетов. Для нашего скромного бюджета - то, что доктор прописал (хороший хостинг 3 миллиардов триплетов полной версии LinkedGeoData обошелся бы недешево). Этот пункт не имеет отношения ни к семантике, ни к RDF и, возможно, подобные урезанные массивы публикуются и для "чистого" OpenStreetMap (хотя мне не попадались). Но это лишь подчеркивает, что у массивов из Linked Data могут быть и чисто технические, выходящие за рамки семантики преимущества.

Во-вторых, онтология LinkedGeoData, связывающая все категории и свойства OpenStreetMap, отлично легла на наш интерфейс выбора нового места, к тому же позволив использовать логический вывод, например, для получения зданий всех типов. Мелочь, а приятно.

Мы рассмотрели преимущества использования RDF-массивов GeoNames и LinkedGeoData по отдельности. Однако название Linked Data как бы намекает на то, что дополнительные плюсы должны проявляться при интеграции массивов. К сожалению, на текущий момент маппинга между LinkedGeoData и GeoNames нет. Однако когда он все же будет разработан (такой пункт значится в todo-листе разработчиков LinkedGeoData), для нас откроется несколько полезных юзкейсов. Ниже приведу один пример.

Каждая сущность как в GeoNames, так и в LinkedGeoData снабжается координатами (широтой и долготой). Для городов (да и для других объектов с большой площадью) координаты, насколько я могу судить, не имеют какой-либо семантики (например, можно было бы предположить, что это координаты здания городской администрации): это просто координаты внутри города. Так вот в GeoNames и LinkedGeoData эти координаты частенько отличаются. Отличие в координатах, как правило, не очень большое, но достаточное для того, чтобы наступить на следующие грабли. В OpenStreetMap рядом с этими координатами прописывается название города. Когда в форме добавления нового места вы выбираете город, на карте устанавливается точка из GeoNames (ведь поиск городов осуществляется при помощи GeoNames), при этом название города на карте не видно (по крайней мере при используемом по умолчанию масштабе). Имея же маппинг GeoNames+LinkedGeoData, мы сможем подгружать для GeoNames-городов координаты из LinkedGeoData.

Подытоживая, могу с уверенностью сказать, что использование Linked Data - это не дань моде (есть такое мнение...), а реальная возможность расширить функциональность вашего приложения - главное найти грамотное применение открывающимся с переходом на RDF возможностям.

Текущее положение дел в проекте BeAware

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

Начнем с сердца проекта - онтологии.

На мой взгляд, онтология BeAware должна удовлетворять следующим критерям:
1. Быть дружелюбной к пользователю. Этот пункт не случайно на первом месте. Мы создаем не академическое приложение, а поэтому нельзя допустить, чтобы пользоваться сайтом могли лишь обладатели степени PHD Оксфордского Университета.
2. Одним из конкурентных преимуществ семантических технологий является возможность логического вывода, поэтому считаю, что онтология должна максимально эффективно (эффективно для пользователя, опять же) его использовать. Сейчас работа движка логического вывода проявляется, например, при поиске всех развлекательных событий (сколько бы нижележащих уровней иерархии ни было) или научных конференций по всем гуманитарным наукам. Лучше, чем ничего... но эта сторона онтологии еще явно требует доработки.
3. Онтология должна быть обобщением основных типов событий, происходящих в мире.

Я уже говорил об этом в предыдущем посте, но не могу не повториться (уж очень это, на мой взгляд, важно). Проработка онтологии - сложная и ответственная задача. Сложная, потому что нужно рассмотреть огромное число происходящих в мире событий и обобщить их в удобной для конечного пользователя форме. Ответственная, потому что как только онтология будет стабилизирована, вступит в действие ограничение обратной совместимости, а значит мы уже не сможем свободно ее менять (так как для каждого типа уже будут созданы события, которые нужно будет поддерживать).

Список открытых вопросов по структуре онтологии:
1. Сейчас событие "музыкальный концерт" является наследником "развлекательного события". Однако, на мой взгляд, концерты классической музыки претендуют на звание культурного события. В рамках текущего подхода, когда корневыми событиями (корневыми в визуальном плане: все события являются наследниками базового класса Event) являются события, относящиеся к какой-либо сфере жизни, было бы логично выделить класс "концерт классической музыки" и сделать его подклассом "культурного события". Однако мне кажется, что такой подход будет путать пользователей (и концерты классической музыки будут по ошибке создаваться как экземпляры "музыкального концерта"), поэтому решение этой проблемы пока под вопросом.
2. У события "Театр" есть свойство "вид театрального искусства" (не придумал более лаконичного лейбла). Стоит ли оставить это так, или лучше выделить оперу, баллет и т. д. в подклассы класса "Театр"? С одной стороны, это загромоздит онтологию, с другой, - текущая реализация не позволит нам в будущем добавить дополнительные свойства, например, для балета (технически-то сможем, но юзабилити такого решения представляется мне сомнительным).
3. Есть ли какая-то стандартизированная классификация наук? Текущая иерархия для свойства "вид науки" взята из английской википедии, но, во-первых, она довольно куцая, а во-вторых, слабо коррелирует с классификацией, принятой на постсоветском пространстве.
4. Не приложу ума, куда разместить событие "выставка" (exhibition). Выставки бывают разные: картин, собак, IT (софт, железо, игры) и т. д.
5. У меня есть большой соблазн создать корневую категорию IT. Пока я с ним успешно борюсь... но встает более серьезный вопрос: по каким критериям выделять корневые события?

Перейдем ко второму пункту сегодняшнего поста - к обзору геоданных и их применения в BeAware.

Итак, каждое событие привязывается к определенному месту, где:
Место = Город (GeoNames) + [Объект (LinkedGeoData)], где объект - опциональный параметр.

Сначала предлагаю обсудить, как можно использовать привязку каждого события к GeoNames. Итак, имеем следующие исходные данные:
1. У каждого события есть URI из RDF-массива GeoNames
2. GeoNames построен на транзитивной иерархии (например, вот (http://ws.geonames.org/hierarchy?geonameId=1489425) иерархия для Томска: Томск->Томская область->Российская федерация->Европа->Земля). Причем количество и названия элементов иерархии меняются от страны к стране.
3. Движок логического вывода Virtuoso может играючи обрабатывать транзитивность, определяя принадлежность события, к тому или иному уровню иерархии.

Раз все так хорошо, почему у нас реализована лишь фильтрация по городам и странам? Дело в том, что мы пока не нашли красивого user-friendly решения. Я вижу два варианта реализации гибкой фильтрации (под гибкой я имею в виду фильтрацию, которая использует иерархию GeoNames в полной мере):
1. На базе существующего решения. Просто убираем ограничение поиска лишь по странам и городам - пользователь сможет найти и районы, и области, и республики и т. д. Но это будет полный бардак. Сейчас при поиске сущности вручную прописывается, является ли она городом или страной. Однако при гибком подходе мы можем прописать лишь GeoNames feature code (http://www.geonames.org/statistics/total.html), но это очень недружелюбно к пользователю.
2. Пользователь может вводить только города, но рядом с соответствующим фильтру городом отображается вышележащая иерархия (элементы которой можно выбрать наравне с городом). В этом случае засчет визуальности иерархии отчасти решается проблема первого подхода, но при этом рождается новая: пользователю нужно знать город в том регионе, который он хочет выбрать.

Ни один из вариантов мне не нравится но, вероятно, один из них придется реализовать. Что думаете на сей счет?

Иерархия GeoNames на текущий момент не включает в себя объединения стран. При этом идея фильтрации тех же научных конференции по всему Европейскому Союзу выглядит довольно интересной. Реализовать это можно: во-первых, в этом направлении идет работа внутри GeoNames, а во-вторых, есть замечательная геополитическая онтология, которую можно интегрировать с GeoNames. Вот, кстати, недавняя дискуссия на сей счет в гуглгруппе GeoNames. Но будет ли это востребовано? Есть ли еще объединения стран (кстати, необязательно именно стран) со столь же высокой степенью интеграции, как в Евросоюзе? Не хочется лишний раз нагружать и без того не самый простой интерфейс BeAware.

Продолжая вопрос геофильтрации, обратимся ко второму "измерению" месторасположения события, к конкретному объекту из LinkedGeoData. Почему бы не дать пользователям возможность фильтровать события по кокретному месту в городе? Навскидку, довольно полезный юзкейс: можно отслеживать все представления в любимом театре или все вечеринки в любимом ночном клубе. Серьезных сложностей с реализацией этой возможности возникнуть не должно, однако в релиз она попадет вместе со всеми изменениями, касающимися геоданных: придется крепко поломать голову над тем, как объединить все виды геофильтрации, и при этом не отпугнуть пользователей излишней сложностью.

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

Довольно логичным решением было бы использовать интерфейс, базирующийся на поиске по имени/адресу объекта. Однако в этом случае пользователь может по ошибке выбрать объект, не находящийся в выбранном им городе. Кстати, этой проблемы не лишен и текущий интерфейс. Пользователь может выбрать город, затем увести карту куда угодно и выбрать объект в другой части света. Проверить принадлежность координат к городу довольно сложно, учитывая, что города постоянно растут. По крайней мере мне не известен ни один сервис, предоставляющий такую информацию. Может, у военных попросить... :) В качестве обходного пути я вижу следующее решение. Для каждого города у нас есть координаты его условного центра (просто некоторая точка внутри города). Также у нас есть некоторый объект (у которого тоже есть координаты). Мы можем рассчитать расстояние между этими точками и разделить его на население города (здесь предполагается, что размер города находится в прямой зависимости от его населения). Если это нормированное значение превышает некоторый порог, мы либо выдаем предупреждающее сообщение пользователю, либо отдаем событие на премодерацию. Что скажете?

На этом данный пост завершается и плавно переходит в следующий, который появится совсем скоро.

воскресенье, 23 мая 2010 г.

Запущена альфа-версия проекта BeAware

Все началось несколько месяцев назад, когда в поисках информации о конференции я посетил не один каталог событий, однако ни один из них меня не порадовал: отсутствие удобного поиска (что при большом наполнениии превращает сайт в мусорку), недостаток интеграции с геоданными и другие огрехи подтолкнули меня к идеи реализации собственной площадки событий. При этом, пожалуй, самым серьезным мотиватором стал потенциал применения в этом проекте технологий из стека Semantic Web (а такой проект я подыскивал уже давно). Объединившись с Ефимовым Александром, мы приступили к работе над проектом BeAware.

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

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

После того, как выбран тип события, необходимо задать место его проведения. Можно либо выбрать уже ранее отмеченное место (здесь ничего интересного), либо добавить новое:
Место - это, прежде всего, город (используется GeoNames)। Однако, выбрав город, можно задать и конкретный объект в нем (используется массив LinkedGeoData, который, в свою очередь, базируется на OpenStreetMap). Между выбором города есть промежуточный этап выбора типа объекта, который помогает отфильтровать объекты (кстати, здесь ненавязчиво используется логический вывод, например, при выборе всех типов зданий).
После того как место выбрано, перед нам открываются остальные свойства события (их список варьируется в зависимости от типа события):
Заполняем их - и событие создано.

Ознакомившись с тем, что из себя представляют события, вернемся на главную страницу и рассмотрим поиск, точнее его расширенную версию:
Для начала выберем тип события (текущая реализация выпадающего дерева событий не самая удобная... но мы работаем над этим), в результате чего подгрузятся дополнительные опциональные критерии фильтрации. Например, для научной конференции это будут два критерия: "платность/бесплатность" и вид науки. И иерархия событий, и иерархия значений свойств событий обрабатываются движком логического вывода, поэтому если пользователь запросит развлектельные события, в выдачу попадут как непосрдественно экземпляры класса "развлектельное событие", так и экземпляры всех его потомков (фестивали, карнавалы и т. д.). Аналогично, если пользователя интересуют научные конференции по всем гуманитарным наукам - нет проблем.

Теперь рассмотрим фильтрацию по месторасположению. На данный момент можно отфильтровать события либо по городу, либо по стране. И это лишь малая часть того, что мы можем сделать, имея в руках те мощные средства, на которых базируется наш сервис (GeoNames, LinkedGeoData, движок логического вывода из Virtuoso). Сейчас я не буду вдаваться в детали, но о том, почему мы остановились на такой реализации и какие перемены ждут геофильтрацию, подробно расскажу в следующем посте.

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

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

Во-первых, будет детальнее проработана онтология. Это очень сложная и ответственная задача. Сложная, потому что нужно рассмотреть огромное число происходящих в мире событий и обобщить их в удобной для конечного пользователя форме. Ответственная, потому что как только онтология будет стабилизирована, вступит в действие ограничение обратной совместимости, а значит мы уже не сможем свободно менять ее в будущем (так как для каждого типа уже будут созданы события, которые нужно будет поддерживать).

Во-вторых, будет улучшена геофильтрация. Это просто нелепо иметь в руках GeoNames+LinkedGeoData+Движок_логического_вывода и выжать из всего этого лишь фильтрацию по городам и странам. Постараемся существенно улучшить этот компонент.

В-третьих, будут реализованы подписки, интерфейс которых будет очень похож на интерфейс расширенного поиска. Подписки лишат пользователей, желающих отслеживать те или иные события, "удовольствия" ежедневного ручного поиска, дав им возможность получать уведомления посредством email или RSS.

В-четвертых, добавим RDFa-разметку.

В-пятых, интегрируем MusicBrainz для музыкальных концертов.

В-шестых, предлагайте свои идеи - мы не оставим их без внимания :)

До запуска беты наши основные приоритеты - функционал и юзабилити, после - популяризация.

P. S. Спасибо ребятам из компании "Соционика" за помощь с дизайном и версткой.
PP. S. Отдельное "спасибо" хабрачеловеку LeeMiller. Взявшись за разработку дизайна и верстки BeAware, он начал за здравие, но после получения предоплаты его как будто подменили. В течение полутора месяцев он кормил нас "завтрками" и враньем на любой вкус, а в результате сорвал нам все сроки (особенно если учесть, что его мы искали после того, как нас кинул предыдущий дизайнер: видимо, была черная полоса). Я, быть может, и забил бы на эту ситуацию, но LeeMiller проигнорировал мои сообщения о том, что было бы неплохо вернуть предоплату - а значит это уже не халатное отношение к работе, а мошенничество. Уважаемый LeeMiller, в ваших интересах прислушаться к моим сообщениям раньше, чем мы не доберемся с постами о BeAware на Хабр.