Восполнение отсутствующих данных

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

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

Реализующая эту идею функция mdclassify получается небольшой модификацией classify. Добавьте ее в файл treepredict.py:

def mdclassify(observation,tree): if tree.results!=None: return tree.results else:

v=observation[tree.col] if v==None:

tr,fr=mdclassify(observation,tree.tb),mdclassify(observation,tree.fb)

tcount=sum(tr.values( ))

fcount=sum(fr.values( ))

tw=float(tcount)/(tcount+fcount)

fw=float(fcount)/(tcount+fcount)

result={}

for k,v in tr.items( ): result[k]=v*tw for k,v in fr.items( ): result[k]=v*fw return result else:

if isinstance(v,int) or isinstance(v,float): if v>=tree.value: branch=tree.tb else: branch=tree.fb else:

if v==tree.value: branch=tree.tb else: branch=tree.fb return mdclassify(observation,branch)

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

Протестируем функцию mdclassify на строке, в которой отсутствует важная информация: >>> reload(treepredict)

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

>>> treepredict.mdclassify([‘google’,None,’yes’,None],tree)

{‘Premium’: 1.5, ‘Basic’: 1.5}

>>> treepredict2.mdclassify([‘google’,’France’,None,None],tree)

{‘None’: 0.125, ‘Premium’: 2.25, ‘Basic’: 0.125}

Как и следовало ожидать, отсутствие переменной «Сколько просмотрел страниц» дает сильные шансы на премиальное обслуживание и слабые шансы на базовое. Отсутствие переменной «Читал FAQ» дает другое распределение, где шансы на обоих концах взвешены с учетом количества образцов по обе стороны.

Числовые результаты

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

Хотя функцию buildtree можно применить к набору данных, где результатами являются числа, ничего хорошего из этого, скорее всего, не получится. Если все числа трактовать как различные категории, то алгоритм не будет принимать во внимание то, насколько сильно числа отличаются; все они будут рассматриваться как абсолютно независимые величины. Чтобы справиться с этой проблемой, необходимо в качестве критерия расщепления использовать дисперсию вместо энтропии или коэффициента Джини. Добавьте в файл treepredict.py функцию variance:

def variance(rows):

if len(rows)==0: return 0 data=[float(row[len(row)-1]) for row in rows] mean=sum(data)/len(data)

variance=sum([(d-mean)**2 for d in data])/len(data) return variance

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

Вы можете следить за любыми ответами на эту запись через 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