[{"data":1,"prerenderedAt":1428},["ShallowReactive",2],{"article-id-ru-ml-basic-3":3},{"id":4,"title":5,"body":6,"description":1189,"extension":1412,"meta":1413,"navigation":1422,"path":37,"seo":1423,"stem":1426,"__hash__":1427},"content/ru/blog/ml-basic-3.mdx","Ml Basic 3",{"type":7,"value":8,"toc":1404},"minimark",[9,1178],[10,11,12,16,39,42,47,139,142,145,149,166,183,186,193,196,202,205,211,214,220,223,227,230,236,239,242,248,251,256,259,265,280,283,289,292,295,456,459,513,554,557,651,654,657,786,834,949,952,1014,1017,1023,1026,1032,1035,1038,1056,1059,1063,1066,1072,1075,1078,1084,1087,1090,1093,1096,1102,1105,1108,1111,1116,1119,1136,1139,1143,1146,1149,1155,1158,1169,1172,1175],"section-md",{},[13,14,15],"p",{},"Это статья из цикла про основы машинного обучения.",[17,18,19,27,33],"ul",{},[20,21,22],"li",{},[23,24,26],"a",{"href":25},"/ru/blog/ml-basic-1","Часть 1. О машинном обучении простым языком",[20,28,29],{},[23,30,32],{"href":31},"/ru/blog/ml-basic-2","Часть 2. Линейная регрессия — проще некуда",[20,34,35],{},[23,36,38],{"href":37},"/ru/blog/ml-basic-3","Часть 3. О чем думают деревья?",[13,40,41],{},"В прошлой статье мы начали рассматривать самые простые\nметоды машинного обучения на примере линейной регрессии. Сегодня\nпосмотрим на еще одну модель, но уже для задачи классификации.",[43,44,46],"h2",{"id":45},"классификация-vs-регрессия","Классификация vs регрессия",[13,48,49,50,73,74,97,98,115,116,120,121,124,125,138],{},"Для начала вспомним первую статью и сформулируем для себя задачу.\nВходные данные у нас прежние: число или вектор чисел, как и раньше\nобозначим его ",[51,52,55],"span",{"className":53},[54],"katex",[56,57,59],"math",{"xmlns":58},"http://www.w3.org/1998/Math/MathML",[60,61,62,69],"semantics",{},[63,64,65],"mrow",{},[66,67,68],"mi",{},"X",[70,71,68],"annotation",{"encoding":72},"application/x-tex",". А вот выходные данные — ",[51,75,77],{"className":76},[54],[56,78,79],{"xmlns":58},[60,80,81,94],{},[63,82,83],{},[84,85,87,90],"mover",{"accent":86},"true",[66,88,89],{},"y",[91,92,93],"mo",{"stretchy":86},"^",[70,95,96],{"encoding":72},"\\widehat{y}"," — теперь\nизменятся. Раньше это было просто число. Для линейной регрессии вообще\nбез ограничений как на значения, так и на диапазон. Теперь же\n",[51,99,101],{"className":100},[54],[56,102,103],{"xmlns":58},[60,104,105,113],{},[63,106,107],{},[84,108,109,111],{"accent":86},[66,110,89],{},[91,112,93],{"stretchy":86},[70,114,96],{"encoding":72}," сможет принимать не любое значение, а только ",[117,118,119],"strong",{},"одно из\nзаданных заранее",". Такие значения будем называть ",[117,122,123],{},"классами",". Также\nдля наших данных есть заведомо правильные ответы, их будем обозначать\n",[51,126,128],{"className":127},[54],[56,129,130],{"xmlns":58},[60,131,132,136],{},[63,133,134],{},[66,135,89],{},[70,137,89],{"encoding":72}," (без крышки).",[13,140,141],{},"Давайте вернемся к примеру из прошлой статьи про определение веса по\nросту. Если раньше мы определяли точный вес в килограммах, то теперь мы,\nскорее, будем в роли судей перед боксерскими поединками. То есть нам не\nважен точный вес, а важна категория (легкая, средняя, тяжелая и так\nдалее).",[13,143,144],{},"Еще один вариант — бинарная классификация, когда класса всего два.\nОбычно это означает, что мы отвечает на какой-то вопрос словами «да» или\n«нет». Например, в случае с тем же ростом и весом мы можем попробовать\nответить на вопрос «Выше/тяжелее ли этот человек, чем в среднем по\nгороду?». Именно бинарную классификацию мы и будем рассматривать дальше.",[43,146,148],{"id":147},"как-классифицировать","Как классифицировать?",[13,150,151,152,165],{},"Итак, у нас есть входной вектор ",[51,153,155],{"className":154},[54],[56,156,157],{"xmlns":58},[60,158,159,163],{},[63,160,161],{},[66,162,68],{},[70,164,68],{"encoding":72}," и всего два возможных варианта\nответа. Давайте обозначим ответ «да» как единицу, а ответ «нет» как\nноль.",[13,167,168,169,182],{},"Возьмем самый простой случай, когда ",[51,170,172],{"className":171},[54],[56,173,174],{"xmlns":58},[60,175,176,180],{},[63,177,178],{},[66,179,68],{},[70,181,68],{"encoding":72}," — это одно число. Линейная\nрегрессия нам здесь не подойдет, так как она выдает ответ из\nнепрерывного множества (спойлер: есть способ заставить регрессию решать\nнашу текущую задачу, но это тема следующей статьи). Поэтому давайте пока\nпридумывать что-то другое.",[13,184,185],{},"Визуализируем наши данные. Они одномерные, поэтому легко отображаются на\nчисловой оси. Обозначим синими точками данные, для которых правильный\nответ — 0, и красными для которых ответ — 1.",[13,187,188],{},[189,190],"img",{"alt":191,"src":192},"Визуадизация данных классификации 1","/img/blog/ml-basic-3/image1.png",[13,194,195],{},"В таком случае все просто. Мы можем выбрать какое-то значение на прямой,\nи если наше входное число меньше этого значения, то ответ 0, а если\nбольше — 1. Как нам выбрать такое число. Давайте будем перебирать все\nварианты, как разделить выборку. Обычно делят в середине между двумя\nточками. У нас, таким образом, будет 8 вариантов:",[13,197,198],{},[189,199],{"alt":200,"src":201},"Визуадизация данных классификации 2","/img/blog/ml-basic-3/image2.png",[13,203,204],{},"Теперь проверим, сколько правильных ответов позволяет получить каждый из\nвариантов. Очевидно, что в этом конкретном случае у нас есть вариант,\nкоторый позволяет получить все правильные ответы:",[13,206,207],{},[189,208],{"alt":209,"src":210},"Визуадизация данных классификации 3","/img/blog/ml-basic-3/image3.png",[13,212,213],{},"Но так бывает не всегда. Изменим начальные условия:",[13,215,216],{},[189,217],{"alt":218,"src":219},"Визуадизация данных классификации с другими изначальными условиями","/img/blog/ml-basic-3/image4.png",[13,221,222],{},"В таком случае мы не можем полностью правильно разделить наши данные. Но\nможно минимизировать ошибку. Если разделить данные там, где это делалось\nв прошлый раз, мы получим 7 правильных ответов из 8. И это лучшее, чего\nмы можем достичь одним разделением.",[43,224,226],{"id":225},"строим-деревья","Строим деревья",[13,228,229],{},"Но бывают случаи, когда невозможно достичь нормального качества только\nодним разделением. Например, такой:",[13,231,232],{},[189,233],{"alt":234,"src":235},"Вариант данных, где одно разделение будет неэффективно","/img/blog/ml-basic-3/image5.png",[13,237,238],{},"Здесь при одном разделении у нас будет максимум 5 правильных ответов из\n8, что не очень хорошо. Поэтому надо придумывать что-то еще.",[13,240,241],{},"Решение выглядит интуитивным: делить не один раз, а несколько. Например,\nмы можем сначала поделить вот так:",[13,243,244],{},[189,245],{"alt":246,"src":247},"Данные с несколькими разделениями","/img/blog/ml-basic-3/image6.png",[13,249,250],{},"После такого деления, мы считаем, что все объекты меньше этого значения\nимеют класс 1. Оставшуюся часть мы делим еще раз (точки, закрашенные\nбелым, мы определили на предыдущем шаге, и их можно не рассматривать):",[13,252,253],{},[189,254],{"alt":246,"src":255},"/img/blog/ml-basic-3/image7.png",[13,257,258],{},"В итоге получаем алгоритм, который нам нужно выполнить, чтобы\nклассифицировать любой элемент:",[13,260,261],{},[189,262],{"alt":263,"src":264},"Визуализация алгоритма разделения данных","/img/blog/ml-basic-3/image8.png",[13,266,267,268,271,272,275,276,279],{},"Такой алгоритм и называется деревом решений. У дерева есть ",[117,269,270],{},"корень"," --\nэто то место, с которого начинается алгоритм. А точки, где он\nзаканчивается, то есть места, где мы получаем класс (на рисунке выше это\nцветные цифры — метки классов) называют ",[117,273,274],{},"листьями"," дерева. А все\nпромежуточные точки (прямоугольники на рисунке) называют ",[117,277,278],{},"узлами",".\nИменно узел описывает разделение значений на две части.",[13,281,282],{},"Остается понять, как такое дерево строить. Итак, в самом начале узлов и\nлистьев нет. Нам нужно сделать первое разделение данных, то есть создать\nузел. Снова выберем точки — кандидаты для разделения. Это будут\nсередины отрезков между соседними точками исходных данных (как и в\nпримере про самый простой случай):",[13,284,285],{},[189,286],{"alt":287,"src":288},"Визуализация кандидатов для разделения","/img/blog/ml-basic-3/image9.png",[13,290,291],{},"Теперь нужно решить, какой кандидат самый подходящий. И просто посчитать\nколичество правильных ответов тут уже не получится. Дело в том, что,\nесли мы постараемся получить максимум правильных ответов на первом шаге\n(в программировании это называется жадным алгоритмом), мы можем\nусложнить себе задачу на следующих. То есть надо оптимизировать все\nрешение, а не только первый шаг.",[13,293,294],{},"Поэтому придется действовать чуть сложнее. Мы по-прежнему будем\nперебирать всех кандидатов по очереди, но метрика будет другой. Итак, в\nпервую очередь считаем, сколько элементов оказываются справа и слева от\nнашего разделения:",[296,297,298,382],"table",{},[299,300,301],"thead",{},[302,303,304,310,347],"tr",{},[305,306,307],"th",{},[117,308,309],{},"Точка",[305,311,312,313,346],{},"|",[51,314,316],{"className":315},[54],[56,317,318],{"xmlns":58},[60,319,320,343],{},[63,321,322],{},[323,324,325,329],"msub",{},[66,326,328],{"mathvariant":327},"bold","S",[63,330,331,334,337,340],{},[66,332,333],{"mathvariant":327},"l",[66,335,336],{"mathvariant":327},"e",[66,338,339],{"mathvariant":327},"f",[66,341,342],{"mathvariant":327},"t",[70,344,345],{"encoding":72},"\\mathbf{S}_{\\mathbf{left}}"," |",[305,348,349,350,346],{},"| ",[51,351,353],{"className":352},[54],[56,354,355],{"xmlns":58},[60,356,357,379],{},[63,358,359],{},[323,360,361,363],{},[66,362,328],{"mathvariant":327},[63,364,365,368,371,374,377],{},[66,366,367],{"mathvariant":327},"r",[66,369,370],{"mathvariant":327},"i",[66,372,373],{"mathvariant":327},"g",[66,375,376],{"mathvariant":327},"h",[66,378,342],{"mathvariant":327},[70,380,381],{"encoding":72},"\\mathbf{S}_{\\mathbf{right}}",[383,384,385,397,408,419,429,438,447],"tbody",{},[302,386,387,391,394],{},[388,389,390],"td",{},"A",[388,392,393],{},"1",[388,395,396],{},"7",[302,398,399,402,405],{},[388,400,401],{},"B",[388,403,404],{},"2",[388,406,407],{},"6",[302,409,410,413,416],{},[388,411,412],{},"C",[388,414,415],{},"3",[388,417,418],{},"5",[302,420,421,424,427],{},[388,422,423],{},"D",[388,425,426],{},"4",[388,428,426],{},[302,430,431,434,436],{},[388,432,433],{},"E",[388,435,418],{},[388,437,415],{},[302,439,440,443,445],{},[388,441,442],{},"F",[388,444,407],{},[388,446,404],{},[302,448,449,452,454],{},[388,450,451],{},"G",[388,453,396],{},[388,455,393],{},[13,457,458],{},"Эти значения пока отложим, они пригодятся чуть позже. Теперь нужно\nпосчитать, насколько хорошо разделены данные слева и справа. Другими\nсловами, насколько качественно мы разделили объекты на два класса. Для\nэтого будем использовать критерий Джини. Он считается по формуле",[13,460,461],{},[51,462,464],{"className":463},[54],[56,465,466],{"xmlns":58},[60,467,468,510],{},[63,469,470,472,475,478,481],{},[66,471,451],{},[91,473,474],{},"=",[476,477,393],"mn",{},[91,479,480],{},"−",[63,482,483,486,496,499,507],{},[91,484,485],{"fence":86},"(",[487,488,489,491,494],"msubsup",{},[66,490,13],{},[476,492,493],{},"0",[476,495,404],{},[91,497,498],{},"+",[487,500,501,503,505],{},[66,502,13],{},[476,504,393],{},[476,506,404],{},[91,508,509],{"fence":86},")",[70,511,512],{"encoding":72},"G = 1 - \\left( p_{0}^{2} + p_{1}^{2} \\right)",[13,514,515,516,534,535,553],{},"где ",[51,517,519],{"className":518},[54],[56,520,521],{"xmlns":58},[60,522,523,531],{},[63,524,525],{},[323,526,527,529],{},[66,528,13],{},[476,530,493],{},[70,532,533],{"encoding":72},"p_{0}"," и ",[51,536,538],{"className":537},[54],[56,539,540],{"xmlns":58},[60,541,542,550],{},[63,543,544],{},[323,545,546,548],{},[66,547,13],{},[476,549,393],{},[70,551,552],{"encoding":72},"p_{1}"," — это доли классов ноль и один в нашем\nразделении.",[13,555,556],{},"Допустим, у нас слева три нуля и одна единица. Тогда",[13,558,559],{},[51,560,562],{"className":561},[54],[56,563,564],{"xmlns":58},[60,565,566,648],{},[63,567,568,582,584,586,588,634,636,638,640,643,645],{},[323,569,570,572],{},[66,571,451],{},[63,573,574,576,578,580],{},[66,575,333],{},[66,577,336],{},[66,579,339],{},[66,581,342],{},[91,583,474],{},[476,585,393],{},[91,587,480],{},[63,589,590,592,610,612,616,632],{},[91,591,485],{"fence":86},[593,594,595,608],"msup",{},[63,596,597,599,606],{},[91,598,485],{"fence":86},[600,601,602,604],"mfrac",{},[476,603,415],{},[476,605,426],{},[91,607,509],{"fence":86},[476,609,404],{},[91,611,498],{},[613,614,615],"mtext",{}," ",[593,617,618,630],{},[63,619,620,622,628],{},[91,621,485],{"fence":86},[600,623,624,626],{},[476,625,393],{},[476,627,426],{},[91,629,509],{"fence":86},[476,631,404],{},[91,633,509],{"fence":86},[91,635,474],{},[476,637,393],{},[91,639,480],{},[476,641,642],{},"0.625",[91,644,474],{},[476,646,647],{},"0.375",[70,649,650],{"encoding":72},"G_{left} = 1 - \\left( \\left( \\frac{3}{4} \\right)^{2} + \\ \\left( \\frac{1}{4} \\right)^{2} \\right) = 1 - 0.625 = 0.375",[13,652,653],{},"Чем меньше критерий, тем лучше. Например, если слева только единицы или\nтолько нули, значение критерия будет равно нулю. Это значит, что с этой\nстороны мы идеально отделили один из классов.",[13,655,656],{},"Посчитаем критерии для всех наших кандидатов:",[296,658,659,725],{},[299,660,661],{},[302,662,663,667,695],{},[305,664,665],{},[117,666,309],{},[305,668,669],{},[51,670,672],{"className":671},[54],[56,673,674],{"xmlns":58},[60,675,676,692],{},[63,677,678],{},[323,679,680,682],{},[66,681,451],{"mathvariant":327},[63,683,684,686,688,690],{},[66,685,333],{"mathvariant":327},[66,687,336],{"mathvariant":327},[66,689,339],{"mathvariant":327},[66,691,342],{"mathvariant":327},[70,693,694],{"encoding":72},"\\mathbf{G}_{\\mathbf{left}}",[305,696,697],{},[51,698,700],{"className":699},[54],[56,701,702],{"xmlns":58},[60,703,704,722],{},[63,705,706],{},[323,707,708,710],{},[66,709,451],{"mathvariant":327},[63,711,712,714,716,718,720],{},[66,713,367],{"mathvariant":327},[66,715,370],{"mathvariant":327},[66,717,373],{"mathvariant":327},[66,719,376],{"mathvariant":327},[66,721,342],{"mathvariant":327},[70,723,724],{"encoding":72},"\\mathbf{G}_{\\mathbf{right}}",[383,726,727,736,745,754,762,770,778],{},[302,728,729,731,733],{},[388,730,390],{},[388,732,493],{},[388,734,735],{},"0.41",[302,737,738,740,742],{},[388,739,401],{},[388,741,493],{},[388,743,744],{},"0.44",[302,746,747,749,751],{},[388,748,412],{},[388,750,493],{},[388,752,753],{},"0.48",[302,755,756,758,760],{},[388,757,423],{},[388,759,647],{},[388,761,647],{},[302,763,764,766,768],{},[388,765,433],{},[388,767,753],{},[388,769,493],{},[302,771,772,774,776],{},[388,773,442],{},[388,775,744],{},[388,777,493],{},[302,779,780,782,784],{},[388,781,451],{},[388,783,735],{},[388,785,493],{},[13,787,788,789,809,810,833],{},"Нам остается посчитать только финальную метрику для каждого кандидата.\nСчитается она как взвешенная сумма. Вспомним, что мы считали количество\nэлементов справа и слева от суммы. Весами будут как раз эти количества,\nделенные на суммарное количество элементов ",[51,790,792],{"className":791},[54],[56,793,794],{"xmlns":58},[60,795,796,806],{},[63,797,798,802,804],{},[66,799,801],{"mathvariant":800},"normal","∣",[66,803,328],{},[66,805,801],{"mathvariant":800},[70,807,808],{"encoding":72},"|S|",". У нас всего 8\nэлементов, то есть ",[51,811,813],{"className":812},[54],[56,814,815],{"xmlns":58},[60,816,817,830],{},[63,818,819,821,823,825,827],{},[66,820,801],{"mathvariant":800},[66,822,328],{},[66,824,801],{"mathvariant":800},[91,826,474],{},[476,828,829],{},"8",[70,831,832],{"encoding":72},"|S| = 8",". Итоговая формула:",[13,835,836],{},[51,837,839],{"className":838},[54],[56,840,841],{"xmlns":58},[60,842,843,946],{},[63,844,845,848,850,852,882,896,898,930],{},[66,846,847],{},"M",[91,849,474],{},[613,851,615],{},[600,853,854,874],{},[63,855,856,858,872],{},[91,857,801],{"fence":86},[323,859,860,862],{},[66,861,328],{},[63,863,864,866,868,870],{},[66,865,333],{},[66,867,336],{},[66,869,339],{},[66,871,342],{},[91,873,801],{"fence":86},[63,875,876,878,880],{},[66,877,801],{"mathvariant":800},[66,879,328],{},[66,881,801],{"mathvariant":800},[323,883,884,886],{},[66,885,451],{},[63,887,888,890,892,894],{},[66,889,333],{},[66,891,336],{},[66,893,339],{},[66,895,342],{},[91,897,498],{},[600,899,900,922],{},[63,901,902,904,920],{},[91,903,801],{"fence":86},[323,905,906,908],{},[66,907,328],{},[63,909,910,912,914,916,918],{},[66,911,367],{},[66,913,370],{},[66,915,373],{},[66,917,376],{},[66,919,342],{},[91,921,801],{"fence":86},[63,923,924,926,928],{},[66,925,801],{"mathvariant":800},[66,927,328],{},[66,929,801],{"mathvariant":800},[323,931,932,934],{},[66,933,451],{},[63,935,936,938,940,942,944],{},[66,937,367],{},[66,939,370],{},[66,941,373],{},[66,943,376],{},[66,945,342],{},[70,947,948],{"encoding":72},"M = \\ \\frac{\\left| S_{left} \\right|}{|S|}G_{left} + \\frac{\\left| S_{right} \\right|}{|S|}G_{right}",[13,950,951],{},"Считаем для всех наших кандидатов:",[296,953,954,966],{},[299,955,956],{},[302,957,958,962],{},[305,959,960],{},[117,961,309],{},[305,963,964],{},[117,965,847],{},[383,967,968,975,982,990,996,1002,1008],{},[302,969,970,972],{},[388,971,390],{},[388,973,974],{},"0.36",[302,976,977,979],{},[388,978,401],{},[388,980,981],{},"0.33",[302,983,984,987],{},[388,985,986],{},"С",[388,988,989],{},"0.3",[302,991,992,994],{},[388,993,423],{},[388,995,647],{},[302,997,998,1000],{},[388,999,433],{},[388,1001,989],{},[302,1003,1004,1006],{},[388,1005,442],{},[388,1007,981],{},[302,1009,1010,1012],{},[388,1011,451],{},[388,1013,974],{},[13,1015,1016],{},"Лучшая метрика у нас для точек C и E. Делить можно по любой, разделим по\nC.",[13,1018,1019],{},[189,1020],{"alt":1021,"src":1022},"Лучший кандидат для первого разделения","/img/blog/ml-basic-3/image10.png",[13,1024,1025],{},"Теперь смотрим, что у нас получилось. Слева только класс 1. Значит, тут\nу нас будет лист и дальше мы ничего не делим. Справа есть разные классы.\nЗначит тут не лист, а еще один узел. Повторяем разделение для этого\nузла:",[13,1027,1028],{},[189,1029],{"alt":1030,"src":1031},"Лучший кандидат для второго разделения","/img/blog/ml-basic-3/image11.png",[13,1033,1034],{},"После расчетов увидим, что делить нужно по E. Слева у нас будет класс 0.\nСправа класс 1. То есть все объекты распределены по классам. Добавляем\nдва листа. Дерево построено.",[13,1036,1037],{},"Итоговый алгоритм (изначально дерево пустое):",[1039,1040,1041,1044,1047,1050,1053],"ol",{},[20,1042,1043],{},"Добавляем узел в корень",[20,1045,1046],{},"Делаем разделение в узле",[20,1048,1049],{},"Если слева все объекты одного класса, создаем лист, иначе создаем\nузел",[20,1051,1052],{},"Если справа все объекты одного класса, создаем лист, иначе создаем\nузел",[20,1054,1055],{},"Повторяем пункты 2-4 пока в дереве есть хоть один узел",[13,1057,1058],{},"Когда дерево построено, мы для каждого нового объекта просто проходим по\nнему от корня, пока не дойдем до листа. Класс в листе и будет классом\nдля нашего объекта.",[43,1060,1062],{"id":1061},"больше-размерностей","Больше размерностей",[13,1064,1065],{},"Мы научились строить деревья для входных данных размерности 1, то есть\nдля единичных чисел. Например, с помощью дерева, описанного в предыдущей\nглаве, можно попробовать определить, яблоко перед нами или груша по\nодному параметру. Например, по диаметру. Однако, такая классификация\nбудет очень неточной. Один диаметр почти ничего не говорит о том, груша\nэто или яблоко.",[13,1067,1068],{},[189,1069],{"alt":1070,"src":1071},"Визуализация данных, которые невозможно эффективно разделить в одной размерности","/img/blog/ml-basic-3/image12.png",[13,1073,1074],{},"На всех рисунках дальше яблоки будем обозначать яблоки красным цветом, а\nгруши — синим. По рисунку видно, что разбить данные на группы больше\nодного элемента невозможно.",[13,1076,1077],{},"Ситуация радикально меняется, если мы добавим вторую размерность. Теперь\nкаждый фрукт мы будем описывать не одним параметром, а двумя: ширина\n(или диаметр) и высота. Добавление второго параметра позволит гораздо\nэффективнее отличать яблоки от груш.",[13,1079,1080],{},[189,1081],{"alt":1082,"src":1083},"Перенос данных в 2 размерности","/img/blog/ml-basic-3/image13.png",[13,1085,1086],{},"Обратите внимание, по оси X ничего не изменилось. Но теперь данные очень\nхорошо разделены по оси Y.",[13,1088,1089],{},"Если классификацию проводил бы человек, то он смотрел бы на вытянутость\n(отличие высоты от ширины). Чтобы сделать нечто подобное с помощью\nмашинного обучения можно снова использовать решающие деревья. Осталось\nразобраться, как построить дерево для нашего случая.",[13,1091,1092],{},"На самом деле алгоритм будет почти таким же. Мы на каждом шаге делим\nданные на две части. Основное отличие в том, что раньше нам не нужно\nбыло выбирать, по какому параметру делить, так как параметр был один\nединственный. Теперь параметров два и сначала нам нужно решить, по\nкакому из параметров проводить разделение. После этого все сводится к\nвыбору точки разделения, а это мы уже научились делать в предыдущей\nглаве.",[13,1094,1095],{},"Как будут выглядеть такие разделения на графике? Раньше у нас была\nтолько одна ось, и мы просто ставили точку, левее которой все объекты\nпопадают в одну ветку дерева, а правее — в другую. Теперь у нас осей\nдве. И первый шаг — это выбор, по какой оси мы производим разделение.\nЕсли мы выбираем ось X, то это будет вертикальная линия, если Y —\nгоризонтальная.",[13,1097,1098],{},[189,1099],{"alt":1100,"src":1101},"Кандидат для разделения в 2-х размерностях","/img/blog/ml-basic-3/image14.png",[13,1103,1104],{},"Оранжевым и зеленым цветами показаны разделения по разным признакам\n(осям).",[13,1106,1107],{},"На втором этапе мы выбираем, где именно такая линия будет проходить.\nПосле этого, объекты по разную сторону от линии (выше/ниже или\nлевее/правее) попадают в разные ветки дерева.",[13,1109,1110],{},"Осталось разобраться, как же именно нам выбирать ось. На самом деле все\nочень просто. Мы перебираем теперь не только кандидатов на разделение по\nодному признаку, а по всем. И выбираем лучший из всех вариантов. А когда\nна втором шаге нам нужно сделать разделение по выбранной оси, мы уже\nзнаем, где это сделать, так как посчитали это на первом шаге. Если\nвизуализировать работу дерева на графике, получим такой результат:",[13,1112,1113],{},[189,1114],{"alt":1100,"src":1115},"/img/blog/ml-basic-3/image15.png",[13,1117,1118],{},"Итоговый алгоритм будет выглядеть так:",[1039,1120,1121,1123,1126,1129,1131,1133],{},[20,1122,1043],{},[20,1124,1125],{},"Находим лучшее разделение по каждому из признаков",[20,1127,1128],{},"Делаем разделение в узле по лучшему из признаков",[20,1130,1049],{},[20,1132,1052],{},[20,1134,1135],{},"Повторяем пункты 2-5 пока в дереве есть хоть один узел",[13,1137,1138],{},"Если посмотреть на этот алгоритм, станет понятно, что нам ничего не\nмешает работать с данными больших размерностей. Например, для трехмерных\nданных мы будет разделять их не линией, а плоскостью. Такой вариант еще\nможно визуализировать. А вот для четырех и более размерностей наглядной\nвизуализации нет, так как там разделять данные будет гиперплоскость.",[43,1140,1142],{"id":1141},"переобучение-и-что-с-ним-делать","Переобучение и что с ним делать",[13,1144,1145],{},"Пока мы строили дерево до тех пор, пока все объекты не будут правильно\nклассифицированы. На первый взгляд кажется, что такой вариант\nединственно правильный, ведь нам не нужно допускать ошибки. Однако это\nтолько на первый взгляд. Перфекционизм в машинном обучении чаще вредит,\nчем помогает.",[13,1147,1148],{},"Вернемся к примеру с яблоками и грушами и представим, что к нам в\nобучающую выборку попалось дефектное вытянутое яблоко. И дерево решений,\nесли оставить все как есть, будет строить ветви, чтобы точно\nклассифицировать этот объект как яблоко, хотя вокруг будут одни груши. В\nитоге, когда мы будем делать классификацию с помощью этого дерева, есть\nриск, что нормальная груша будет классифицирована как яблоко.",[13,1150,1151],{},[189,1152],{"alt":1153,"src":1154},"Переобучение для двух размерностей","/img/blog/ml-basic-3/image16.png",[13,1156,1157],{},"Что с этим делать? Нужно заставить дерево не реагировать на единичные\nстранные примеры. Есть несколько способов это сделать:",[1039,1159,1160,1163,1166],{},[20,1161,1162],{},"Ограничить глубину дерева. Например, мы можем сделать не более трех\nразделений. После трех разделений крайние узлы считаются листьями.",[20,1164,1165],{},"Ограничить минимальное количество данных в листе. Например, если в\nузле четыре или менее объектов, этот узел автоматически считается\nлистом и больше не делится",[20,1167,1168],{},"Ограничить само число листов. Если лимит исчерпан, новые разделения\nне происходят, а все крайние узлы считаются листьями.",[13,1170,1171],{},"Каждый из этих способов может помочь бороться с переобучением. Но\nуниверсального рецепта нет. Обычно применяют комбинацию из методов, а\nпараметры подбирают экспериментально.",[13,1173,1174],{},"Для таких экспериментов (причем не только для решающих деревьев, а и для\nмногих других моделей машинного обучения) очень полезно наличие тестовой\nвыборки. Что это такое? Мы до начала обучения выделяем 10-20 процентов\nданных как тестовые. И дальше в процессе обучения их не используем. Это\nочень важный момент, тестовые данные ни в коем случае не должны быть\nвидны модели в процессе обучения.",[13,1176,1177],{},"Когда обучение закончено, мы прогоняем через модель эти тестовые данные\nи смотрим, насколько хорошо она с ними работает. Если на тренировочных\nданных все очень хорошо, а на тестовых плохо, скорее всего это как раз\nпереобучение и нужно принимать меры. Обычно стараются, чтобы процент\nправильных ответов на тренировочной и тестовой выборках был примерно\nодинаковым.",[1179,1180,1182,1202,1226,1339,1352,1365,1378,1391],"faq",{"title":1181},"Вопросы и ответы",[1183,1184,1186,1193],"faq-item",{"value":1185},"item-1",[1187,1188,1190],"template",{"v-slot:question":1189},"",[13,1191,1192],{},"Чем классификация отличается от регрессии?",[1187,1194,1195],{"v-slot:answer":1189},[13,1196,1197,1198,1201],{},"В регрессии модель предсказывает непрерывное число из произвольного\nдиапазона (например, точный вес в килограммах). В классификации модель\nвыбирает один из заранее заданных вариантов — ",[117,1199,1200],{},"классов",". Если классов\nвсего два, это бинарная классификация (ответ «да» или «нет»).",[1183,1203,1205,1210],{"value":1204},"item-2",[1187,1206,1207],{"v-slot:question":1189},[13,1208,1209],{},"Что такое решающее дерево и из чего оно состоит?",[1187,1211,1212],{"v-slot:answer":1189},[13,1213,1214,1215,1217,1218,1221,1222,1225],{},"Это алгоритм, который представляет собой последовательность проверок.\nДерево состоит из трёх типов элементов: ",[117,1216,270],{}," — начальная точка,\nс которой начинается работа алгоритма; ",[117,1219,1220],{},"узлы"," — промежуточные точки,\nв которых происходит разделение данных на две части; ",[117,1223,1224],{},"листья"," — конечные\nточки, содержащие итоговый класс. Чтобы классифицировать новый объект,\nнужно пройти от корня по узлам, выполняя проверки, пока не дойдёшь до\nлиста.",[1183,1227,1229,1234],{"value":1228},"item-3",[1187,1230,1231],{"v-slot:question":1189},[13,1232,1233],{},"Зачем нужен критерий Джини и что он показывает?",[1187,1235,1236],{"v-slot:answer":1189},[13,1237,1238,1239,1282,1283,534,1301,1319,1320,1338],{},"Критерий Джини показывает, насколько «чистым» получилось разделение\nданных в узле. Он считается по формуле\n",[51,1240,1242],{"className":1241},[54],[56,1243,1244],{"xmlns":58},[60,1245,1246,1279],{},[63,1247,1248,1250,1252,1254,1256,1259,1267,1269,1277],{},[66,1249,451],{},[91,1251,474],{},[476,1253,393],{},[91,1255,480],{},[91,1257,485],{"stretchy":1258},"false",[487,1260,1261,1263,1265],{},[66,1262,13],{},[476,1264,493],{},[476,1266,404],{},[91,1268,498],{},[487,1270,1271,1273,1275],{},[66,1272,13],{},[476,1274,393],{},[476,1276,404],{},[91,1278,509],{"stretchy":1258},[70,1280,1281],{"encoding":72},"G = 1 - (p_0^2 + p_1^2)",", где ",[51,1284,1286],{"className":1285},[54],[56,1287,1288],{"xmlns":58},[60,1289,1290,1298],{},[63,1291,1292],{},[323,1293,1294,1296],{},[66,1295,13],{},[476,1297,493],{},[70,1299,1300],{"encoding":72},"p_0",[51,1302,1304],{"className":1303},[54],[56,1305,1306],{"xmlns":58},[60,1307,1308,1316],{},[63,1309,1310],{},[323,1311,1312,1314],{},[66,1313,13],{},[476,1315,393],{},[70,1317,1318],{"encoding":72},"p_1"," — доли классов 0 и 1\nсреди объектов. Чем меньше значение, тем лучше разделение: ",[51,1321,1323],{"className":1322},[54],[56,1324,1325],{"xmlns":58},[60,1326,1327,1335],{},[63,1328,1329,1331,1333],{},[66,1330,451],{},[91,1332,474],{},[476,1334,493],{},[70,1336,1337],{"encoding":72},"G = 0","\nозначает, что все объекты по одну сторону принадлежат одному классу.",[1183,1340,1342,1347],{"value":1341},"item-4",[1187,1343,1344],{"v-slot:question":1189},[13,1345,1346],{},"Почему нельзя просто выбирать разделение с максимальным числом правильных\nответов?",[1187,1348,1349],{"v-slot:answer":1189},[13,1350,1351],{},"Такой подход называется жадным алгоритмом — он оптимизирует только\nтекущий шаг, не учитывая последующие. Лучшее разделение на первом этапе\nможет привести к плохому качеству на следующих. Поэтому используется\nвзвешенная сумма критериев Джини: она учитывает не только «чистоту»\nразделения, но и количество объектов с каждой стороны.",[1183,1353,1355,1360],{"value":1354},"item-5",[1187,1356,1357],{"v-slot:question":1189},[13,1358,1359],{},"Как решающее дерево работает с данными, у которых больше одного признака?",[1187,1361,1362],{"v-slot:answer":1189},[13,1363,1364],{},"Алгоритм почти не меняется. Единственное отличие: на каждом шаге нужно\nне только выбрать точку разделения, но и определить, по какому признаку\nделить. Для двух признаков разделение выглядит как вертикальная или\nгоризонтальная линия на графике. Для трёх — это плоскость, а для\nбольшего числа — гиперплоскость. Кандидаты перебираются по всем\nпризнакам, и выбирается лучший вариант.",[1183,1366,1368,1373],{"value":1367},"item-6",[1187,1369,1370],{"v-slot:question":1189},[13,1371,1372],{},"Что такое переобучение и почему оно опасно?",[1187,1374,1375],{"v-slot:answer":1189},[13,1376,1377],{},"Переобучение возникает, когда модель слишком сильно подстраивается под\nобучающие данные, включая шум и выбросы. Например, если в обучающей\nвыборке попадётся нетипичный объект, дерево создаст отдельные ветки\nдля его классификации. В итоге на новых данных модель будет ошибаться,\nпотому что выучила особенности конкретной выборки, а не общую\nзакономерность.",[1183,1379,1381,1386],{"value":1380},"item-7",[1187,1382,1383],{"v-slot:question":1189},[13,1384,1385],{},"Какие есть способы борьбы с переобучением в решающих деревьях?",[1187,1387,1388],{"v-slot:answer":1189},[13,1389,1390],{},"Основные подходы: ограничение глубины дерева (максимальное число\nразделений), ограничение минимального числа объектов в листе (узел\nс малым числом элементов не делится дальше) и ограничение общего числа\nлистьев. На практике обычно комбинируют несколько способов, а параметры\nподбирают экспериментально с помощью тестовой выборки.",[1183,1392,1394,1399],{"value":1393},"item-8",[1187,1395,1396],{"v-slot:question":1189},[13,1397,1398],{},"Зачем нужна тестовая выборка?",[1187,1400,1401],{"v-slot:answer":1189},[13,1402,1403],{},"Тестовая выборка — это часть данных (обычно 10–20%), которую модель не\nвидит в процессе обучения. После обучения мы проверяем качество модели\nна этих данных. Если на тренировочных данных модель работает хорошо, а\nна тестовых — плохо, это признак переобучения. В идеале качество на\nобеих выборках должно быть примерно одинаковым.",{"title":1189,"searchDepth":1405,"depth":1405,"links":1406},2,[1407,1408,1409,1410,1411],{"id":45,"depth":1405,"text":46},{"id":147,"depth":1405,"text":148},{"id":225,"depth":1405,"text":226},{"id":1061,"depth":1405,"text":1062},{"id":1141,"depth":1405,"text":1142},"mdx",{"readTime":1414,"image":1415,"date":1416,"tags":1417,"authors":1420},"13 минут","/img/blog/ml-basic-3/preview.png","2026-05-15",[1418,1419],"Искусственный интеллект","Машинное обучение",[1421],"vgorash",true,{"title":1424,"description":1425},"О чем думают деревья?","В этой статье мы начнем разбираться в задаче классификации. И первым алгоритмом будет самый интуитивно понятный, а именно - решающие деревья.","ru/blog/ml-basic-3","Iw8ib4qfFNmfZ8oL1fyJ4oMckl32BScdLws5oiq3bZg",1780489445263]