Категориальные свойства

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

Ответы «да/нет»

Это самый простой случай: ответ «да» преобразуется в 1, ответ «нет» – в -1. При этом еще остается возможность для сопоставления отсутствующему или неоднозначному ответу (например, «не знаю») значения 0. Добавьте в файл advancedclassify.py функцию yesno, которая будет выполнять такое преобразование: def yesno(v):

if v==’yes’: return 1 elif v==’no’: return -1 else: return 0

Списки интересов

Представить список интересов человека в наборе данных можно несколькими способами. Самый простой – считать каждый элемент списка отдельной числовой переменной, которая принимает значение 0, если человек выразил интерес, и 1 – в противном случае. Если речь идет об отдельных людях, то это самый лучший подход. Но когда мы имеем дело с парами, то более интуитивным подходом будет взять за переменную количество общих интересов.

Добавьте в файл advancedclassify.py функцию matchcount, которая возвращает количество совпавших элементов в двух списках в виде числа с плавающей точкой:

def matchcount(interest1,interest2): l1=interest1.split(‘:’) l2=interest2.split(‘:’) x=0

for v in l1:

if v in l2: x+=1 return x

Количество общих интересов – любопытная переменная, но очевидно, что она отбрасывает некоторую потенциально полезную информацию. Быть может, некоторые сочетания интересов способствуют образованию хорошей пары, например катание на лыжах и сноубординг или любовь к выпивке и к танцам. Классификатор, который не был обучен на реальных данных, никогда не сможет узнать о таких сочетаниях. Альтернатива созданию отдельной переменной для каждого интереса (это увеличивает общее число переменных и, следовательно, сложность классификатора) – иерархическая организация интересов. Например, можно сказать, что катание на лыжах и сноубординг – примеры зимних видов спорта, которые, в свою очередь, являются подкатегорией спорта вообще. Если оба члена пары интересуются зимними видами спорта, но не одними и теми же, то matchcount добавляет к их индексу сочетаемости не 1, а 0,8. Чем выше приходится подниматься по иерархии, чтобы найти соответствие, тем меньше вклад в индекс. Хотя в наборе данных для подбора пар такой иерархии нет, этот подход заслуживает внимания при решении аналогичных задач.

Вычисление расстояний с помощью сайта Yahoo! Maps

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

Конечно, точно вычислить расстояние между двумя адресами без дополнительной информации невозможно. Но, к счастью, сайт Yahoo! Maps предлагает службу Geocoding, которая по адресу в США возвращает широту и долготу. Получив эти данные для двух адресов, можно приблизительно вычислить расстояние между ними.

Если по какой-то причине вы не можете воспользоваться API службы Yahoo!, просто добавьте в файл advancedclassify.py такую заглушку:

def milesdistance(a1,a2): return 0

Получение ключа разработчика для Yahoo!

Для доступа к API службы Yahoo! необходимо сначала получить ключ разработчика, который будет включаться в запросы для идентификации вашего приложения. Чтобы его получить, нужно зайти на страницу http://api.search.yahoo.com/webservices/register_application и ответить на несколько вопросов. Если у вас еще нет учетной записи в Yahoo!, создайте ее. Ключ вы получите сразу же, ждать ответа по электронной почте не придется.

Работа с Geocoding API

Для обращения к API службы Geocoding необходимо задать URL вида http://api.local.yahoo.com/MapsService/V1 /geocode?appid=appid& location=location.

Параметр location – это местонахождение в свободном формате: адрес, почтовый индекс или даже только город и штат. В ответ возвращается XML-документ:

<ResultSet>

<Result precision="address">

<Latitude>37.417312</Latitude>

<Longitude>-122.026419</Longitude>

<Address>755 FIRST AVE</Address>

<City>SUNNYVALE</City>

<State>CA</State>

<Zip>94089-1019</Zip>

<Country>US</Country>

</Result>

</ResultSet>

Вас интересуют в нем поля Longitude (Долгота) и Latitude (Широта). Для разбора документа воспользуемся библиотекой minidom, с которой мы уже работали в предыдущих статьях. Добавьте в файл advancedclassify. py функцию getlocation: yahookey="Sarn ключ"

from xml.dom.minidom import parseString from urllib import urlopen,quote_plus

loc_cache={}

def getlocation(address):

if address in loc_cache: return loc_cache[address] data=urlopen(‘http://api.local.yahoo.com/MapsService/V1/’+\ ‘geocode?appid=%s&location=%s’ % (yahookey,quote_plus(address))).read( ) doc=parseString(data)

lat=doc.getElementsByTagName(‘Latitude’)[0].firstChild.nodeValue long=doc.getElementsByTagName(‘Longitude’)[0].firstChild.nodeValue loc_cache[address]=(float(lat),float(long)) return loc_cache[address]

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

Вычисление расстояния

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

относительно невелики и нужны только для сравнения, поэтому достаточно приближенных значений. Для аппроксимации применяется евклидово расстояние, только разность широт предварительно умножается на 69,1, а разность долгот – на 53.

Добавьте функцию milesdistance в файл advancedclassify.py:

def milesdistance(a1,a2): lat1,long1=getlocation(a1) lat2,long2=getlocation(a2) latdif=69.1*(lat2-lat1) longdif=53.0*(long2-long1) return (latdif**2+longdif**2)**.5

Здесь сначала вызывается написанная ранее функция getlocation для получения координат обоих адресов, а потом вычисляется расстояние между ними. Если хотите, можете протестировать функцию в интерактивном сеансе:

>>> reload(advancedclassify)

<module ‘advancedclassify’ from ‘advancedclassify.py’>

>>> advancedclassify.getlocation(‘1 alewife center, cambridge, ma’)

(42.398662999999999, -71.140512999999999)

>>> advancedclassify.milesdistance(‘cambridge, ma’,’new york,ny’)

191.77952424273104

Обычно погрешность вычисления расстояний с помощью этой функции не превышает 10%, что для нашего приложения вполне приемлемо.

Создание нового набора данных

Теперь все готово для создания набора данных, пригодного для обучения классификатора. Необходима лишь функция, которая сведет все составные части воедино. Она загрузит данные с помощью loadmatch и преобразует их в набор столбцов. Добавьте функцию loadnumerical в файл advancedclassify.py: def loadnumerical( ): oldrows=loadmatch(‘matchmaker.csv’) newrows=[] for row in oldrows: d=row.data

data=[float(d[0]),yesno(d[1]),yesno(d[2]), float(d[5]),yesno(d[6]),yesno(d[7]), matchcount(d[3],d[8]), milesdistance(d[4],d[9]), row.match] newrows.append(matchrow(data)) return newrows

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

Вызовите ее в интерактивном сеансе, чтобы создать новый набор данных:

>>> reload(advancedclassify)

>>> numericalset=advancedclassify.loadnumerical( ) >>> numericalset[0].data

[39.0, 1, -1, 43.0, -1, 1, 0, 0.90110601059793416] При желании легко создать поднаборы, указав интересующие вас столбцы. Это полезно для визуализации данных и чтобы понять, как классификатор работает для различных переменных.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100