Text
                    Editor’s choice —
выбор главного редактора
Разговоры о Big Data идут уже давно, есть и книги на эту тему.
Но в общем и целом все они были о том, что Big Data — «круто»,
этим занимаются ведущие компании мира, а вот и кейсы от этих
компаний.
Теперь же у нас есть книга, которая показывает, как работать с Big
Data практически, причем без сложных программ, на обычном Excel.
Изучив ряд несложных приемов, руководители малого и среднего
бизнеса смогут находить в массивах своих данных неочевидные
зависимости, которые позволят получить серьезное конкурентное
преимущество.
Знания — это сила, а знания, полученные из больших данных, —
большая сила.

Сергей Турко,
главный редактор издательства
«Альпина Паблишер»


Data Smart Using Data Science to Transform Information into Insight John W. Foreman
Много цифр Анализ больших данных при помощи Excel Джон Форман Перевод с английского Москва 2016
УДК 330.47 ББК 65.051.03 Ф79 Переводчик А. Соколова Редактор Л. Мамедова Ф79 Форман Дж. Много цифр: Анализ больших данных при помощи Excel / Джон Форман ; Пер. с англ. А. Соколовой. — М. : Альпина Паблишер, 2016. — 461 с. ISBN 978-5-9614-5032-3 Казалось бы, термин «большие данные» понятен и доступен только специалистам. Но автор этой книги доказывает, что анализ данных можно организовать и в простом, понятном, очень эффективном и знакомом многим Excel. Причем не важно, сколько велик ваш массив данных. Техники, предложенные в этой книге, будут полезны и владельцу небольшого интернет-магазина, и аналитику крупной торговой компании. Вы перестанете бояться больших данных, научитесь видеть в них нужную вам информацию и сможете проанализировать предпочтения ваших клиентов и предложить им новые продукты, оптимизировать денежные потоки и складские запасы, другими словами, повысите эффективность работы вашей организации. Книга будет интересна маркетологам, бизнес-аналитикам и руководителям разных уровней, которым важно владеть статистикой для прогнозирования и планирования будущей деятельности компаний. УДК 330.47 ББК 65.051.03 Все права защищены. Никакая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами, включая размещение в сети Интернет и в корпоративных сетях, а также запись в память ЭВМ для частного или публичного использования без письменного разрешения владельца авторских прав. По вопросу организации доступа к электронной библиотеке издательства обращайтесь по адресу mylib@alpina.ru ISBN 978-5-9614-5032-3 (рус.) ISBN 978-1-118-66146-8 (англ.) © John Wiley & Sons, Inc., Indianapolis, Indiana, 2014 All Rights Reserved. This translation published under license with the original publisher John Wiley & Sons, Inc. © Издание на русском языке, перевод, оформление. ООО «Альпина Паблишер», 2016 © Фотография на обложке. Jason Travis / Courtesy of John W. Foreman
Содержание Введение ........................................................................................................................................ 11 1 Все, что вы жаждали знать об электронных таблицах, но боялись спросить ..................................................................................................... 21 Немного данных для примера..................................................................................... 22 Быстрый просмотр с помощью кнопок управления ............................................... 23 Быстрое копирование формул и данных .................................................................. 24 Форматирование ячеек................................................................................................ 25 Специальная вставка .................................................................................................... 27 Вставка диаграмм ......................................................................................................... 28 Расположение меню поиска и замены ...................................................................... 29 Формулы поиска и вывода величины ........................................................................ 30 Использование VLOOKUP/ВПР для объединения данных ...................................... 32 Фильтрация и сортировка ........................................................................................... 33 Использование сводных таблиц ................................................................................. 37 Использование формул массива ................................................................................ 40 Решение задач с помощью «Поиска решения»........................................................ 41 OpenSolver: хотелось бы обойтись без него, но это невозможно......................... 46 Подытожим .................................................................................................................... 47 2 Кластерный анализ, часть I: использование метода k-средних для сегментирования вашей клиентской базы ................................................... 49 Девочки танцуют с девочками, парни чешут в затылке.......................................... 51 Реальная жизнь: кластеризация методом k-средних в электронном маркетинге .......................................................................................... 56 Оптовая Винная Империя Джоуи Бэг О'Донатса ........................................................ 56 Исходный набор данных ............................................................................................ 57 Определяем предмет измерений ............................................................................... 58
6 Много цифр Начнем с четырех кластеров ...................................................................................... 61 Евклидово расстояние: измерение расстояний напрямик ......................................... 62 Расстояния и принадлежность к кластеру для всех! .................................................. 65 Поиск решений для кластерных центров ................................................................... 67 Смысл полученных результатов ................................................................................. 70 Рейтинг сделок кластерным методом ........................................................................ 71 Силуэт: хороший способ позволить разным значениям k посостязаться .................. 75 Как насчет пяти кластеров?........................................................................................ 82 Поиск решения для пяти кластеров ........................................................................... 83 Рейтинг сделок для всех пяти кластеров.................................................................... 84 Вычисление силуэта кластеризации по пяти средним ............................................... 87 K-медианная кластеризация и асимметрическое измерение расстояний........... 89 Использование k-медианной кластеризации ............................................................. 89 Переходим к соответствующему измерению расстояний.......................................... 90 А теперь все то же самое, но в Excel .......................................................................... 92 Рейтинг сделок для 5-медианных кластеров .............................................................. 94 Подытожим .................................................................................................................... 98 3 Наивный байесовский классификатор и неописуемая легкость бытия идиотом ............................................................. 101 Называя продукт Mandrill, ждите помех вместе с сигналами .............................. 101 Самое быстрое в мире введение в теорию вероятности ..................................... 104 Суммируем условную вероятность .......................................................................... 104 Совместная вероятность, цепное правило и независимость ................................... 105 Что же с зависимыми событиями? ........................................................................... 106 Правило Байеса ....................................................................................................... 107 Использование правила Байеса для создания моделирования .......................... 108 Высококлассные вероятности часто считаются равными........................................ 110 Еще немного деталей классификатора .................................................................... 111 Да начнется Excel-вечеринка! ................................................................................... 113 Убираем лишнюю пунктуацию ................................................................................. 113 Разное о пробелах ................................................................................................... 114 Подсчет жетонов и вычисление вероятностей......................................................... 118 У нас есть модель! Воспользуемся ею ..................................................................... 121 Подытожим .................................................................................................................. 127 4 Оптимизационное моделирование: этот «свежевыжатый апельсиновый сок» не смешает себя сам ................ 129 Зачем ученым, работающим с данными, нужна оптимизация? .......................... 130 Начнем с простого компромисса ............................................................................. 131 Представим проблему в виде политопа ................................................................... 132
Содержание Решение путем сдвигания линии уровня функции ................................................... 134 Симплекс-метод: все по углам ................................................................................. 135 Работа в Excel ........................................................................................................... 137 Монстр в конце главы .............................................................................................. 147 Свежий, из сада — прямо в стакан… с небольшой остановкой на модель смешивания................................................. 148 Вы используете модель для смешивания ................................................................. 149 Начнем с характеристик ........................................................................................... 150 Возвращаемся к консистенции ................................................................................ 151 Вводим данные в Excel ............................................................................................. 152 Постановка задачи «Поиску решения» ..................................................................... 155 Снижаем стандарты ................................................................................................. 158 Удаление дохлых белок: правило минимакс ............................................................ 161 «Если… то» и ограничение «Большого М» ................................................................ 164 Еще больше переменных: добьем до 11 .................................................................. 167 Моделируем риски ..................................................................................................... 175 Нормальное распределение данных ........................................................................ 176 Подытожим .................................................................................................................. 184 5 Кластерный анализ, часть II: сетевые графы и определение сообществ.... 187 Что такое сетевой граф? ............................................................................................ 188 Визуализируем простой граф ................................................................................... 189 Краткое введение в Gephi.......................................................................................... 192 Установка Gephi и подготовка файлов ..................................................................... 192 Визуализация графа ................................................................................................. 194 Степень вершины ..................................................................................................... 197 Приятная картинка ................................................................................................... 200 Прикосновение к данным графа .............................................................................. 200 Строим граф из данных об оптовой торговле вином ........................................... 202 Создание матрицы близости косинусов................................................................... 204 Построение графа N-соседства ............................................................................... 207 Числовое значение ребра: очки и штрафные в модулярности графа ................ 212 Кто же такие «очки» и «штрафные»? ........................................................................ 212 Подготовка к итоговому подсчету ............................................................................ 216 Переходим к кластеризации! .................................................................................... 219 Деление 1 ................................................................................................................. 219 Деление 2: электролатино! ....................................................................................... 225 И… деление 3: возмездие ......................................................................................... 227 Кодируем и анализируем группы ............................................................................. 228 Туда и обратно: история Gephi ................................................................................. 233 Подытожим .................................................................................................................. 238 7
8 Много цифр 6 Бабушка контролируемого искусственного интеллекта — регрессия ..... 241 Погоди, ты что — беременна? ................................................................................... 241 Не обольщайтесь! ....................................................................................................... 242 Определение беременных покупателей РитейлМарта с помощью линейной регрессии.............................................................................. 243 Набор отличительных признаков ............................................................................. 244 Сборка обучающих данных ...................................................................................... 245 Создание фиктивных переменных............................................................................ 247 Мы сделаем свою собственную линейную регрессию! ........................................... 250 Статистика линейной регрессии: R-квадрат, критерии Фишера и Стьюдента ......... 259 Делаем прогнозы на основании новых данных и измеряем результат .................... 270 Предсказание беременных покупателей РитейлМарта с помощью логистической регрессии ..................................................................... 281 Первое, что нам нужно — это функция связи ........................................................... 281 Присоединение логистической функции и реоптимизация ..................................... 282 Создание настоящей логистической регрессии....................................................... 286 Выбор модели: сравнение работы линейной и логистической регрессий............... 287 Дополнительная информация .................................................................................. 291 Подытожим .................................................................................................................. 292 7 Комплексные модели: огромная куча ужасной пиццы ................................. 293 Используем данные из главы 6 ................................................................................. 294 Бэггинг: перемешать, обучить, повторить ............................................................... 296 Одноуровневое дерево решений — неудачное название «неумного» определителя ........................................................ 296 А мне не кажется, что это глупо! .............................................................................. 297 Нужно еще сильнее! ................................................................................................... 300 Обучим же ее! .......................................................................................................... 300 Оценка бэггинговой модели ..................................................................................... 310 Бустинг: если сразу не получилось, бустингуйте и пробуйте снова .................................................................................. 315 Обучаем модель: каждому признаку — шанс ........................................................... 315 Оценка модели бустинга .......................................................................................... 324 Подытожим .................................................................................................................. 327 8 Прогнозирование: дышите ровно, выиграть невозможно ........................... 329 Торговля мечами начата ............................................................................................ 330 Знакомство с временной последовательностью данных ..................................... 331 Медленный старт с простым экспоненциальным сглаживанием ........................ 333 Настраиваем прогноз простого экспоненциального сглаживания........................... 335
Содержание Возможно, у вас есть тренд ...................................................................................... 341 Экспоненциальное сглаживание Холта с корректировкой тренда ..................... 344 Настройка холтовского сглаживания с коррекцией тренда в электронной таблице ... 346 Мультипликативное экспоненциальное сглаживание Холта–Винтерса ............. 360 Установка исходных значений уровня, тренда и сезонности ................................... 362 Приступим к прогнозу .............................................................................................. 367 И наконец… оптимизация!........................................................................................ 372 Пожалуйста, скажите, что это все!!! ......................................................................... 373 Создаем интервал прогнозирования вокруг прогноза ............................................. 374 И диаграмма с областями для пущего эффекта ....................................................... 378 Подытожим .................................................................................................................. 381 9 Определение выбросов: выделяющиеся не значит важные ....................... 383 Выбросы тоже (плохие?) люди! ................................................................................ 384 Захватывающее дело Хадлум против Хадлум ........................................................ 384 Границы Тьюки ......................................................................................................... 386 Применение границ Тьюки в таблице ...................................................................... 386 Ограничения этого нехитрого метода ...................................................................... 388 Ни в чем не ужасен, плох во всем ............................................................................ 390 Подготовка данных к отображению на графе.......................................................... 391 Создаем граф ........................................................................................................... 394 Вычисляем k ближайших соседей ............................................................................ 397 Определение выбросов на графе, метод 1: полустепень захода.............................. 398 Определение выбросов на графе, метод 2: нюансы k-расстояния .......................... 401 Определение выбросов на графе, метод 3: факторы локальных выбросов — это то, что надо ........................................................................................................ 403 Подытожим .................................................................................................................. 409 10 Переходим от таблиц к программированию ..................................................... 411 Налаживаем контакт с R ............................................................................................ 412 Пошевелим пальцами .............................................................................................. 413 Чтение данных в R .................................................................................................... 421 Настоящая научная работа с данными ................................................................... 423 Сферическое k-среднее винных данных в нескольких линиях ................................. 423 Построение моделей ИИ для данных о беременных ................................................ 430 Прогнозирование в R ............................................................................................... 439 Определение выбросов............................................................................................ 443 Подытожим .................................................................................................................. 448 Заключение ................................................................................................................................. 451 Благодарности ............................................................................................................................ 459 9
Моей жене Лидии. То, что ты делаешь каждый день — круто! Если бы не ты, я бы лишился волос (и ума) миллиард лет назад
Введение Что я здесь делаю? Наверняка где-нибудь в прессе, финансовой литературе и журналах или на конференции вы слышали что-то об обработке данных, их представлении и анализе — том, что составляет «науку о данных». Эта наука может предсказать результаты выборов, рассказать о ваших покупательских привычках больше, чем вы осмелились бы поведать маме, и определить, на сколько лет сокращают вашу жизнь сырные буррито с чили. В последнее время вокруг науки о данных наблюдается некоторый ажиотаж, который начинает оказывать давление на многие виды бизнеса. Не занимаясь анализом данных, вы рискуете потерпеть неудачу в конкурентной борьбе. Обязательно появится кто-нибудь, разработавший очередной новый продукт под названием «Что-то-про-графы-и-большие-данные», — и уничтожит ваш бизнес. Сделайте глубокий вдох. Не все так мрачно! Вас, несомненно, спасет то, что большинство тех, кто считает себя «доками» в науке о данных, делают все ровно наоборот. Они начинают с покупки программ и нанимают консультантов. Они тратят все свои деньги еще до того, как поймут, чего же они на самом деле хотят. Заказав программные инструменты, они считают, что сделали главное и можно расслабиться. Прочитав эту книгу, вы будете на голову выше этих «специалистов». Вы будете иметь точное представление о том, что такое техники анализа данных и как они используются. И когда придет время планировать, нанимать и покупать, вы уже будете знать, как применить возможности науки о данных с пользой именно для вашей конкретной компании. Цель этой книги — введение в практическую науку о данных в комфортном режиме беседы. Надеюсь, что по окончании чтения священный ужас перед этим таинственным «зверем» — данными — сменится энтузиазмом и мыслями о том, как с их помощью поднять свой бизнес на новый уровень.
12 Много цифр Рабочее определение науки о данных В некоторой степени наука о данных — синоним таких терминов, как бизнес-аналитика; исследование операций; бизнес-интеллект; промышленный шпионаж; анализ, моделирование и раскрытие данных (также называемое обнаружением знаний в базах данных, или ОЗБД). Иными словами, нынешняя наука о данных — просто новый виток того, чем люди занимаются уже довольно долго. После расцвета вышеозначенных и других дисциплин произошел скачок в технологиях. Совершенствование аппаратной и программной платформ сделали легким и недорогим сбор и анализ больших объемов данных во всех областях — будь то продажи и маркетинг, запросы HTTP с вашего сайта или информация для поддержки клиентов. Малый бизнес и некоммерческие организации могут теперь привлекать аналитиков, содержание которых раньше могли себе позволить только большие корпорации. Конечно, из-за того, что наука о данных используется как всеобъемлющее ученое словечко для обозначения аналитики сегодня, она чаще всего ассоциируется с техниками добычи данных (data mining), такими как искусственный интеллект, кластерный анализ и определение выбросов. Благодаря подешевевшей аппаратной поддержке, обеспечившей резкий рост количества переменных бизнес-данных, эти вычислительные техники стали опорой бизнеса в последние годы, хотя раньше они были слишком громоздкими для использования на производстве. В этой книге я собираюсь дать широкий обзор всех разделов науки о данных. Вот определение, которое я буду использовать: Наука о данных — это трансформация данных методами математики и статистики в рабочие аналитические выводы, решения и продукты. Я определяю это понятие с точки зрения бизнеса. В нем упоминается применимый и полноценный готовый продукт, получаемый из данных. Почему? Потому что я занимаюсь этим не в исследовательских целях и не из любви к искусству. Я изучаю данные для того, чтобы помочь моей компании работать лучше и постоянно повышать свою эффективность; поскольку вы держите в руках мою книгу, подозреваю, что наши намерения схожи. Используя это определение, я собираюсь описать вам основные техники анализа данных, такие как оптимизация, прогнозирование и моделирование, а также затронуть наболевшие темы — искусственный интеллект, сетевые графы, кластерный анализ и определение выбросов.
Введение Одни из этих техник довоенные в буквальном смысле слова. Другие внедрены в течение последних 5 лет. Но вы увидите, что возраст не имеет никакого отношения к сложности или полезности. Все эти техники — независимо от степени популярности — одинаково полезны для бизнеса при правильном выборе. Вот почему вам нужно понимать, какая техника для решения какой проблемы подходит, как эти техники работают и как их моделировать. Довольно много людей имеют представление о сути одной или двух описанных мною техник — этим их знания и ограничиваются. Если бы у меня в ящике для инструментов был только молоток, наверное, я бы пытался решать все проблемы ударом посильнее. Совсем как мой двухлетний сын. Но поскольку мне не два года, я предпочитаю иметь еще какие-то инструменты в своем распоряжении. Но подождите, а как же большие данные? Наверняка вы слышали термин «большие данные» даже чаще, чем «наука о данных». О них ли эта книга? Ответ зависит от того, что понимать под большими данными. Если вы определяете большие данные как подсчет сводной статистики неструктурированного мусора, хранящегося в горизонтально масштабируемом NoSQL-массиве, то нет, это книга не о больших данных. Если вы определяете большие данные как превращение переменных данных в решения и аналитические выводы с помощью ультрасовременных методов анализа (независимо от того, где хранится информация), тогда да, моя книга о больших данных. В этой книге не рассматриваются системы управления базами данных, такие как MongoDB и Hbase. В ней не рассказывается о пакетах для разработчиков, таких как Mahout, Numpy, различных R-библиотеках и т. д. Для этого существуют другие книги. Я сделал так намеренно. Эта книга игнорирует инструменты, хранилища и код. Вместо этого она, по возможности, фокусируется на методах. Многие думают, что если смешать хранение и извлечение данных с щепоткой очистки и агрегации, получится коктейль «Все, что нужно знать о больших данных». Они ошибаются. Эта книга поможет вам беспрепятственно пробиться сквозь завесу многозначительной болтовни, которой нас окружают продавцы программного обеспечения для работы с большими данными и блогеры, и покажет вам, на что на самом деле способны ваши данные. Что примечательно, для большинства этих техник объем ваших данных может быть любым — крошечным или 13
14 Много цифр огромным. Вы не обязаны иметь петабайт данных и энную сумму с пятью нулями на предсказание интересов вашей огромной клиентской базы. Иметь массив данных — это, конечно, замечательно, однако есть бизнесы, прекрасно обходящиеся и без этого «сокровища», более того — никому не хочется их генерировать. Например, мяснику, торгующему в моем родном квартале. Но это не значит, что его бизнесу помешало бы небольшое кластерное разделение «бекон/колбаса». Если сравнивать книги с видами спорта, моя книга сравнима с гимнастикой. Никаких тренажеров и упражнений на выносливость. Поняв, как реализовывать техники с помощью базовых инструментов, вы обнаружите, что свободно можете применять их во многих технологиях, с легкостью моделировать их, правильно выбирать программные продукты у консультантов, формулировать задачи программистам и т. д. Кто я? Давайте прервемся ненадолго, и я расскажу вам о себе. Научный подход к изучению данных, который я проповедую, возник не вчера — к нему меня вел долгий путь. Много лет назад я был консультантом по менеджменту. Я работал над аналитическими проблемами таких организаций, как ФБР, министерство обороны США, компания Coca-Cola, группы отелей Intercontinental и Royal Carribbean. Из всего этого опыта я вынес одно: наука о данных должна стать прерогативой не только ученых. Я работал с менеджерами, которые покупали симуляции, когда им были нужны модели оптимизации. Я работал с аналитиками, которые понимали только графики Ганта *, так что абсолютно все приходилось представлять в виде этих графиков. Как консультанту, мне было нетрудно расположить к себе покупателя, имея в арсенале любые старые бумаги и миленькую презентацию в PowerPoint, потому что они не могли отличить искусственный интеллект от бизнес-анализа, а бизнес-анализ — от ВS. Цель этой книги — расширение аудитории, способной понять и применить техники научного анализа данных. Я не пытаюсь обратить вас, уважаемые читатели, в специалистов по научной обработке данных против вашей воли. Я просто хочу, чтобы вы научились применять науку о данных настолько, насколько сможете, в той области, в которой вы уже хорошо разбираетесь. Это заставляет задать вопрос: кто же вы? * Популярный тип столбчатых диаграмм (гистограмм), который используется для иллюстрации плана, графика работ по какому-либо проекту. Является одним из методов планирования проектов. — Прим. ред.
Введение Кто вы? Не пугайтесь, я не использовал научный анализ данных, чтобы шпионить за вами. Я понятия не имею, кто вы, но заранее благодарен вам за то, что раскошелились на эту книгу. Вот несколько архетипов (или личностей — для вас, маркетологи!), которые пришли мне на ум, когда я писал эту книгу. Возможно, вы: заместитель начальника по маркетингу и хотите использовать свои бизнес• переменные стратегическим образом, для оценки продукта и сегмента рынка, но не понимаете подходов, рекомендуемых разработчиками приложений и переоцененными консультантами; аналитик, предсказывающий спрос, который знает, что история заказов • фирмы содержит больше информации о клиентах, чем даже план на следующий квартал; руководитель розничного интернет-магазина, желающий угадать по дан• ным о предыдущих заказах, когда клиент скорее всего «созреет» для очередной покупки; бизнес-аналитик, который в состоянии просчитать растущие денежные • потоки и затраты на снабжение, но не знает, как перебросить мостик экономии на издержках; онлайн-маркетолог, который хочет чего-то большего для своей компании • от бесплатных текстовых сервисов, таких как электронные письма или социальные сети. Пока же судьба разосланных сообщений незавидна — их открывают и тут же выбрасывают в корзину. Иными словами, вы — читатель, который получает практическую пользу от дополнительной информации о научной обработке данных, но пока не нашел «свой конек» во всем многообразии техник. Цель этой книги — стряхнуть мишуру (код, инструменты и просто слухи) с науки о данных и обучить необходимым техникам на практических примерах, понятных любому, прошедшему курс линейной алгебры или вычислительной математики в институте. Если вы, конечно, их успешно сдали. Если нет — читайте медленно и не стесняйтесь пользоваться Википедией. 15
16 Много цифр Никаких сожалений — только электронные таблицы Эта книга не о программировании. Я даже готов гарантировать полное отсутствие (ну, по крайней мере, до главы 10) в ней кода. Почему? Да потому что я не хочу тратить первые сто страниц на возню с Git, объявлением переменных среды и выступление Emacs против Vi. Если вы пользуетесь исключительно Windows и Microsoft Office, работаете в государственной структуре и вам запрещено скачивать и устанавливать приложения из каких попало открытых источников и даже если MATLAB или ваш графический калькулятор наводили на вас леденящий ужас во времена студенчества, вам нечего бояться. Нужно ли вам знать, как пишется код, чтобы перевести большую часть этих техник в автоматизированную, производственную форму? Непременно! Вы или кто-то из ваших коллег должен знать технологии хранения данных и уметь управляться с кодом. Нужно ли вам знать, как пишется код, чтобы понимать, различать и моделировать эти техники? Совершенно ни к чему! Именно поэтому я объясняю каждую методику с помощью электронных таблиц. Ну, ладно, если по-хорошему, то я должен признаться, что все вышесказанное мною не совсем правда. Последняя глава этой книги — о переходе на язык программирования R, ориентированный на анализ данных. Она предназначена для тех из вас, кто захочет использовать эту книгу как трамплин к пониманию новых глубин аналитики. Но электронные таблицы так устарели! Электронные таблицы — не самый привлекательный инструмент из существующих. Электронные таблицы стоят немного особняком. Они позволяют вам видеть данные и взаимодействовать с ними (или, по крайней мере, кликать на них). Они создают определенную свободу для маневра. Во время изучения анализа данных вам понадобится инструмент — привычный, понятный каждому, позволяющий двигаться быстро и легко в процессе. Это и есть электронные таблицы. Давайте, наконец, скажем себе: «Я человек и обладаю чувством собственного достоинства. Я не должен делать вручную работу программного фреймворка, чтобы научиться анализировать данные».
Введение А еще электронные таблицы отлично подходят для прототипирования! Конечно, вы не запустите с их помощью производственную модель ИИ* для вашего интернет-магазина из программы Excel, но зато сможете понять характер заказов, спрогнозировать, какие продукты в будущем вызовут интерес потребителей, и разработать прототип модели для определения целевой аудитории. Используйте Excel или LibreOffice Все примеры, с которыми вам придется работать, отображаются в таблицах Excel. На сайте этой книги (www.wiley.com/go/datasmart) размещены электронные таблицы с открытым доступом для каждой главы, так что вы сможете следить за ходом повествования. Если вы по натуре склонны к риску, можете стереть оттуда все данные, кроме исходных, и сделать всю работу самостоятельно. Эта книга совместима с Excel версий 2007, 2010, 2011 для MacOS и 2013. В первой главе достаточно подробно рассматриваются различия между версиями. У большинства из вас есть доступ к Excel и вы наверняка уже применяете его в вашей работе для отчетности или хранения информации. Но если по какой-то причине этой программы у вас нет, вы можете ее либо купить, либо воспользоваться бесплатным аналогом от LibreOffice (www.libreoffice.org). А КАК ЖЕ GOOGLE DRIVE? Кто-то из вас наверняка спросит, можно ли при решении задач, которые нам предстоят, использовать Google Drive — облачный сервис, доступный с любого устройства, как почтовый ящик. Что и говорить, вариант заманчивый… К сожалению, он не будет работать. Google Drive отлично справляется с небольшими таблицами, но того, чем собираетесь заниматься вы, он просто не выдержит. Процесс добавления строк и колонок уже раздражает, реализация поиска решения просто ужасна, а у графиков даже нет линий тренда! Хотелось бы мне, чтобы было иначе, но увы… LibreOffice — открытый бесплатный ресурс, имеющий практически всю функциональность Excel. Я даже думаю, что его собственный поиск решений предпочтительнее, чем у Excel. Так что если вы не раздумали читать эту книгу — вперед! * Искусственный интеллект. — Прим. пер. 17
18 Много цифр Условные обозначения Чтобы помочь вам извлечь из текста максимальную пользу, я ввел в эту книгу несколько условных обозначений. ВСТАВКИ Вставки типа той, в которой вы только что прочитали про Google Drive, раскрывают «побочные» темы, упомянутые в тексте. ВНИМАНИЕ! Эти разделы содержат важную информацию, напрямую связанную с текстом, которую я рекомендую все время держать в уме. ЗАМЕТКИ Здесь вы найдете советы, подсказки, приемы и все в этом духе, что пришлось к слову в текущем обсуждении. Частенько я буду вставлять в текст небольшие кусочки кода Excel вроде этого: =CONCATENATE(“THIS IS A FORMULA”, “IN EXCEL!”)/ =СЦЕПИТЬ(“ЭТО ФОРМУЛА”, “В EXCEL!”) Мы выделяем курсивом новые термины и важные слова при первом упоминании. Названия файлов, веб-страниц и формул в тексте выглядят так: http://www.john-foreman.com. Итак, начнем В первой главе я намерен заполнить некоторые пробелы в ваших познаниях об Excel, после чего вы сможете погрузиться непосредственно в практику. К концу книги вы не только будете иметь представление о нижеперечисленных техниках, но и приобретете опыт их применения:
Введение оптимизация с использованием линейного и интегрального программи• рования; работа с временными рядами данных, определение трендов и изменений • сезонного характера, а также прогнозирование методом экспоненциального сглаживания; моделирование методом Монте-Карло в оптимизации и прогнозировании • сценариев для количественного выражения и адресации рисков; искусственный интеллект с использованием общей линейной модели, функ• ции логистических звеньев, ансамблевых методов и наивного байесовского классификатора; измерение расстояния между клиентами с помощью близости косинусов • угла, создание К-ближайших граф, расчет модулярности и кластеризация клиентов; определение выбросов в одном измерении по методу Тьюки или в несколь• ких измерениях с помощью локальных факторов выброса; применение пакетов R для использования результатов работы других про• граммистов при выполнении этих задач. Если хотя бы что-то из вышесказанного звучит для вас воодушевляюще — продолжайте чтение! Если пугающе — то тоже продолжайте! Я торжественно обещаю разжевывать все как можно тщательнее. Итак, без лишней суеты приступим! 19

1 Все, что вы жаждали знать об электронных таблицах, но боялись спросить В этой книге я исхожу из того, что вы уже имеете некоторое представление об электронных таблицах и пользуетесь ими. Если же вы никогда не сталкивались с расчетами по формулам, вам поначалу придется нелегко. Перед нашим совместным погружением в Excel с головой я бы рекомендовал проштудировать «Excel для чайников» или другую подобную литературу вводного уровня. Но даже если вы — заслуженный мастер по работе с Excel, все равно в моем тексте иногда будут возникать упоминания о таких возможностях программы, которыми вы никогда не пользовались. Так, в настоящей главе вы встретите много небольших приемов с простыми функциями. Некоторые наверняка покажутся вам немного странными. Не зацикливайтесь на непонятном — двигайтесь дальше. Вы всегда сможете вернуться к недочитанной главе позже. ОТЛИЧИЯ В РАЗНЫХ ВЕРСИЯХ EXCEL Как я уже упоминал во введении, для этой книги подходят Excel 2007, 2009, 2011 для MacOS и LibreOffice. К сожалению, в каждой новой версии Excel разработчики Microsoft перемещают инструменты и функционал как им угодно. Например, элементы из вкладки «Разметка» в версии 2011 года находятся во вкладке «Вид» во всех остальных версиях. «Поиск решения» в версиях 2010 и 2013 одинаковый, но реализован он лучше в 2007 и 2011, несмотря на гротескный интерфейс в версии 2007. Снимки с экрана в этой книге будут делаться с Excel 2011. Если у вас более новая или старая версия, вам придется действовать по-другому, особенно когда дело касается положения элементов управления во вкладках меню. Я очень постараюсь найти и учесть все различия. Если что-то мной упущено, поисковый инструмент Excel и Google всегда к вашим услугам. А вот то, что, несомненно, должно вас обрадовать: «табличная часть электронной таблицы» всегда неизменна.
22 Много цифр Несколько слов о LibreOffice. Если вы решили пользоваться открытыми источниками программного обеспечения, рискну предположить, что вы — человек, склонный до всего доходить самостоятельно. И хотя я не буду напрямую обращаться к интерфейсу LibreOffice, вы этого попросту не заметите. Они с Excel похожи как две капли воды. Немного данных для примера ЗАМЕТКА: Рабочая тетрадь Excel, используемая в этой главе «Concessions.xlsx», доступна для загрузки на сайте книги www.wiley.com/go/datasmart Представьте себе, что вам жутко не везет по жизни. Даже став взрослым, вы до сих пор живете с родителями и работаете в киоске на баскетбольных матчах в своей старой школе. (Клянусь, это только наполовину автобиографично!). У вас есть электронная таблица о вчерашних продажах, и выглядит она примерно как рис. 1-1. Рис. 1-1. Продажи киоска На рис. 1-1 показана каждая продажа: что именно продано, к какому типу еды или напитков относится проданный товар, цена и процент прибыли с продажи.
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Быстрый просмотр с помощью кнопок управления Если хотите ознакомиться с записями — промотайте список колесиком мышки, пальцем (если у вас сенсорный экран) или стрелками клавиатуры. Пока вы просматриваете записи, приятно иметь строку заголовков в поле зрения — тогда вы точно не забудете, что в какой колонке записано. Для этого выберите «Закрепить области» или «Закрепить верхнюю строку» во вкладке «Вид» в Windows (вкладка «Разметка» в MacOS2011, как показано на рис. 1-2). Рис. 1-2. Закрепление верхней строки. Чтобы быстро переместиться в конец документа и посмотреть, сколько всего у вас продаж, выберите значение в одном из заполненных столбцов и нажмите Ctrl+ (Command+ на Mac). Вас отбросит прямо к последней заполненной ячейке этого столбца. В этой таблице последняя строка — 200. Заметьте также, что кнопка Ctrl/Command со стрелками даст вам возможность точно так же перемещаться по всему документу, в том числе вправо и влево. Если вы хотите узнать среднюю прибыль за единицу проданного за вечер, то под столбцом с ценами (столбцом С) можно вбить формулу: =AVERAGE(C2:C200)/ =СРЗНАЧ(С2:С200) 23
24 Много цифр Средняя прибыль получается $2,83, так что отдыхать от трудов праведных вам, увы, еще не время. Подсчет можно произвести и другим способом: переместиться на последнюю ячейку в столбце, С200 и удерживать Shift+Ctrl+ , чтобы выделить весь столбец доверху, а затем выбрать «Среднее значение» на нижней панели справа (рис. 1-3). В Windows нужно кликнуть на этой панели для того, чтобы выбрать среднее значение, скажем, вместо суммы, стоящей там по умолчанию. В MacOS, если нижняя панель отключена, нужно нажать на меню «Вид» и выбрать «Строку состояния», чтобы включить ее. Рис. 1-3. Среднее значение колонки с ценами на панели состояния Быстрое копирование формул и данных Пожелав видеть свою прибыль в фактических долларах, а не в процентах, вы можете добавить что-то вроде заголовка в столбец Е, который назовем «Фактическая прибыль». В ячейке Е2 нужно просто перемножить соответствующие значения из столбцов с ценой и прибылью, чтобы получить такую формулу: =C2*D2 Для строки с пивом результат будет равным $2. Не нужно переписывать формулу для каждой строки. Excel позволяет переносить формулы из ячейки перетаскиванием за правый нижний угол куда вам угодно. Значения в столбцах С и D будут меняться в зависимости от того, куда скопирована формула. Если, как в случае с данными о продажах, столбец слева полностью заполнен,
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить дважды кликните на правом нижнем углу ячейки с формулой, и Excel заполнит значениями весь столбец, как это показано на рис. 1-4. Попробуйте этот двойной клик сами, потому что я буду использовать его во всей книге. Освоив его сейчас, вы избавите себя от огромных неудобств в будущем. Обязательно ли значение в ячейках, упомянутых в формуле, должно меняться в зависимости от того, куда вы ее перетаскиваете или копируете? Нет, конечно. Хотите оставить что-то неизменным — просто поставьте перед ним $. К примеру, если вы измените формулу в Е2 таким образом: =C$2×D$2 Рис. 1-4. Заполнение столбца по формуле растягиванием ее за угол В этом случае при копировании формулы на все последующие ячейки в ней ничего не меняется. Формула продолжает обращаться ко 2-й строке. Если скопировать формулу вправо, то С заменится на D, D на Е и т. д. Если вам не нравится такое «поведение», добавьте $ также перед ссылками на столбцы в формуле. Это называется абсолютной ссылкой, в противоположность относительной ссылке. Форматирование ячеек Excel предлагает статические и динамические опции для форматирования содержимого ячеек. Взгляните на столбец Е с фактической прибылью, который вы только что создали. Выделите его, кликнув на серый заголовок колонки. Затем кликните на выбранном столбце правой клавишей и выберите «Формат ячеек». 25
26 Много цифр В этом меню вы можете выбрать формат содержимого ячеек столбца Е. В нашем случае нужен денежный формат. Также можно указать число знаков после запятой при округлении. Оставьте 2 знака после запятой, как показано на рис. 1-5. Также в меню «Формат ячеек» доступны такие опции, как цвет шрифта, заливка ячейки, выравнивание текста, границы и т. д. Рис. 1-5. Меню «Формат ячеек» Но есть нюанс. Допустим, нужно отформатировать только те ячейки, которые содержат определенные значения или диапазон значений, и это форматирование должно меняться в зависимости от значений. Такой вид форматирования называется условным форматированием, и оно повсеместно используется в этой книге. Закройте меню «Формат ячеек» и переместитесь во вкладку «Главная». В разделе «Стили» («Формат» в MacOS) вы найдете «Условное форматирование»
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить (рис. 1-6). При нажатии на него выпадает меню. Самое используемое условное форматирование в этой книге — цветовые шкалы. Выберите шкалу для столбца Е и посмотрите, как изменился цвет каждой ячейки в зависимости от величины значения в ней. Рис. 1-6. Применение условного форматирования к столбцу с прибылью Чтобы очистить условное форматирование, используйте опцию «Удалить правила» меню условного форматирования. Специальная вставка Конечно, гораздо удобнее работать, если формулы не путаются у вас под рукой, как в колонке Е на рис. 1-4. А если это еще и формулы вроде RAND( )/СЛЧИС( ), генерирующей случайные числа, которые меняют свое значение при каждом автопересчете таблицы, то ваше раздражение вполне справедливо. Решение проблемы — в копировании этих ячеек и вставке их обратно в таблицу в виде постоянных величин. Чтобы перевести формулы в цифры, просто выделите и скопируйте столбец Е, заполненный формулами, и вставьте его обратно с помощью опции «Специальная вставка» (находится во вкладке «Главная» под опцией «Вставить» в Windows 27
28 Много цифр и в меню «Редактировать» в MacOS). В окне «Специальная вставка» выберите вставку в качестве значений (рис. 1-7). Замечу, что это меню при вставке позволяет также транспонировать данные из вертикали в горизонталь и наоборот. Это свойство очень пригодится вам в дальнейшем. Рис. 1-7. Окно «Специальная вставка» в Excel 2011 Вставка диаграмм Методичка, посвященная торговле с лотка, включает в себя графу «Калории» с малюсенькой табличкой. В ней указано, сколько калорий содержится в каждом напитке или закуске, которые продаются в киоске. Вы тоже легко можете сделать такую диаграмму в Excel. Во вкладке «Вставка» («Диаграммы» в MacOS) есть раздел, в котором находятся различные варианты отображения, такие как столбчатая гистограмма, линейный график и круговая диаграмма. ЗАМЕТКА В этой книге мы в основном будем пользоваться столбчатыми гистограммами, линейными графиками и графиками рассеяния. Никогда не пользуйтесь круговыми диаграммами! И особенно круговыми 3D-диаграммами, которые вам предлагает Excel. Не вздумайте ослушаться, иначе мой призрак будет мучить вас после моей смерти! Круговые диаграммы уродливы, плохо соотносятся с данными, эстетически их 3D-эффект примерно таков же, как у картинок из ракушек на стене кабинета моего стоматолога.
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Выделяя столбцы А и В в листе «Calories» вы можете выбрать столбчатую диаграмму с группировкой для отображения данных. Поиграйте с графикой. Нажимайте на разделы правой клавишей мыши, чтобы увидеть меню форматирования. Например, щелчок правой клавиши на столбцах диаграммы вызовет меню, в котором можно выбрать «Формат рядов данных». Под ним вы сможете поменять цвет столбцов с синего по умолчанию на любой оттенок, который вам по вкусу, например черный. В наличии легенды по умолчанию тоже нет никакого смысла, так что советую выделить ее и нажать «Удалить». Также вам может понадобиться выделить разные текстовые подписи к диаграмме и увеличить размер шрифта (размер шрифта находится под вкладкой «Главная»). Таким образом получается диаграмма, показанная на рис. 1-8. Рис. 1-8. Вставка диаграммы содержания калорий Расположение меню поиска и замены В этой книге вам частенько придется пользоваться функциями поиска и замены. В Windows это делается, как обычно, нажатием Ctrl+F для открытия окна поиска (и Ctrl+H для замены) или перемещением во вкладку «Главная», где в разделе «Правка» находится кнопка «Найти». В MacOS строка поиска расположена в верхнем правом углу листа (для замены нажмите либо стрелку вниз, либо Cmd+F для вызова меню поиска и замены). 29
30 Много цифр Чтобы проверить прочитанное на практике, откройте меню замены на листе «Calories». Замените слово «Калории» на слово «Энергия» везде, где оно встречается (рис. 1-9), вбив эти слова в окно поиска и замены и нажав «Заменить все». Рис. 1-9. Поиск и замена Формулы поиска и вывода величины Если бы я не уточнил, что вам знакомы хотя бы некоторые простые формулы Excel (SUM, MAX, MIN, PERCENTILE / СУММ, МАКС, МИН, ПЕРСЕНТИЛЬ и т. д.), мы бы просидели здесь целый день. А я хочу начать анализировать данные. Вместе с тем я часто использую в этой книге формулы, с которыми вы могли ни разу не столкнуться, если до этого не погружались с головой в волшебный мир электронных таблиц. Эти формулы работают с поиском значения в ряду и выводом его положения или, наоборот, поиском положения в ряду и возвратом значения. Я покажу это на примере листа «Calories». Иногда хочется узнать положение элемента в столбце или строке. Первый он, второй или третий? Формула MATCH/ПОИСКПОЗ справляется с этим довольно неплохо. Под вашими данными о калориях назовите А18 Match/Поискпоз. Вы можете применить формулу к ячейке В18, чтобы найти, где в списке выше упоминается слово «Hamburger». Чтобы использовать эту формулу, необходимо указать в ней значение, которое нужно найти, границы поиска и 0, чтобы она вывела позицию самого слова: =MATCH("Hamburger", A2:A15,0) / =ПОИСКПОЗ("Hamburger", A2:A15,0) Она выдает 6, так как «Hamburger» — шестая позиция в списке (рис. 1-10).
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Рис. 1-10. Формулы, которые нужно знать Следующая формула — INDEX / ИНДЕКС. Назовите ячейку А19 Index/Индекс. Эта формула находит значение элемента по заданному положению в строке или столбце. Например, подставив в нее из нашей таблицы калорий А1:В15 и задав координаты поиска «3 строка, 2 столбец», мы получим количество калорий в бутылке воды: =INDEX(A1:B15,3,2) / =ИНДЕКС(A1:B15,3,2) Мы видим количество калорий, равное 0, как и предполагалось (рис. 1-10). Другая формула, которая часто встречается в нашем тексте, — это OFFSET/ СМЕЩ. Назовем же ячейку А20 Offset/Смещ и поиграем с формулой в В20. С помощью этой формулы вы задаете промежуток, который перемещаете, подобно курсору, по сетке из столбцов и строк (точно так же, как INDEX/ИНДЕКС ищет единственную ячейку, если только в нем не упомянут 0). Например, можно задать функции OFFSET/СМЕЩ рамки от верхней левой ячейки листа А1 и затем растянуть ее на 3 ячейки вниз, создавая ряд из 3 строк и 0 столбцов: =OFFSET(A1,3,0) / =СМЕЩ(A1,3,0) Эта формула возвращает значение третьего элемента списка — «Chocolate Bar» (рис. 1-10). Последняя формула, о которой я хочу сказать в этом разделе, — SMALL/НАИМЕНЬШИЙ (у него есть двойник — LARGE/НАИБОЛЬШИЙ, который работает точно 31
32 Много цифр так же). Если у вас есть список значений и вы хотите выбрать, скажем, третье наименьшее из них, данная функция делает это за вас. Назовите ячейку А21 Small/Наименьший, а в В21 напишите следующую формулу, содержащую границы поиска и параметр 3: =SMALL(B2:B15,3)/ =НАИМЕНЬШИЙ(B2:B15,3) Эта формула возвращает значение 150, которое является третьим наименьшим после 0 (бутылка воды) и 120 (газировка), как показано на рис. 1-10. И, наконец, еще одна формула для поиска значений, похожая на MATCH/ПОИСКПОЗ, употребившую стероиды. Это VLOOKUP/ВПР (и ее горизонтальный двойник HLOOKUP/ГПР). Им я уделю целый раздел, ибо это монстры. Использование VLOOKUP/ВПР для объединения данных Перейдем обратно к листу продаж на баскетбольных матчах. При этом мы в любое время можем обратиться предыдущему листу с калориями, просто указав его название и поставив перед номером ячейки «!». Например, Calories!В2 является отсылкой к количеству калорий в пиве, несмотря на то, что вы в данный момент работаете с другим листом. Предположим, вы захотите увидеть количество калорий на листе продаж для каждого наименования товара. Вам нужно будет каким-то образом найти содержание калорий в каждом товаре и поместить его в колонку, следующую за прибылью. Что ж, оказывается, и для этого есть отдельная функция под названием VLOOKUP/ВПР. Назовем колонку F в нашем листе «Calories / Калории». Ячейка F2 будет содержать количество калорий из таблицы в товаре из первой строки — пиве. Используя эту формулу, можно указать в названии товара из ячейки А2 ссылку на таблицу Calories!$A$1:$B$15 и номер столбца, из которого следует выбирать значения. В нашем случае он второй по счету: =VLOOKUP(A2,Calories!$A$1:$B$15,2,FALSE) / =ВПР(A2,Calories!$A$1:$B$15,2,ЛОЖЬ) FALSE/ЛОЖЬ в конце формулы означает, что вам не подходят приблизительные значения «Beer». Если функция не может найти «Beer» в таблице калорий, она возвращает ошибку.
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить После ввода формулы вы увидите, что 200 калорий считались из таблицы в листе «Calories». Поставив $ в формуле перед ссылками на таблицу, вы можете скопировать формулу вниз по колонке двойным щелчком на нижнем правом углу ячейки. Оп-ля! У вас есть количество калорий для каждой позиции, как показано на рис. 1-11. Рис. 1-11. Использование VLOOKUP/ВПР для указания количества калорий Фильтрация и сортировка Отразив в листе продаж калорийность ваших товаров, задайтесь целью видеть, например, только товары из категории «Замороженные продукты» — иными словами, отфильтровать ваш лист. Для этого сначала выберите данные в рамках А1:F200. Наведите курсор на А1 и нажмите Shift+Ctrl+ , а затем . Есть способ еще проще — кликнуть наверху столбца и, удерживая клавишу мышки нажатой, переместить курсор к столбцу F, чтобы выделить все 6 столбцов. Затем, чтобы применить автофильтрацию к этим шести колонкам, нажмите кнопку «Фильтр» из вкладки «Данные». Она похожа на серую воронку, как на рис. 1-12. Если автофильтрация включена, можно кликнуть на выпадающем меню, которое появляется в ячейке В1, и выбрать для показа только определенные категории (в данном случае отобразятся товары из категории «Замороженные продукты»), как на рис. 1-13. После фильтрации выделение столбцов данных позволяет нижней панели показывать краткую информацию об этих ячейках. Например, отфильтровав только замороженные продукты, можно выделить значения в столбце Е и использовать нижнюю панель, чтобы быстро узнать сумму прибыли только по этой категории товара, как на рис. 1-14. 33
34 Много цифр Рис. 1-12. Автофильтрация выбранной области Рис. 1-13. Фильтрация по категории Автофильтрация позволяет также производить сортировку. К примеру, если вы хотите рассортировать прибыль, просто кликните на меню автофильтрации в ячейке Profit/Прибыль (D1) и выберите сортировку по возрастанию (или убыванию), как на рис. 1-15.
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Рис. 1-14. Сумма значений в отфильтрованном столбце Рис. 1-15. Сортировка по возрастанию прибыли Чтобы убрать все фильтры, которые вы применяли, либо вернитесь в меню фильтрации по категориям и отметьте другие категории, либо отключите кнопку «Фильтр» во вкладке «Данные», нажатую в самом начале. Вы увидите, что, несмотря на возвращение всех ваших данных на свои места, 35
36 Много цифр «Замороженные продукты» остаются в том порядке, который был определен фильтром. Excel также предлагает интерфейс для выполнения более сложных сортировок, чем те, на которые способна автофильтрация. Чтобы использовать его, выделите данные для сортировки (снова выберите A: F) и нажмите «Сортировка» в разделе «Сортировка и фильтр» во вкладке «Данные». На экране появится меню сортировки. В MacOS для вызова этого меню нужно нажать стрелку вниз на кнопке сортировки и выбрать настройку. В меню сортировки, показанном на рис. 1-16, независимо от наличия заголовка у столбцов с данными, можно выбрать колонки для сортировки по названию. И теперь самая потрясающая часть этого сортировочного интерфейса, скрытая под кнопкой «Параметры». Нажмите ее, чтобы отсортировать данные слева направо вместо сортировки по колонкам. Это как раз то, чего не может автофильтрация. От начала до конца этой книги вам придется сортировать данные различным образом — и по столбцам, и по строкам, в чем вам очень поможет интерфейс сортировки. А сейчас просто выйдите из этого меню — ведь данные уже рассортированы так, как вам хотелось. Рис. 1-16. Использование меню сортировки
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Использование сводных таблиц Предположим, вам нужно знать количество проданного товара каждого типа или общую сумму выручки по определенному товару. Эти задачи сродни запросам «aggregate» или «group by», используемым в традиционных базах данных SQL. Но наши данные — еще не база. Это — электронная таблица. И здесь нам на помощь приходят сводные таблицы. После фильтрации вы начинаете с выделения данных, которыми хотите манипулировать. В нашем случае — данных о продажах в области А1:F20. Во вкладке «Вставить» (вкладка «Данные» в MacOS) выберите «Сводная таблица» и создайте ее на новом листе. Несмотря на то, что новые версии Excel позволяют вставлять сводную таблицу в существующий лист, ее, как правило, помещают на отдельном, если нет явной причины сделать иначе. На новом листе конструктор сводных таблиц будет расположен справа от таблицы (в MacOS он перемещается). Он позволяет брать столбцы из листа с выделенными данными и использовать их как фильтры отчета, заголовки столбцов и строк для группировки или как значения. Фильтр отчета делает все то же самое, что и фильтр из предыдущего раздела, — позволяет вам выбрать определенный набор данных вроде «Замороженных продуктов». Заголовки столбцов и строк наполняют содержимое отчета сводной таблицы различными значениями из выделенных столбцов. В Windows появляющаяся сводная таблица будет по умолчанию пустой, в то время как в MacOS она оказывается уже частично заполненной значениями из первого выделенного столбца в первом столбце и значениями из второго столбца во всех остальных. Если вы пользуетесь MacOS, то просто уберите все галочки в окнах конструктора и работайте дальше с пустой таблицей. Допустим, теперь вам нужно знать объем выручки за каждый товар. Для этого перетащите ссылку Item/«Товар» в конструкторе сводных таблиц в поле строк, а ссылку Price/«Цена» — в поле данных. Это значит, что вы будете работать с доходом, сгруппированным по названию товара. Изначально сводные таблицы создавались для простого подсчета количества записей о ценах внутри группы. Например, на рис. 1-17 есть 20 строк о пиве. Нужно изменить подсчет количества записей на сумму значений. Чтобы это сделать в Windows, используйте выпадающее меню из ссылки «Цена» в поле данных и выберите в нем «Параметры поля данных». В MacOS нужно нажать маленькую кнопочку «i». В этом меню среди множества других опций можно выбрать сумму. А что, если вам захотелось разбить эти суммы по категориям? Для этого в конструкторе перетащите ссылку «Категории» в поле столбцов. В итоге получается 37
38 Много цифр Рис. 1-17. Конструктор сводной таблицы и подсчет продаж по названию товара таблица, показанная на рис. 1-18. Заметьте, что сводная таблица на рисунке автоматически суммирует для вас строки и столбцы. Если же вы хотите избавиться от каких-либо данных в своей таблице, просто снимите галочку в конструкторе или вытащите ссылку из поля, в котором она находится, будто решили ее выбросить. Избавьтесь, к примеру, от ссылки «Категория». Когда требуемый отчет появился у вас в виде сводной таблицы, вы всегда можете выделить значения и вставить их в другой лист для дальнейшей работы. В нашем примере можно скопировать таблицу (А5:В18 в MacOS) и с помощью «Специальной вставки» перенести значения на новый лист под названием «Прибыль по каждой позиции» (рис. 1-19). Поперемещайте разные заголовки строк и столбцов, пока вам не станет ясна процедура. К примеру, попробуйте подсчитать калорийность всех проданных позиций по категориям с помощью сводных таблиц.
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Рис. 1-18. Разбиение прибыли по названию товара и категориям Рис. 1-19. Лист прибыли по каждой позиции, созданный вставкой значений из сводной таблицы 39
40 Много цифр Использование формул массива В методичке по торговле с лотка есть графа под названием «Комиссия». Оказывается, тренер О'Шонесси позволяет вам торговать с лотка, только если вы отправляете ему некую часть своей прибыли (возможно, чтобы облегчить его затраты на носки без пяток, которые он привык покупать). Графа «Комиссия» отображает, сколько процентов прибыли он забирает с каждой продажи. Как же узнать, сколько вы ему должны после вчерашнего матча? Чтобы ответить на этот вопрос, умножьте общую прибыль по каждой позиции из сводной таблицы на процент комиссии и затем сложите результаты. Есть замечательная функция как раз для этой операции, которая умножит и сложит все, что надо, одним махом. Называется она довольно интересно — SUMPRODUCT/СУММПРОИЗВ. В ячейку Е 1 листа с прибылью по каждой позиции добавьте заголовок «Общая комиссия Тренера». В С2 поместите SUMPRODUCT/ СУММПРОИЗВ для расчета прибыли и процентов от нее: =SUMPRODUCT(B2:B15,'Fee Shedule'!B2:O2) / =СУММПРОИЗВ(В2:В15,'Комиссия'!В2:О2) Ого, да здесь ошибка! В ячейке видно только #Value/#Значение. Что же случилось? Несмотря на то, что вы выбрали две области данных одинакового размера и применили к ним функцию SUMPRODUCT/СУММПРОИЗВ, формула не видит их равенства, потому что одна область вертикальная, а другая — горизонтальная. К счастью, в Excel есть функция для расположения массивов в нужном направлении. Она называется TRANSPOSE/ТРАНСП. Нужно написать такую формулу: =SUMPRODUCT(B2:B15,TRANSPOSE('FeeSchedule'!B2:O2)) / =СУММПРОИЗВ(B2:B15,ТРАНСП('Комиссия'!B2:O2)) Но нет! Все еще возникает ошибка. Причина, по которой это происходит, такова: каждая функция Excel по умолчанию возвращает результат в виде единственного значения. Даже если TRANSPOSE/ ТРАНСП вернет первое значение в транспонированный массив. Если вы хотите видеть в результате целый массив, нужно включить TRANSPOSE/ТРАНСП в «формулу массива». Формулы массива действительно возвращают результат в виде массива, а не единственного значения. Вам не нужно писать SUMPRODUCT/СУММПРОИЗВ как-то иначе, чтобы все получилось. Все, что следует сделать — это вместо клавиши «Enter» после ввода формулы нажать «Ctrl+Shift+Enter». В MacOS нужное сочетание — «Command+Return».
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Победа! Как видно на рис. 1-20, результатом вычислений является 57,60 долларов. Но я бы округлил его до 50 — неужели Тренеру нужно столько носков? Рис. 1-20. Применение SUMPRODUCT/СУММАПРОИЗ с формулой для массива Решение задач с помощью «Поиска решения» Многие техники, которым вы научитесь в этой книге, могут быть сведены к моделям оптимизации. Проблема оптимизации — из разряда тех, для которых нужно подобрать лучшее решение (наилучший способ инвестирования, минимизировать траты вашей компании и т. д.). Применительно к моделям оптимизации приходится часто пользоваться словами «минимизировать» и «максимизировать». В рамках науки о данных многие приемы, чего бы они ни касались — искусственного интеллекта, извлечения и анализа данных или прогнозирования — на деле состоят из некоторой подготовки данных и стадии подбора модели, которая на самом деле и является моделью оптимизации. Так что, по моему мнению, имеет смысл сначала научиться оптимизации. Но просто взять и выучить все об оптимизации невозможно. Мы проведем углубленное исследование оптимизации в главе 4, после того, как вы немного «поиграете» с проблемами машинного самообучения в главах 2 и 3. Но чтобы заполнить пробелы, неплохо было бы немного попрактиковаться в оптимизации уже сейчас — для пробы. В Excel проблемы оптимизации решаются с помощью встроенного модуля под названием «Поиск решения». В Windows «Поиск решения» можно подключить, пройдя во вкладку «Файл» • (в Excel 2007 это верхняя левая кнопка Windows) Параметры Надстройки. Нажав «Доступные надстройки» в выпадающем меню, отметьте «Поиск решения». 41
42 Много цифр В MacOS «Поиск решения» добавляется из меню «Инструменты», в кото• ром следует выбрать «Надстройки», а затем Solver.xlam. Кнопка «Поиск решения» появится в разделе «Анализ» вкладки «Данные» в любой версии Excel. Отлично! Включив «Поиск решения», можете приступать к оптимизации. Представьте, что вам велели потреблять 2400 ккал в день. Какое минимальное количество покупок нужно сделать в вашем киоске, чтобы набрать дневную норму? Очевидно, самый простой выход — купить 10 сэндвич-мороженых по 240 ккал в каждом, но можно ли набрать норму, совершив меньше 10 покупок? «Поиск решения» знает ответ! Для начала сделайте копию листа «Calories»/«Калории», назовите его «Калории — решение» и удалите из копии все, кроме таблицы калорийности. Чтобы сделать копию листа в Excel, просто кликните правой клавишей мышки на заголовке листа, который хотите скопировать (внизу), и выберите в появившемся меню «Переместить» или «Копировать». Так вы получите новый лист, как на рис. 1-21. Рис. 1-21. Скопированный лист «Калории — решение» Чтобы заставить «Поиск решения» искать решение, нужно задать ему пределы ячеек, в которых следует вести поиск. В нашем случае мы хотим узнать,
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить сколько и чего нужно купить. Поэтому следующий за калорийностью столбец С назовите «Сколько?» (или как вам больше нравится) и разрешите «Поиску решения» хранить свои решения в нем. Excel считает значения всех пустых ячеек равными нулю, так что вам не нужно заполнять этот столбец перед началом работы. «Поиск решения» сделает это за вас. В ячейке С16 просуммируйте количество покупок таким образом: =SUM(C2:C15) / =СУММ(C2:C15) Под данной формулой можно подсчитать количество килокалорий в этих покупках (которая должна, по вашему разумению, равняться 2400), используя формулу SUMPRODUCT/СУММПРОИЗВ: =SUMPRODUCT(B2:B15,C2:C15) / =СУММПРОИЗВ(B2:B15,C2:C15) Таким образом получается лист, изображенный на рис. 1-22. Теперь вы готовы к построению модели, так что запускайте «Поиск решения», нажав кнопку «Поиск решения» во вкладке «Данные». Рис. 1-22. Настройка расчета килокалорий и продуктов 43
44 Много цифр ЗАМЕТКА Окно поиска решений в Excel 2011, показанное на рис. 1-23, выглядит примерно так же, как и в Excel 2010 и 2013. В Excel 2007 интерфейс немного другой, но единственное существенное отличие заключается в отсутствии окна выбора алгоритма. Зато можно выбрать «Линейную модель» в параметрах поиска решений. Обо всех этих элементах мы поговорим позже. Основные элементы, которые нужны «Поиску решения» для решения проблемы, как показано на рис. 1-23, — это ячейка для результата, направление оптимизации (минимализация или максимализация), несколько условных переменных, которые «Поиск решения» может изменять, и какие-либо условия. Рис. 1-23. Окно неактивированного поиска решения Наша цель — минимизировать количество покупок в ячейке С16. Ячейки, значение которых может меняться, находятся в пределах С2:С15. Условие же состоит в том, что значение С17 — общего количества килокалорий — должно равняться 2400. Также нужно добавить условие, что результат должен быть положительным и целым — мы ведь считаем покупки в штуках, так что придется
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить отметить галочкой опцию «Неотрицательные значения» в меню параметров поиска решения Excel 2007 и добавить целочисленность как условие решения. Так или иначе, мы не можем купить 1,7 бутылок газировки. (Всю глубину условия целочисленности вы познаете в главе 4). Чтобы добавить условие общего количества килокалорий, нажмите «Добавить» и задайте ячейке С17 значение 2400, как показано на рис. 1-24. Рис. 1-24. Добавление условия о количестве калорийности Точно так же можно добавить условие целочисленности для С2:С15, как показано на рис. 1-25. Рис. 1-25. Добавление условия целочисленности Нажмите ОК. В Excel 2010, 2011 и 2013 убедитесь, что метод решения установлен на «Поиск решения линейных задач симплекс-методом». Это наиболее подходящий для нашей задачи метод, так как она линейна. Под линейностью я подразумеваю, что для решения проблемы нужны только линейные комбинации значений из С2:С15 (суммы, произведения значений и констант количества килокалорий и т. д.). Если бы в нашей модели встречались нелинейные комбинации (вроде квадратного корня из решения, логарифма или экспоненты), то мы могли бы использовать какой-нибудь другой алгоритм, предлагаемый Excel. Подробно этот вариант рассматривается в главе 4. В Excel 2007 обозначить задачу как линейную можно, нажав на «Линейную модель» внизу окна «Параметры поиска решений». В итоге должно получиться то, что изображено на рис. 1-26. 45
46 Много цифр Рис. 1-26. Результат настройки «Поиска решений» для минимализации количества покупок, содержащих 2400 ккал Отлично! Самое время нажать кнопку «Выполнить». Excel найдет решение практически мгновенно. Как явствует из рис. 1-27, результат равняется 5. Ваш Excel может выбрать какие-то другие 5 позиций, но их минимальное количество останется неизменным. OpenSolver: хотелось бы обойтись без него, но это невозможно Вообще эта книга писалась для работы исключительно со встроенным поиском решений Excel. Но по загадочным и необъяснимым причинам часть функционала была просто удалена из позднейших версий надстройки. Это значит, что все описанное в книге работает для стандартного «Поиска решения» Excel 2007 и Excel 2011 на MacOS, но в Excel 2010 и 2013 встроенный поиск решения вдруг начинает жаловаться на то, что оптимизируемая линейная модель слишком велика для него (я заранее сообщу, какие модели из рассматриваемых в книге настолько сложны).
1. Все, что вы жаждали знать об электронных таблицах, но боялись спросить Рис. 1-27. Оптимизированный выбор покупок К счастью, существует превосходный бесплатный инструмент под названием OpenSolver, совместимый с версиями Excel для Windows, который восполняет этот недостаток. С ним можно строить модель в обычном интерфейсе «Поиска решения», в который OpenSolver добавляет кнопку для использования симплексметода решения линейных задач, работающего буквально со скоростью света. Для установки OpenSolver зайдите на http://opensolver.org и загрузите оттуда архив. Распакуйте файл в папку и в любое время, когда понадобится решить «увесистую» модель, просто внесите ее в электронную таблицу и дважды кликните на файле opensolver.xlam, после чего во вкладке «Данные» появится новый раздел OpenSolver. Теперь нажмите на кнопку «Решить». Как показано на рис. 1-28, я применил OpenSolver в Excel 2013 к модели из предыдущего раздела, и он считает, что можно купить 5 кусков пиццы. Подытожим Вы научились быстро ориентироваться в Excel и выбирать области поиска, эффективно использовать абсолютные ссылки, пользоваться специальной вставкой, VLOOKUP/ВПР и другими функциями поиска ячейки, сортировкой и фильтрацией 47
48 Много цифр Рис. 1-28. OpenSolver скупает пиццу, как сумасшедший данных, создавать сводные таблицы и диаграммы, работать с формулами массива и поняли, как и когда прибегать к помощи «Поиска решения». Но вот один грустный (или смешной, в зависимости от вашего нынешнего настроения) факт. Я знал консультантов по менеджменту в крупных компаниях, которые получали немаленькую зарплату за то, что я называю «двухшаговым консалтингом»/консультационным тустепом: 1. Разговор с клиентами обо всякой чепухе (о спорте, отпуске, барбекю… конечно, я не имею в виду, что жареное мясо — полная ерунда). 2. Сведение данных в Excel. Вы можете не знать всего о школьном футболе (я определенно не знаю), но если вы усвоите эту главу, смело отправляйте второй пункт в нокаут. Запомните: вы читаете эту книгу не затем, чтобы стать консультантом по менеджменту. Вы здесь для того, чтобы глубоко погрузиться в науку о данных. И это погружение произойдет буквально со следующей главы, которую мы начнем с небольшого неконтролируемого машинного самообучения.
2 Я Кластерный анализ, часть I: использование метода k-средних для сегментирования вашей клиентской базы работаю в индустрии почтового маркетинга для сайта под названием MailChimp.com. Мы помогаем клиентам делать новостную рассылку для своей рекламной аудитории. Каждый раз, когда кто-нибудь называет нашу работу «почтовым вбросом», я чувствую на сердце неприятный холод. Почему? Да потому что адреса электронной почты — больше не черные ящики, которые вы забрасываете сообщениями, будто гранатами. Нет, в почтовом маркетинге (как и в других формах онлайн-контакта, включая твиты, посты в Facebook и кампании на Pinterest) бизнес получает сведения о том, как аудитория вступает в контакт на индивидуальном уровне, с помощью отслеживания кликов, онлайн-заказов, распространения статусов в социальных сетях и т. д. Эти данные — не просто помехи. Они характеризуют вашу аудиторию. Но для непосвященного эти операции сродни премудростям греческого языка. Или эсперанто. Как вы собираете данные об операциях с вашими клиентами (пользователями, подписчиками и т. д.) и используете ли их данные, чтобы лучше понять свою аудиторию? Когда вы имеете дело с множеством людей, трудно изучить каждого клиента в отдельности, особенно если все они по-разному связываются с вами. Даже если бы теоретически вы могли достучаться до каждого лично, на практике это вряд ли осуществимо. Нужно взять клиентскую базу и найти золотую середину между «бомбардировкой» наобум и персонализированным маркетингом для каждого отдельного покупателя. Один из способов достичь такого баланса — использование кластеризации для сегментирования рынка ваших клиентов, чтобы вы могли обращаться к разным сегментам вашей клиентской базы с различным целевым контентом, предложениями и т. д. Кластерный анализ — это сбор различных объектов и разделение их на группы себе подобных. Работая с этими группами — определяя, что у их членов общего, а что отличает их друг от друга — вы можете многое узнать о беспорядочном
50 Много цифр имеющемся у вас массиве данных. Это знание поможет вам принимать оптимальные решения, причем на более детальном уровне, нежели раньше. В этом разрезе кластеризация называется разведочной добычей данных, потому что эти техники помогают «вытянуть» информацию о связях в огромных наборах данных, которые не охватишь визуально. А обнаружение связей в социальных группах полезно в любой отрасли — для рекомендаций фильмов на основе привычек целевой аудитории, для определения криминальных центров города или обоснования финансовых вложений. Одно из моих любимых применений кластеризации — это кластеризация изображений: сваливание в кучу файлов изображений, которые «выглядят одинаково» для компьютера. К примеру, в сервисах размещения изображений типа Flickr пользователи производят кучу контента и простая навигация становится невозможной из-за большого количества фотографий. Но, используя кластерные техники, вы можете объединять похожие изображения, позволяя пользователю ориентироваться между этими группами еще до подробной сортировки. КОНТРОЛИРУЕМОЕ ИЛИ НЕКОНТРОЛИРУЕМОЕ МАШИННОЕ ОБУЧЕНИЕ? В разведочной добыче данных вы, по определению, не знаете раньше времени, что же за данные вы ищете. Вы — исследователь. Вы можете четко объяснить, когда двое клиентов выглядят похожими, а когда разными, но вы не знаете лучшего способа сегментировать свою клиентскую базу. Поэтому «просьба» к компьютеру сегментировать клиентскую базу за вас называется неконтролируемым машинным обучением, потому что вы ничего не контролируете — не диктуете компьютеру, как делать его работу. В противоположность этому процессу, существует контролируемое машинное обучение, которое появляется, как правило, когда искусственный интеллект попадает на первую полосу. Если я знаю, что хочу разделить клиентов на две группы — скажем, «скорее всего купят» и «вряд ли купят» — и снабжаю компьютер историческими примерами таких покупателей, применяя все нововведения к одной из этих групп, то это контроль. Если вместо этого я скажу: «Вот что я знаю о своих клиентах и вот как определить, разные они или одинаковые. Расскажи-ка что-нибудь интересненькое», — то это отсутствие контроля. В данной главе рассматривается самый простой способ кластеризации под названием метод k-средних, который ведет свою историю из 50-х годов и с тех пор стал дежурным в открытии знаний из баз данных (ОЗБД) во всех отраслях и правительственных структурах.
2. Кластерный анализ, часть I Метод k-средних — не самый математически точный из всех методов. Он создан, в первую очередь, из соображений практичности и здравого смысла — как афроамериканская кухня. У нее нет такой шикарной родословной, как у французской, но и она зачастую угождает нашим гастрономическим капризам. Кластерный анализ с помощью k-средних, как вы вскоре убедитесь, — это отчасти математика, а отчасти — экскурс в историю (о прошлых событиях компании, если это сравнение относится к методам обучения менеджменту). Его несомненным преимуществом является интуитивная простота. Посмотрим, как работает этот метод, на простом примере. Девочки танцуют с девочками, парни чешут в затылке Цель кластеризации методом k-средних — выбрать несколько точек в пространстве и превратить их в k группы (где k — любое выбранное вами число). Каждая группа определена точкой в центре вроде флага, воткнутого в Луну и сигнализирующего: «Эй, вот центр моей группы! Присоединяйтесь, если к этому флагу вы ближе, чем к остальным!» Этот центр группы (с официальным названием кластерный центроид) — то самое среднее из названия метода k-средних. Вспомним для примера школьные танцы. Если вы сумели стереть ужас этого «развлечения» из своей памяти, я очень извиняюсь за возвращение таких болезненных воспоминаний. Герои нашего примера — ученики средней школы Макакне, пришедшие на танцевальный вечер под романтическим названием «Бал на дне морском», — рассеяны по актовому залу, как показано на рис. 2-1. Я даже подрисовал в Photoshop паркет, чтобы было легче представить ситуацию. А вот примеры песен, под которые эти юные лидеры свободного мира будут неуклюже танцевать (если вдруг вам захочется музыкального сопровождения, к примеру, на Spotify): Styx: Come Sail Away • Everything But the Girl: Missing • Ace of Base: All that She Wants • Soft Cell: Tainted Love • Montell Jordan: This is How We Do It • Eiffel 65: Blue • 51
52 Много цифр Рис. 2-1. Ученики средней школы Макакне расположились в актовом зале Теперь кластеризация по k-средним зависит от количества кластеров, на которое вы желаете поделить присутствующих. Давайте остановимся для начала на трех кластерах (далее в этой главе мы рассмотрим вопрос выбора k). Алгоритм размещает три флажка на полу актового зала некоторым допустимым образом, как показано на рис. 2-2, где вы видите 3 начальных флажка, распределенных по полу и отмеченных черными кружками. В кластеризации методом k-средних танцоры привязаны к ближайшему для них кластерному центру, так что между двумя любыми центрами на полу можно нарисовать демаркационную линию. Таким образом, если танцор находится на одной стороне линии, он принадлежит к одной группе, если по другую сторону — то уже к другой (как на рис. 2-3). Используя эти демаркационные линии, разделим танцоров на группы и раскрасим соответствующим образом, как на рис. 2-4. Эта диаграмма, разделяющая пространство на многоугольники, определенные близостью к тому или иному кластерному центру, называется диаграммой Вороного. Посмотрим на наше первоначальное разделение. Что-то не так, не правда ли? Пространство разделено довольно странным образом: нижняя левая группа осталась пустой, а на границе верхней правой группы, напротив, много людей. Алгоритм кластеризации методом k-средних перемещает кластерные центры по полу, пока не достигнет наилучшего результата.
2. Кластерный анализ, часть I Рис. 2-2. Размещение начальных центров кластеров Как определить «наилучший результат»? Каждый присутствующий отстоит на сколько-то от своего кластерного центра. Чем меньше среднее расстояние от участников до центра их группы, тем лучше результат. Рис. 2-3. Линии отмечают границы кластеров 53
54 Много цифр Рис. 2-4. Группировка по кластерам, отмеченным разными фоновыми узорами на диаграмме Вороного Теперь, как я и обещал в главе 1, вводим слово «минимизация» — оно вам очень пригодится в оптимизации модели для лучшего расположения кластерных центров. В данной главе вы будете заставлять «Поиск решения» передвигать кластерные центры бессчетное количество раз. Способ, который использует «Поиск решения» для нахождения наилучшего расположения кластерных центров, — это медленное итеративное перемещение их по поверхности с фиксацией лучших найденных результатов и комбинированием их (буквально спариванием, как скаковых лошадей) для нахождения наилучшего положения. Так что если диаграмма на рис. 2-4 выглядит довольно бледно, «Поиск решения» может внезапно расположить центры как на рис. 2-5. Таким образом среднее расстояние между каждым танцором и его центром немного уменьшится. Очевидно, что рано или поздно «Поиск решения» поймет, что центры должны быть размещены в середине каждой группы танцоров, как показано на рис. 2-6. Отлично! Вот так выглядит идеальная кластеризация. Кластерные центры находятся в центре каждой группы танцоров, минимизируя среднее расстояние между танцором и ближайшим центром. Теперь, когда кластеризация закончена, время перейти к развлекательной части, а именно: попытке понять, что же эти кластеры означают. Если вы узнали цвет волос танцоров, их политические предпочтения или время преодоления ими стометровки, то кластеризация не имеет особого смысла.
2. Кластерный анализ, часть I Рис. 2-5. Слегка смещаем центры Рис. 2-6. Оптимальная кластеризация на школьных танцах Но решив определить возраст и пол присутствующих, вы начнете видеть некоторые общие тенденции. Небольшая группа внизу — это пожилые люди, скорее всего сопровождающие. Группа слева вся состоит из мальчиков, а группа справа — из девочек. И все очень боятся танцевать друг с другом. 55
56 Много цифр Таким образом, метод k-средних позволил вам разделить множество посетителей танцев на группы и скоррелировать характеристики каждого посетителя с принадлежностью к определенному кластеру, чтобы понять причину разделения. Теперь вы наверняка говорите себе: «Да ладно, что за глупости. Я уже до начала знал ответ». Вы правы. В этом примере — да. Я специально привел такой «игрушечный» пример, будучи уверенным, что вы можете решить его, просто взглянув на точки. Действие происходит в двумерном пространстве, в котором кластеризация производится элементарно с помощью глаз. Но что, если вы держите магазин, реализующий тысячи товаров? Некоторые покупатели совершили одну или две покупки за последние два года. Другие — десятки. И каждый покупал что-то свое. Как вы кластеризируете их на таком «танцполе»? Начнем с того, что этот танцпол не двумерный, и даже не трехмерный. Это тысячемерное пространство реализации товара, в котором покупатель приобрел или не приобрел товар в каждом измерении. Видите, как быстро проблема кластеризации начинает выходить за пределы способностей «глазного яблока первого разряда», как любят говорить мои друзья-военные. Реальная жизнь: кластеризация методом k-средних в электронном маркетинге Давайте перейдем к более предметному случаю. Я занимаюсь электронным маркетингом, поэтому приведу пример из жизни MailChimp.com, в которой работаю. Этот же самый пример будет работать и на данных о розничной торговле, преобразовании рекламного трафика, социальных сетей и т. д. Он взаимодействует практически с любым типом данных, связанных с донесением до клиентов рекламного материала, после чего они безоговорочно выбирают вас. Оптовая Винная Империя Джоуи Бэг О'Донатса Представьте на минуту, что вы живете в Нью-Джерси, где держите Оптовую Винную Империю Джоуи Бэг О'Донатса. Это импортно-экспортный бизнес, целью которого является доставка огромного количества вина из-за границы и продажи его определенным винным магазинам по всей стране. Этот бизнес работает таким образом, что Джоуи путешествует по всему миру в поисках невероятных сделок с большим количеством вина. Он отправляет его к себе в Джерси, а пристроить присланное в магазины и получить прибыль — ваша забота.
2. Кластерный анализ, часть I Вы находите покупателей разными способами: страница на Facebook, аккаунт в Twitter, порой даже прямая рассылка — ведь электронные письма «раскручивают» большинство видов бизнеса. В прошлом году вы отправляли одно письмо в месяц. Обычно в каждом письме описываются две или три сделки, скажем, одна с шампанским, а другая с мальбеком. Некоторые сделки просто удивительны — скидка составляет 80% или больше. В итоге вы заключили около 32 сделок за год и все они прошли более-менее гладко. Но то, что дела идут просто хорошо, не значит, что они не могут идти лучше. Было бы нелишне чуть глубже понять мотивы своих покупателей. Конечно, взглянув на конкретный заказ, вы видите, что некий Адамс купил сколько-то игристого в июле с 50%-ной скидкой, но не можете определить, что подвигло его на покупку. Понравился ли ему минимальный объем заказа в одну коробку с шестью бутылками или цена, которая еще не поднялась до своего максимума? Было бы неплохо иметь возможность разбить список клиентов на группы по интересам. Тогда вы бы могли отредактировать письма к каждой группе отдельно и, возможно, раскрутили бы бизнес еще больше. Любая подходящая данной группе сделка могла стать темой письма и идти в первом абзаце текста. Такой тип целевой рассылки может вызвать форменный взрыв продаж! Но как разделить список рассылки? С чего начать? Есть возможность дать компьютеру сделать работу за вас. Используя кластеризацию методом k-средних, вы можете найти наилучший вариант разбиения на группы, а затем попытаться понять, почему же он лучший. Исходный набор данных ЗАМЕТКА Документ Excel, который мы будем разбирать в этой главе, находится на сайте книги — www.wiley.com/go/datasmart. В нем содержатся все исходные данные на случай, если вам захочется поработать с ними. Или же вы можете просто следить за текстом, подглядывая в остальные листы документа. Для начала у вас есть два интересных источника данных: метаданные по каждому заказу сохранены в электронной таблице, включая • сорт, минимальное количество вина в заказе, скидку на розничную продажу, информацию о том, пройден ли ценовой максимум, и о стране происхождения. Эти данные размещены во вкладке под названием OfferInformation, как показано на рис. 2-7; 57
58 Много цифр зная, кто из клиентов что заказывает, вы можете вытряхнуть эту ин• формацию из MailChimp и скормить электронной таблице с метаданными предложений во вкладке «Transactions». Это переменные данные, представленные, как показано на рис. 2-8, очень просто: покупатель и его заказ. Рис. 2-7. Детали последних 32 заказов Определяем предмет измерений И вот задача. В проблеме школьных танцев измерение расстояния между присутствующими и определение кластерных центров были несложными, не так ли? Достаточно просто найти подходящую рулетку! Но что делать сейчас?
2. Кластерный анализ, часть I Рис. 2-8. Список количества заказов по покупателям Вы знаете, что в прошлом году было 32 предложения сделок и у вас есть список из 324 заказов в отдельной вкладке, разбитый по покупателям. Но чтобы измерить расстояние от каждого покупателя до кластерного центра, вы должны поместить их в это 32-сделочное пространство. Иначе говоря, вам нужно понять, что за сделки они не совершили, и создать матрицу сделок по покупателям, в которой каждый клиент получает свой собственный столбец с 32 ячейками сделок, заполненные единицами, если сделки были совершены, и нулями, если нет. Другими словами, вам нужно взять эту ориентированную по строкам таблицу сделок и превратить ее в матрицу, в которой клиенты располагаются по вертикали, а предложения — по горизонтали. Лучшим способом ее создать являются сводные таблицы. ЗАМЕТКА Чтобы узнать, что такое сводные таблицы, загляните в главу 1. Алгоритм действия: на листе с переменными данными выделите столбцы А и В, а затем вставьте сводную таблицу. Используя Мастер создания сводных таблиц, просто выберите сделки как заголовок строки, а покупателей как заголовок 59
60 Много цифр столбца и заполните таблицу. В ячейке будет 1, если пара «клиент-сделка» существует, и 0, если нет (в данном случае 0 отображается как пустая ячейка). В результате получается таблица, показанная на рис. 2-9. Рис. 2-9. Сводная таблица «клиент-сделка» Теперь, когда у вас есть информация о заказах в формате матрицы, скопируйте лист OfferInformation и назовите его Matrix. В этот новый лист вставьте СТАНДАРТИЗАЦИЯ ДАННЫХ В этой главе каждое измерение ваших данных представлено одинаково, в виде бинарной информации о заказах. Но во многих ситуациях, связанных с кластеризацией, мы не можем так сделать. Вообразите сценарий, в котором люди кластеризованы по росту, весу и зарплате. Все эти три вида данных имеют разную размерность. Рост может варьироваться от 1,5 до 2 метров, в то время как вес — от 50 до 150 кг. В этом контексте измерение расстояния между покупателями (как между танцорами в актовом зале) становится запутанным делом. Поэтому принято стандартизировать каждый столбец с данными, вычитая среднее и затем деля поочередно на меру разброса под названием среднеквадратичное отклонение, которое мы вычислим в главе 4. Таким образом, все столбцы приводятся к единой величине, количественно варьируясь около 0. Так как наши данные из главы 2 не требуют стандартизации, вы можете понаблюдать ее в действии в главе об определении выбросов — главе 9.
2. Кластерный анализ, часть I Рис. 2-10. Описание сделок и данные о заказах, слитые в единую матрицу значения из сводной таблицы (не нужно копировать и вставлять номер сделки, потому что он уже содержится в информации о заказе), начиная со столбца Н. В итоге у вас должна получиться расширенная версия матрицы, дополненная информацией о заказах, как на рис. 2-10. Начнем с четырех кластеров Ну что ж, теперь все ваши данные сведены к единому удобному формату. Чтобы начать кластеризировать, нужно выбрать k — количество кластеров в алгоритме k-средних. Зачастую метод k-средних применяется так: берется набор различных k и проверяется по одному (как их выбирать, я объясню позже), но мы только начинаем — так что выберем лишь одно. Вам понадобится количество кластеров, которое примерно подходит для того, чем вы хотите заняться. Вы явно не намерены создавать 50 кластеров и рассылать 50 целевых рекламных писем паре ребят из каждой группы. Это моментально лишает смысла наше упражнение. В нашем случае нужно что-то 61
62 Много цифр небольшое. Начните этот пример с 4 — в идеальном мире вы, возможно, разделили бы ваш список клиентов на 4 понятные группы по 25 человек в каждой (что в реальности маловероятно). Итак, если придется разделить покупателей на 4 группы, как наилучшим образом их подобрать? Вместо того чтобы портить симпатичный лист Matrix, скопируйте данные в новый лист и назовите его 4МС. Теперь вы можете вставить 4 столбца после ценового максимума в столбцы от Н до К, которые будут кластерными центрами. (Чтобы вставить столбец, кликните правой клавишей мышки на столбце Н и выберите «Вставить». Столбец появится слева.) Назовите эти кластеры от Cluster 1 до Cluster 4. Вы также можете применить на них условное форматирование, и когда бы вы ни установили их, вы сможете увидеть, насколько они отличаются. Лист 4МС появится, как показано на рис. 2-11. В данном случае все кластерные центры — нули. Но технически они могут быть какими угодно и, что вам особенно понравится — как на школьных танцах, распределены таким образом, что минимизируют расстояние между каждым покупателем и его кластерным центром. Очевидно, что тогда эти центры будут иметь значения от 0 до 1 для каждой сделки, так как все клиентские векторы бинарны. Но что означает «измерить расстояние между кластерным центром и покупателем»? Евклидово расстояние: измерение расстояний напрямик Для каждого клиента у вас есть отдельный столбец. Как же измерить расстояние между ними? В геометрии это называется «кратчайший путь», а расстояние, получаемое в результате, — евклидовым расстоянием. Вернемся ненадолго в актовый зал и попробуем понять, как решить нашу проблему там. Поместим координатные оси на полу и на рис. 2-12 увидим, что в точке (8,2) у нас танцор, а в (4,4) — кластерный центр. Чтобы рассчитать евклидово расстояние между ними, придется вспомнить теорему Пифагора, с которой вы знакомы еще со школьной скамьи. Эти две точки находятся в 8 – 4 = 4 метрах друг от друга по вертикали и в 4 – 2 = 2 метрах по горизонтали. По теореме Пифагора, квадрат расстояния между двумя точками равен 4^2+2^2 = 20 метрам. Отсюда мы вычисляем само расстояние, которое будет равно квадратному корню из 20, что составляет примерно 4,47м (как на рис. 2-13).
2. Кластерный анализ, часть I Рис. 2-11. Пустые кластерные центры, помещенные на лист 4МС 10 9 (8,2) 8 7 6 5 (4,4) 4 3 2 1 1 2 3 4 5 6 7 8 9 10 Рис. 2-12. Танцор в точке (8,2) и кластерный центр в (4,4) 63
64 Много цифр 10 9 (8,2) 8 7 42 + 22 = 4,47 6 4 5 (4,4) 4 2 3 2 1 1 2 3 4 5 6 7 8 9 10 Рис. 2-13. Евклидово расстояние равняется квадратному корню из суммы расстояний в каждом направлении В контексте подписчиков на рассылку у вас больше двух измерений, но применима та же концепция. Расстояние между покупателем и кластерным центром рассчитывается путем определения разниц между двумя точками для каждой сделки, возведения их в квадрат, сложения и извлечения квадратного корня. К примеру, на листе 4МС вы хотите узнать евклидово расстояние между центром кластера 1 в столбце Н и заказами покупателя Адамса в столбце L. В ячейке L34, под заказами Адамса, можно вычислить разницу между вектором Адамса и кластерным центром, возвести ее в квадрат, сложить и затем извлечь корень, используя следующую формулу для массивов (отметьте абсолютные ссылки, позволяющие вам перетаскивать эту формулу вправо или вниз без изменения ссылки на кластерный центр): {=SQRT(SUM((L$2:L$33-$H$2:$H$33)^2))} {=КОРЕНЬ(СУММА(L$2:L$33-$H$2:$H$33)^2))} Формулу для массивов (введите формулу и нажмите Ctrl+Shift+Enter или Cmd+Return в MacOS, как сказано в главе 1) нужно использовать, потому что ее часть (L2:L33-H2:H33)^2 должна «знать», куда обращаться для
2. Кластерный анализ, часть I вычисления разниц и возведения их в квадрат, шаг за шагом. Однако результат в итоге — единственное число, в нашем случае 1,732 (как на рис. 2-14). Он имеет следующий смысл: Адамс заключил три сделки, но так как изначальные кластерные центры — нули, ответ будет равняться квадратному корню из 3, а именно 1,732. Рис. 2-14. Расстояние между центром 1 кластера и Адамсом В электронной таблице на рис. 2-14 я закрепил верхнюю строку (см. главу 1) между столбцами G и Н и назвал строку 34 в ячейке G34 «Distance to Cluster 1», просто чтобы видеть, что где находится, если проматывать страницу вниз. Расстояния и принадлежность к кластеру для всех! Теперь вы знаете, как вычислить расстояние между вектором заказа и кластерным центром. Пришло время добавить Адамсу расчет расстояний до остальных кластерных центров, перетянув ячейку L34 вниз на L37, а затем изменив вручную ссылку на кластерный центр со столбца Н на столбец I, J и К в ячейках ниже. В результате должны получиться следующие 4 формулы в L34:L37: 65
66 Много цифр {=SQRT(SUM((L$2:L$33-$H$2:$H$33)^2))} {=SQRT(SUM((L$2:L$33-$I$2:$I$33)^2))} {=SQRT(SUM((L$2:L$33-$J$2:$J$33)^2))} {=SQRT(SUM((L$2:L$33-$K$2:$K$33)^2))} {=КОРЕНЬ(СУММА((L$2:L$33-$H$2:$H$33)^2))} {=КОРЕНЬ(СУММА((L$2:L$33-$I$2:$I$33)^2))} {=КОРЕНЬ(СУММА((L$2:L$33-$J$2:$J$33)^2))} {=КОРЕНЬ(СУММА((L$2:L$33-$K$2:$K$33)^2))} Так как вы использовали абсолютные ссылки для кластерных центров (ведь значок $ в формулах обозначает именно это, как было сказано в главе 1), можно перетащить L34:L37 в DG34:DG37, чтобы рассчитать расстояние от каждого покупателя до всех четырех кластерных центров. Озаглавьте строки в столбце G в ячейках с 35 по 37 «Distance to Cluster 2» и т. д. Свежерассчитанные расстояния показаны на рис. 2-15. Рис. 2-15. Расчет расстояний от каждого покупателя до всех кластерных центров Теперь вам известно расстояние каждого клиента до всех четырех кластерных центров. Их распределение по кластерам произведено по кратчайшему расстоянию в два приема следующим образом. Сначала вернемся к Адамсу в столбец L и рассчитаем минимальное расстояние до кластерного центра в ячейке L38. Это просто:
2. Кластерный анализ, часть I =MIN(L34:L37) =МИН(L34:L37) Для расчета используем формулу MATCH/ПОИСКПОЗ (подробнее в главе 1). Поместив ее в L39, вы можете увидеть номер ячейки из промежутка L34:L37 (считаю каждую по порядку от 1), которая находится на минимальном расстоянии: =MATCH(L38,L34:L37,0) =ПОИСКПОЗ(L38,L34:L37,0) В данном случае расстояние одинаково для всех четырех кластеров, так что формула выбирает первый (L34) и возвращает 1 (рис. 2-16). Вы можете также перетащить эти две формулы на DG38: DG39. Для пущей организованности добавьте названия строк 38 и 39 в ячейки 38 и 39 столбца G «Minimum Cluster Distance» и «Assigned Cluster». Рис. 2-16. Добавление на лист привязки к кластерам Поиск решений для кластерных центров Ваша электронная таблица пополнилась расчетом расстояний и привязкой к кластерам. Теперь, чтобы установить наилучшее положение кластерных центров, нужно найти такие значения в столбцах от Н до К, которые минимизируют общее расстояние между покупателями и кластерными центрами, к которым они привязаны, указанными в строке 39 для каждого покупателя. 67
68 Много цифр Если вы внимательно читали главу 1, то должны знать, что делать, когда слышите слово «минимизировать»: начинается этап оптимизации, а оптимизация производится с помощью «Поиска решения». Чтобы использовать «Поиск решения», вам понадобится ячейка для результатов, поэтому в А36 просуммируем все расстояния между покупателями и их кластерными центрами: =SUM(L38:DG38) =СУММА(L38:DG38) Эта сумма расстояний от клиентов до ближайших к ним кластерных центров в точности является той целевой функцией, с которой мы встречались ранее, во время кластеризации актового зала средней школы Макакне. Но евклидово расстояние со своими степенями и квадратными корнями — чудовищно нелинейная функция, поэтому вам придется использовать эволюционный алгоритм решения вместо симплекс-метода. В главе 1 вы уже пользовались этим методом. Симплексный алгоритм, если есть возможность его применить, работает быстрее других, но им нельзя воспользоваться для вычисления корней, квадратов и остальных нелинейных функций. Точно так же бесполезен OpenSolver, представленный в главе 1, который использует симплексный алгоритм, пусть даже и будто принявший стероиды. В нашем случае встроенный в «Поиск решения» эволюционный алгоритм использует комбинацию случайного поиска и отличное решение «скрещивания», чтобы, подобно эволюции в биологическом контексте, находить эффективные решения. ЗАМЕТКА Оптимизация подробно описана в главе 4. У вас есть все, что нужно для постановки задачи перед «Поиском решения»: цель: минимизировать общие расстояния от покупателей к их кластер• ным центрам (А36); переменные: вектор каждой сделки относительно кластерного центра • (Н2:К33); условия: кластерные центры должны иметь значения в пределах от 0 до 1. • Рекомендуется наличие «Поиска решения» и молотка. Ставим задачу «Поиску решения»: минимизировать А36 путем изменения значений Н2:К33 с условием
2. Кластерный анализ, часть I Н2:К33 <=1, как и все векторы сделок. Убедитесь, что переменные отмечены как положительные и выбран эволюционный алгоритм (рис. 2-17). Но постановка задачи — еще не все. Придется немного попотеть, выбирая нужные опции эволюционного алгоритма, нажав кнопку «Параметры» в окне «Поиска решения» и перейдя в окно настройки. Советую установить максимальное время секунд на 30 побольше, в зависимости от того, сколько вы готовы ждать, пока «Поиск решений» справится со своей задачей. На рис. 2-18 я поставил свое на 600 секунд (10 минут). Таким образом, я могу запустить «Поиск решения» и пойти обедать. А если вам захочется прервать его пораньше, просто нажмите Escape и выйдите из него с наилучшим решением, которое тот успел найти. Для тех, кому интересно: внутреннее устройство эволюционного алгоритма «Поиска решения» описано в главе 4 и на http://www.solver.com. Рис. 2-17. Установки «Поиска решения» для 4-центровой кластеризации Нажмите «Выполнить» и наблюдайте, как Excel делает свое дело, пока эволюционный алгоритм не сойдется. 69
70 Много цифр Рис. 2-18. Параметры эволюционного алгоритма Смысл полученных результатов Как только «Поиск решения» выдает вам оптимальные кластерные центры, начинается самое веселое. Переходим к изучению групп! На рис. 2-19 мы видим, что «Поиск решения» нашел оптимальное общее расстояние 140,7, а все четыре кластерных центра — спасибо условному форматированию! — выглядят совершенно по-разному. Имейте в виду, что ваши кластерные центры могут отличаться от представленных в книге, потому что эволюционный алгоритм использует случайные числа и ответ каждый раз получается разный. Кластеры могут быть совершенно другими или, что более вероятно, располагаться в другом порядке (к примеру, мой кластер 1 может быть очень близок к вашему кластеру 4 и т. д.). Так как при создании листа вы вставили в столбцы от В до G описания сделок, теперь можно прочитать подробности на рис. 2-19, что важно для понимания идеи кластерных центров. Для кластера 1 в столбце Н условное форматирование выбирает сделки 24, 26, 17 и, в меньшей степени, 2. Прочитав описание этих сделок, можно понять, что у них общего: они все заключались на пино нуар. Взглянув на столбец I, вы увидите, что во всех зеленых ячейках низкое минимальное количество. Это покупатели, которые не желают приобретать огромные партии в процессе сделки.
2. Кластерный анализ, часть I Рис. 2-19. Четыре оптимальных кластерных центра А вот два остальных кластерных центра, честно говоря, сложно интерпретировать. Как насчет того, чтобы вместо интерпретации кластерных центров изучить самих покупателей в кластере и определить, какие сделки им нравятся? Это могло бы внести в вопрос ясность. Рейтинг сделок кластерным методом Вместо выяснения, какие расстояния до какого кластерного центра ближе к 1, давайте проверим, кто к какому кластеру привязан и какие сделки предпочитает. Чтобы это сделать, начнем с копирования листа OfferInformation. Копию назовем 4МС — TopDealsByCluster. Пронумеруйте столбцы от Н до К на этом новом листе от 1 до 4 (как на рис. 2-20). Рис. 2-20. Создание листа таблицы для подсчета популярности сделок с помощью кластеров 71
72 Много цифр На листе 4МС у вас были привязки по кластерам от 1 до 4 в строке 39. Все, что вам нужно сделать, чтобы сосчитать сделки по кластерам, — это взглянуть на названия столбцов от Н до К на листе 4МС — TopDealsByCluster, посмотреть, кто из листа 4МС был привязан к этому кластеру в строке 39, а затем сложить количество их сделок в каждой строке. Таким образом мы получим общее количество покупателей в данном кластере, совершивших сделки. Начнем с ячейки Н2, в которой записано количество покупателей кластера 1, принявших предложение № 1, а именно январский мальбек. Нужно сложить значения ячеек диапазона L2: DG2 на листе 4МС, но только покупателей из 1 кластера, что является классическим примером использования формулы SUMIF / СУММЕСЛИ. Выглядит она так: =SUMIF('4MC'!$L$39:$DG$39,'4MC — TopDealsByCluster'! H$1,'4MC'!$L2:$DG2) =СУММЕСЛИ('4MC'!$L$39:$DG$39,'4MC — TopDealsByCluster'! H$1,'4MC'!$L2:$DG2) Эта формула работает таким образом: вы снабжаете ее некими условными значениями, которые она проверяет в первой части '4MC'!$L$39:$DG$39, затем сравнивает с 1 в заголовке столбца ('4MC — TopDealsByCluster'! H$1), а потом при каждом совпадении, прибавляет это значение в строку 2 в третьей части формулы '4MC'!$L2:$DG2. Заметьте, что вы использовали абсолютные ссылки ($ в формуле) перед всем, что относится к привязке к кластеру, номеру строки в заголовках столбцов и букве, обозначающей столбец, для совершенных сделок. Сделав эти ссылки абсолютными, можно перетащить формулу в любое место из Н2:К33, чтобы рассчитать количество сделок для других кластерных центров и комбинации сделок, как на рис. 2-21. Чтобы эти столбцы были более читаемы, вы также можете применить к ним условное форматирование. Выделяя столбцы от А до К и применяя автофильтрацию (глава 1), вы можете сортировать эти данные. Отсортировав от наименьшего к наибольшему столбец Н, вы увидите, какие сделки наиболее популярны в кластере 1 (рис. 2-22). Как я упоминал ранее, четыре самых крупных сделки для этого кластера — это пино. Эти ребята явно злоупотребляют фильмом «На обочине». Если вы отсортируете кластер 2, то вам станет совершенно ясно, что это — мелкооптовые покупатели (рис. 2-23). Но когда вы отсортируете кластер 3, понять что-либо будет не так просто. Крупные сделки можно пересчитать по пальцам, а разница между ними и остальными не так очевидна. Однако у самых популярных сделок все же есть что-то общее — довольно хорошие скидки, 5 из 6 самых крупных сделок — на игристое
2. Кластерный анализ, часть I вино, и Франция — производитель товара для 3 из 4 из них. Тем не менее эти предположения неоднозначны (рис. 2-24). Что касается кластера 4, то этим ребятам по какой-то причине явно понравилось августовское предложение на шампанское. Также 5 из 6 крупнейших сделок — на французское вино, а 9 из 10 первых по величине — на большой объем товара (рис. 2-25). Может, это тяготеющий к французским винам крупнооптовый кластер? Пересечение кластеров 3 и 4 тоже беспокоит. И это подводит нас к вопросу: настолько ли хорошо подходит 4 для значения k в кластеризации по k-средним? Возможно, нет. Но как узнать? Рис. 2-21. Общее количество сделок по каждому предложению, разбитое по кластерам Рис. 2-22. Сортировка кластера 1. Пино, пино, пино! 73
74 Много цифр Рис. 2-23. Сортировка кластера 2. Мелкооптовики Рис. 2-24. Сортировка кластера 3 немного запутана
2. Кластерный анализ, часть I Рис. 2-25. Сортировка кластера 4 — эти парни просто любят шампанское в августе? Силуэт: хороший способ позволить разным значениям k посостязаться Нет ничего плохого в том, чтобы кластеризировать методом k-средних несколько раз, перебирая различные k, пока не найдется такой результат, который будет иметь для вас интуитивный смысл. Конечно, возможно, причина отсутствия «хорошо читаемых результатов» заключается не только в том, что k подобрано неверно. Может быть, в информации о предложениях не хватает чего-то такого, что могло бы помочь понять кластеры лучше. Так есть ли другой способ (кроме простого разглядывания кластеров) дать красный или зеленый свет конкретному значению k? Он есть — и это вычисление для наших кластеров такого показателя, как силуэт. Прелесть его в том, что он относительно независим от значения k, так что можно сравнивать различные значения k, пользуясь одними и теми же параметрами. Силуэт высокого уровня: насколько далеки от вас ваши соседи? Вы можете сравнить среднее расстояние между каждым покупателем и его друзьями из его же кластера и покупателями из соседних кластеров (с ближайшими кластерными центрами). 75
76 Много цифр Если я немного ближе к членам своего кластера, чем соседнего, то эти ребята — хорошая компания для меня, не так ли? Но что, если ребята из соседнего кластера практически так же близки ко мне, как и мои кластерные собратья? Выходит тогда, что моя привязка к кластерам немного сомнительна? Вот как формально записать это значение: (Среднее расстояние до членов ближайшего соседнего кластера — Среднее расстояние до членов своего кластера)/Максимум из этих двух средних Знаменатель в расчете дает разброс итогового значения от –1 до 1. Подумайте над этой формулой. Чем дальше от вас находящиеся в соседнем кластере (и тем менее они вам подходят), тем ближе к 1 значение этого показателя. А если два средних расстояния почти одинаковы? Тогда величина стремится к 0. Расчет среднего по этой формуле для каждого покупателя дает нам силуэт. Если силуэт равен 1, это прекрасно. Если это 0, то, скорее всего, кластеры выбраны неверно. Если он меньше нуля, то многие покупатели с гораздо большим удовольствием проводили бы время в другом кластере, который совершенно ужасен. Вы можете сравнить силуэты для различных значений k, чтобы увидеть, какое из них лучше. Чтобы сделать эту концепцию более наглядной, вернемся к примеру со школьными танцами. Рис. 2-26 иллюстрирует расчет расстояний в формировании силуэта. Заметьте, что расстояние от одного из сопровождающих до двух других сравнивается с расстояниями до соседнего кластера — компании мальчишек. Видно, что двое других сопровождающих безусловно ближе, чем кучка неуклюжих тинейджеров, что делает результат расчета для этого сопровождающего гораздо больше нуля. Создание матрицы расстояний Для того чтобы применить силуэт, вам понадобится еще одна немаловажная часть данных, а именно расстояние между покупателями. И если кластерные центры могут перемещаться, то расстояние между двумя клиентами никогда не меняется. Так что можно просто создать отдельный лист Distances и использовать его во всех своих расчетах силуэтов, вне зависимости от того, какое k вы используете и где в конечном итоге окажутся ваши кластерные центры. Начнем с создания чистого листа под названием Distances и вставки туда покупателей: по горизонтали — в первую строку и по вертикали — в первый столбец. Ячейка матрицы будет содержать расстояние между покупателем из строки и покупателем из столбца. Чтобы вставить клиентов в строку, скопируйте H1:DC1
2. Кластерный анализ, часть I Рис. 2-26. Расстояния, рассматриваемые как вклад сопровождающего в расчет силуэта из листа Matrix и, используя «Специальную вставку», вставьте значения, убедившись, что выбрали опцию «Транспонировать» в меню специальной вставки. Вам нужно понимать, где в матрице какой покупатель, поэтому пронумеруйте их от 0 до 99 в обоих направлениях. Расположим эту нумерацию в столбце А и строке 1, для чего вставим пустые столбец и строку слева и сверху, соответственно, кликнув для этого правой клавишей мышки на строке и столбце и выбрав «Вставить». ЗАМЕТКА Между прочим, есть много способов поместить эту нумерацию 0–99 в Excel. К примеру, можно просто начать печатать 0, 1, 2, 3, а затем выделить их и потянуть за нижний угол выделенной области до конца списка клиентов. Excel поймет это и продолжит числовой ряд. В результате должна получиться пустая матрица, как на рис. 2-27. Рассмотрим ячейку С3, которая отображает расстояние между Адамсом и Адамсом, то есть между Адамсом и им же самим. Оно должно равняться нулю, верно? Ведь никто не может быть ближе к вам, чем вы сами! Как же вы это рассчитали? А вот как: столбец Н на листе Matrix показывает вектор сделок Адамса. Чтобы вычислить евклидово расстояние между Адамсом и им самим, нужно просто вычесть столбец Н из столбца Н, возвести разницу в квадрат и извлечь из результата квадратный корень. 77
78 Много цифр Но как применить этот расчет к каждой ячейке матрицы? Я бы ни за что не согласился печатать это вручную. Это бы заняло вечность. Что вам нужно — это формула OFFSET/СМЕЩ в ячейке С3 (эта формула подробно объясняется в главе 1). Формула OFFSET/СМЕЩ берет фиксированный набор ячеек (в нашем случае это будет вектор сделок Адамса, Matrix!$H$2:$H$33) и перемещает его целиком на указанное количество строк и столбцов в нужном вам направлении. Вот, например, OFFSET(Matrix!$H$2:$H$33,0,0) / СМЕЩ(Matrix!$H$2: $H$33,0,0) — это просто тот же вектор сделок Адамса, потому что вы передвинули исходный набор на 0 строк вниз и 0 столбцов вправо. Рис. 2-27. Голая таблица расстояний Но OFFSET(Matrix!$H$2:$H$33,0,1) / СМЕЩ(Matrix!$H$2:$H$33,0,1) — это столбец сделок Аллена. OFFSET(Matrix!$H$2:$H$33,0,2) / СМЕЩ(Matrix!$H$2:$H$33,0,2) — столбец Андерсона, и т. д. И здесь нам как раз и пригодится нумерация строк и столбцов 0–99. Вот, например: {=SQRT(SUM((OFFSET(Matrix!$H$2:$H$33,0,Distances!C$1)-OFFSET (Matrix!$H$2:$H$33,0,Distances!$A3))^2))}
2. Кластерный анализ, часть I {=КОРЕНЬ(СУММА((СМЕЩ(Matrix!$H$2:$H$33,0,Distances!C$1)-СМЕЩ (Matrix!$H$2:$H$33,0,Distances!$A3))^2))} Это расстояние между Адамсом и им самим. Обратите внимание: вы применяете Distances!C$1 для смещения столбца в векторе первой сделки и Distances!$А3 в векторе второй сделки. Таким образом, когда вы перетаскиваете эту формулу по таблице, все остается привязанным к вектору сделок Адамса, но формула OFFSET/СМЕЩ смещает вектор на нужное количество строк и столбцов, используя нумерацию в строке 1 и столбце А. Точно так же она сравнивает два любых вектора сделок интересующих вас покупателей. На рис. 2-28 показана заполненная матрица расстояний. Также не забывайте, что, как и на листе 4МС, эти расстояния — это формулы массивов. Рис. 2-28. Готовая матрица расстояний Применение силуэтов в Excel Ну что ж, теперь, когда у нас есть таблица расстояний, можно создать новый лист под названием 4МС Silhouette для окончательного расчета силуэта. Начнем с копирования покупателей и их групповых привязок с листа 4МС и специальной вставки имен клиентов в столбец А, а привязок — в столбец В (не забудьте проверить, отмечено ли «Транспонирование» в меню специальной вставки). 79
80 Много цифр Теперь можно использовать лист Distances для расчета среднего расстояния между каждыми двумя покупателями из разных кластеров. Озаглавьте столбцы от С до F «Distance from People in 1» и далее до «Distance from People in 4». В моем примере Адамс отнесен к кластеру 2, так что рассчитаем в ячейке С2 расстояние между ним и всеми клиентами кластера 1. Вам нужно просмотреть список покупателей, найти тех, кто относится к кластеру 1, и занести их средние расстояния до Адамса в строку 3 листа Distances. Похоже на подходящий случай для формулы AVERAGEIF/СРЗНАЧЕСЛИ: =AVERAGEIF('4MC'!$L$39:$DG$39,1,Distances!$C3:$CX3) =СРЗНАЧЕСЛИ('4MC'!$L$39:$DG$39,1,Distances!$C3:$CX3) AVERAGEIF/СРЗНАЧЕСЛИ проверяет привязки к кластеру и сравнивает их с кластером 1 перед усреднением соответствующих расстояний из С3:СХ3. Для столбцов от D до F формулы одинаковые, за исключением того, что кластер 1 заменяется 2, 3, и 4. Теперь можно кликнуть на этих формулах дважды и скопировать их на всех покупателей, чтобы получить в результате таблицу, показанную на рис. 2-29. Рис. 2-29. Среднее расстояние между каждым покупателем и покупателями каждого кластера В столбце G можно рассчитать ближайшую группу покупателей, используя формулу MIN/МИН. Например, для Адамса это просто: =MIN(C2:F2) =МИН(С2:F2) А в столбце Н можно вычислить вторую по близости группу покупателей, используя формулу SMALL/НАИМЕНЬШИЙ (цифра 2 в формуле указывает на второй результат):
2. Кластерный анализ, часть I =SMALL(C2:F2,2) =НАИМЕНЬШИЙ(C2:F2,2) Точно так же можно рассчитать расстояние до членов вашей собственной группы (которое, очевидно, такое же, как в столбце G, но не всегда) в столбце I: =INDEX(C2:F2,B2) =ИНДЕКС(C2:F2,B2) Формула INDEX/ИНДЕКС пересчитывает столбцы с расстояниями до нужного вам от С до F, используя значение привязки из столбца В как индекс. Для окончательного расчета силуэта вам понадобится расстояние до ближайшей группы покупателей, находящихся не в вашем кластере, которая, скорее всего, расположена в столбце Н, но не всегда. Чтобы получить эту величину в столбце J, нужно сравнить свое собственное кластерное расстояние в I с ближайшим кластером в G, и если они совпадут, то ответ — Н. В противном случае это G. =IF(I2=G2,H2,G2) =ЕСЛИ(I2=G2,H2,G2) Скопировав все эти значения в столбец, вы получите электронную таблицу, показанную на рис. 2-30. Рис. 2-30. Средние расстояния до ребят из моего кластера и до ближайшей группы, принадлежащей к чужому кластеру И, когда вы свели эти значения вместе, добавление значений силуэта для определенного покупателя в столбец К — пара пустяков: 81
82 Много цифр =(J2-I2)/MAX(J2,I2) =(J2-I2)/МАКС(J2,I2) Вы можете просто скопировать эту формулу вниз по столбцу, чтобы получить величину для каждого покупателя. Легко заметить, что для некоторых клиентов эта величина близка к 1. Например, значение силуэта для Андерсона в моем кластерном решении — 0,544 (рис. 2-31). Неплохо! Но для других покупателей, таких как Коллинз, значение меньше нуля. Если так пойдет и дальше, то Коллинзу будет лучше в соседнем кластере, чем в том, в котором он находится. Бедняга! Теперь можно усреднить эти значения, чтобы получить итоговую фигуру силуэта. В моем случае, показанном на рис. 2-31, это 0,1492, что гораздо ближе к 0, чем к 1. Это удручает, но не особенно удивляет. В конце концов, два из четырех кластеров оказались не очень-то устойчивыми, когда мы попытались их интерпретировать с помощью описаний сделок. Рис. 2-31. Итоговый силуэт кластеризации по 4 средним Хорошо. Что же теперь? Силуэт, безусловно, равен 0,1492. Но что это означает? Что с ним делать? Пробовать другие значения k! А затем снова обратиться к силуэту, чтобы узнать, насколько они лучше. Как насчет пяти кластеров? Попробуем поднять k до 5 и посмотреть, что будет. Есть хорошая новость: так как вы уже делали расчет для 4 кластеров, вам не придется начинать все с чистого листа. Не нужно ничего делать с листом Distances. Он вполне сгодится и так.
2. Кластерный анализ, часть I Создаем копию листа 4МС и называем ее 5МС. Все, что нужно — это добавить пятый кластер на лист и ввести его в свои расчеты. Кликните для начала правой клавишей мыши на столбце L и вставим новый столбец, который назовем Cluster 5. Вам также нужно вставить расстояние в строку кластера 5, кликнув на строке 38 правой клавишей и выбрав «Вставить». Скопируйте расстояние в строку кластера 4 в 38 строке и поменяйте столбец с K на L, чтобы создать строку с расстоянием до кластера 5. Что касается строк Minimum Cluster Distance и Assigned Cluster, то ссылки на строку 37 нужно исправить на 38, чтобы включить в расчет новое кластерное расстояние. В результате должна получиться таблица как на рис. 2-32. Рис. 2-32. Таблица кластеризации по 5 средним Поиск решения для пяти кластеров Открыв «Поиск решения», вам нужно только поменять $H$2:$K$33 на $H$2:$L$33 в переменных решения и разделах условий, чтобы включить новый кластер 5. Все остальное остается без изменений. Нажмите «Выполнить» и запустите решение этой новой задачи. Мой «Поиск решения» остановился на итоговом расстоянии 135,1, как показано на рис. 2-33. 83
84 Много цифр Рис. 2-33. Оптимальные кластеры по 5 средним Рейтинг сделок для всех пяти кластеров Отлично. Давайте посмотрим, как это делается. Создайте копию листа 4MC — TopDealsByCluster tab и переименуйте его в 5MC — TopDealsByCluster. Придется еще подкорректировать несколько формул, чтобы все заработало. Сначала убедитесь, что эта таблица упорядочена по номеру предложений в столбце 1. Затем назовите столбец L «5» и перетащите формулы из K в L. Выделите столбцы от А до L и примените автофильтрацию заново, чтобы сделать заказы кластера 5 сортируемыми. Все ссылки на этом листе ведут к листу 4МС, так что пришло время решительно все найти и заменить. Привязки к кластерам на листе 5МС смещены на одну строку вниз и один столбец вправо, поэтому ссылка на '4MC'!$L$39:$DG$39 в формуле SUMIF//СУММАЕСЛИ превратится
2. Кластерный анализ, часть I в '5MC'!$M$40:$DH$40. Как показано на рис. 2-34, вы можете воспользоваться функцией «Найти и заменить». Рис. 2-34. Замена привязок к 4 кластерным центрам привязками к 5 кластерным центрам ЗАМЕТКА Не забывайте, что ваши результаты отличаются от моих из-за использования эволюционного алгоритма. Сортируя кластер 1, мы снова ясно видим наш кластер пино нуар. (рис. 2-35). Рис. 2-35. Сортировка кластера 1 — пино нуар лезет из ушей Кластер 2 — это кластер покупателей малых объемов (рис. 2-36). 85
86 Много цифр Рис. 2-36. Сортировка кластера 2 — понемногу, пожалуйста! Что касается кластера 3, то он снова взрывает мой мозг. Единственное, что можно в нем выделить — это, по какой-то причине, южноафриканское эспуманте (рис. 2-37). Рис. 2-37. Сортировка кластера 3 — так ли важно игристое? Покупатели кластера 4 заинтересованы в больших объемах, преимущественно французского вина и с хорошей скидкой. Здесь даже можно обнаружить склонность к игристым винам. Этот кластер сложно читается, в нем много что происходит (рис. 2-38).
2. Кластерный анализ, часть I Рис. 2-38. Сортировка кластера 5 — их интересует все! Сортировка кластера 5 даст результат, идентичный кластеру 4, хотя большие объемы и большие скидки похожи на основные тенденции (рис. 2-39). Вычисление силуэта кластеризации по пяти средним Вам, должно быть, интересно, чем пять кластеров лучше четырех. Результат-то, похоже, не сильно отличается. Давайте вычислим силуэт для пяти кластеров и посмотрим, что об этом думает компьютер. Начнем с копирования листа 4МС Silhouette и переименования его в 5МС Silhouette. Теперь кликните правой клавишей мышки на столбце G, вставьте новый столбец и назовите его Distance From People in 5. Перетащите формулу из F2 в G2, поменяйте количество кластеров в переборе с 4 на 5, а затем кликните дважды на ячейке, чтобы заполнить весь столбец. Точно так же, как и в предыдущей части, вам нужно найти и заменить '4MC'!$L$39:$DG$39 на '5MC'!$M$40:$DH$40. 87
88 Много цифр Рис. 2-39. Сортировка кластера 5 — большие объемы В ячейки Н2, I2 и J2 нужно добавить расстояние до ребят из кластера 5, поэтому все диапазоны, заканчивающиеся на F2, должны быть расширены до G2. Затем выделите Н2:J2 и двойным щелчком в правом нижнем углу отправьте эти обновленные формулы вниз по столбцам. И, наконец, скопируйте и вставьте с помощью «Специальной вставки» значения привязки к кластерам из строки 40 листа 5МС в столбец В листа 5МС Silhouette. Это также означает, что вы должны отметить «Транспонировать» в меню специальной вставки. После исправлений лист должен выглядеть как на рис. 2-40. Немного удручает, не правда ли? Силуэт не так уж и отличается. Наоборот, 0,134 даже хуже! Но это не назовешь неожиданностью после изучения получившихся кластеров. В обоих случаях получались 3 кластера, действительно имеющие смысл. Остальные — просто статистический шум. Может, стоит пойти в другом направлении и проверить k = 3? Если вы хотите дать этой гипотезе шанс, я оставлю это вам как самостоятельную работу.
2. Кластерный анализ, часть I Рис. 2-40. Силуэт кластеризации по пяти средним Вместо этого предлагаю поразмыслить над тем, что мы делаем не так и откуда появляются эти непонятные кластеры, полные шума. K-медианная кластеризация и асимметрическое измерение расстояний Как правило, стандартной кластеризации по k-средним евклидовыми расстояниями бывает вполне достаточно, но тут мы столкнулись с небольшими проблемами, которые часто встречаются при кластеризации данных, имеющих большой разброс (розничная ли это торговля, классификация ли текстов или биоинформатика). Использование k-медианной кластеризации Первая очевидная проблема заключается в том, что ваши кластерные центры выражены десятыми долями от единицы, притом что вектор сделок каждого покупателя — точный ноль или единица. Что на самом деле значит 0,113 для сделки? Я хочу, чтобы кластерные центры выражали либо совершение сделки, либо ее отсутствие! Если немного изменить алгоритм кластеризации, чтобы он использовал только величины векторов сделок покупателей, то он уже будет называться кластеризацией по k-медианам, а не по k-средним. А если вы не хотите изменять евклидовым расстояниям, то все, что вам нужно — это добавить бинарное условие (bin) в «Поиске решения» для всех кластерных центров. 89
90 Много цифр Но если кластерные центры теперь бинарны, то как использовать евклидово расстояние? Переходим к соответствующему измерению расстояний Переключившись с k-средних на k-медианы, люди обычно перестают пользоваться евклидовым расстоянием и начинают использовать нечто под названием манхэттенское расстояние, или метрика городского квартала. Несмотря на то, что расстояние от точки А до точки В измеряется по прямой, такси на Манхэттене приходится перемещаться по сети прямых улиц, где возможны движения лишь на север, юг, запад или восток. Поэтому, если на рис. 2-13 вы видели, что расстояние между танцором-школьником и его кластерным центром равняется примерно 4,47, его манхэттенское расстояние будет равно 6 метрам (4 метра вниз + 2 метра вбок). В терминах бинарных данных, таких как данные о продажах, манхэттенское расстояние между кластерным центром и покупательским вектором — это просто число несоответствий. Если у кластерного центра 0 и у меня 0, то в этом направлении расстояние будет 0, а если встречаются 0 и 1, то есть числа не совпадают, то в этом направлении расстояние равно 1. Складывая их, вы получаете общее расстояние, которое является просто числом несовпадений. Действительно ли манхэттенское расстояние играет в решении ключевую роль? Перед тем, как погрузиться с головой в k-медианную кластеризацию с использованием манхэттенского расстояния, остановитесь и подумайте о данных. Что значит «покупатель совершил сделку»? Это значит, что он действительно хотел приобрести этот товар! Что значит «покупатель не совершил сделку»? Значит ли это, что он не хотел этот товар настолько, насколько хотел тот, который купил? Одинаково ли сильны положительный и отрицательный сигналы? Может, он и любит шампанское, но уже держит запас в подвале. Может, он просто не видел вашу рассылку за этот месяц. Есть масса причин, почему кто-то чего-то не делает, но всего несколько — почему действия совершаются. Другими словами, стоит обращать внимание на заказы, а не на их отсутствие. Есть затейливое словцо — «асимметрия» данных. Единицы более ценны, чем нули. Если один покупатель совпадает с другим по трем единицам, то это более важное совпадение, чем с третьим покупателем по трем нулям. Что бросается в глаза — так это малое количество ценных единиц в данных — вот они, «разреженные данные»!
2. Кластерный анализ, часть I Но подумайте, что означает для покупателя близость к кластерному центру с евклидовой точки зрения. Если у одного покупателя 1 по одной сделке и 0 по другой, оба эти значения одинаково важны при расчете, насколько бы близко к кластерному центру покупатель ни располагался. Вам нужен расчет асимметричного расстояния. А для переменных данных в бинарном коде вроде этих заказов вина существует уйма неплохих вариантов. Самый, наверное, широко используемый метод подсчета асимметричного расстояния для данных формата 0–1 называется расстоянием по косинусу. Расстояние по косинусу — это не так страшно, несмотря на тригонометрию Самый простой способ объяснить, что такое расстояние по косинусу — это проанализировать понятие «близость по косинусу». Рассмотрим пару двумерных бинарных векторов (1,1) и (1,0). В первом векторе были заказаны оба товара, в то время как во втором только первый. Вы можете представить эти векторы в пространстве и увидеть, что угол между ними — 45 градусов (рис. 2-41). Доставайте транспортир — проверим. Можно сказать, что их близость равна косинусу 45 градусов, что составляет 0,707. Но почему? Оказывается, косинус угла между двумя бинарными заказами — это: Число совпадений заказов в двух векторах, разделенное на произведение квадратных корней количества заказов первого и второго векторов В нашем случае два вектора (1,1) и (1,0) имеют один совпадающий заказ, так что в числителе будет 1, а в знаменателе — квадратный корень из 2 (две заключенные сделки), умноженный на корень из 1 заключенной сделки. В результате имеем 0,707 (рис. 2-41). Что примечательного в этом расчете? Причины три: счетчик в формуле считает только совпадения сделок, то есть он асимме• тричен и поэтому отлично подходит к данному случаю; квадратные корни из количества сделок по каждому вектору в знамена• теле обращают наше внимание на тот факт, что вектор, в котором совершены все сделки — назовем его неразборчивым — гораздо дальше отстоит от другого вектора, чем тот, в котором совершены те же сделки и не совершены несколько других. Вам нужно совпадение векторов, «вкусы» которых совпадают, а не один вектор, содержащий «вкусы» другого. 91
92 Много цифр для бинарных данных эта близость находится в промежутке между 0 и 1, • причем у двух векторов не получается 1, пока все их заказы не совпадут. Это означает, что 1 — близость по косинусу может использоваться как мера расстояния, называемая расстоянием по косинусу, которое также варьируется от 0 до 1. (1,1) (1,0) 45° cos(45°) = 1 совпадающий заказ 2 заказа = 0,707 1 заказ Рис. 2-41: Близость по косинусу на примере бинарных векторов А теперь все то же самое, но в Excel Пришло время дать шанс проявить себя k-медианной кластеризации с помощью расстояния по косинусу. ЗАМЕТКА Кластеризация с помощью расстояния по косинусу также иногда называется сферической по k-средним. В главе 10 вы увидите сферические k-средние в R. Будем последовательны и продолжим с k= 5. Снова начнем с копирования листа 5МС и переименования его, на этот раз в 5MedC. Так как кластерные центры должны быть бинарными, нужно удалить все, что туда понаписал «Поиск решения».
2. Кластерный анализ, часть I Единственные вещи, требующие изменения здесь (кроме добавления бинарного условия в «Поиск решения» для k-медиан), — это расчеты расстояний в строках с 34 по 38. Начните с ячейки М34, в которой находится расстояние между Адамсом и центром кластера 1. Чтобы сосчитать совпадения сделок у Адамса и кластера 1, нужно применить к этим двум столбцам SUMPRODUCT/СУММПРОИЗВ. Если у одного из них или у обоих встречается 0, строка остается пустой, но если у обоих 1, то это совпадение обрабатывается SUMPRODUCT/СУММПРОИЗВ и 1, помноженная на 1, остается 1. Что касается извлечения корня из количества сделок, совершенных в векторе, это просто SQRT//КОРЕНЬ, наложенный на SUM//СУММА вектора. Таким образом, уравнение расстояния можно записать как =1-SUMPRODUCT(M$2:M$33,$H$2:$H$33)/ (SQRT(SUM(M$2:M$33))*SQRT(SUM($H$2:$H$33))) =1-СУММПРОИЗВ(M$2:M$33,$H$2:$H$33)/ (КОРЕНЬ(СУММА(M$2:M$33))*КОРЕНЬ(СУММА($H$2:$H$33))) Обратите внимание на «1–» в начале формулы, что отличает близость по косинусу от расстояния по косинусу. Также, в отличие от евклидова расстояния, расчет расстояния по косинусу не требует использования формул массива. Так или иначе, когда вы вставите это в М34, следует добавить проверку на ошибки на случай, если кластерный центр окажется 0: =IFERROR(1-SUMPRODUCT(M$2:M$33,$H$2:$H$33)/ (SQRT(SUM(M$2:M$33))*SQRT(SUM($H$2:$H$33))),1) =ЕСЛИОШИБКА(1-СУММПРОИЗВ(M$2:M$33,$H$2:$H$33)/ (КОРЕНЬ(СУММА(M$2:M$33))*КОРЕНЬ(СУММА($H$2:$H$33))),1) Добавление формулы IFERROR/ЕСЛИОШИБКА избавляет вас от деления на 0. И если по какой-то причине «Поиск решения» выбирает кластерный центр, полностью состоящий из 0, вы можете предположить, что этот центр находится на расстоянии 1 от всего остального (1 как наибольшее значение бинарной переменной). Затем вы можете скопировать М34 вниз по столбцу до М38 и изменить ссылки столбца H на I, J, K или L. Так же, как в случае с евклидовым расстоянием, вы используете абсолютные ссылки ($) в формуле, так что можете перетаскивать ее куда вздумается без ущерба для столбца с кластерным центром. Таким образом, мы получили лист 5MedC (рис. 2-42), который пока абсолютно идентичен листу 5МС, с которым мы работали ранее. 93
94 Много цифр Теперь, чтобы найти кластеры, откройте «Поиск решения» и измените условие «<= 1» для Н2:L33 на бинарное. Нажмите «Выполнить». Вы можете отдохнуть полчасика, пока компьютер ищет для вас оптимальные кластеры. Вы сразу заметите, что все кластерные центры теперь — бинарные, так что у условного форматирования остаются два оттенка, что сильно повышает контраст. Рис. 2-42. Лист 5МedС еще не оптимизирован Рейтинг сделок для 5-медианных кластеров По завершении работы «Поиска решения» у вас образуется 5 кластерных центров, и в каждом — кучка единичек, указывающих на сделки, предпочитаемые этим кластером. Мой «Поиск решения» выдал оптимальное объективное значение 42,8, хотя ваше может серьезно отличаться (рис. 2-43). Давайте разберемся в этих кластерах, используя метод подсчета сделок, которым мы пользовались для k-средних. Для этого сперва скопируйте лист 5MC — TopDealsByCluster tab и назовите его 5MedC — TopDealsByCluster. Все, что нужно сделать на этом листе, чтобы заставить его работать, — это найти и заменить 5МС на 5MedC. Так как общий вид столбцов и строк у этих двух листов идентичен, все вычисления пройдут гладко, если ссылка на лист изменена. Ваши кластеры могут немного отличаться от моих и по порядку, и по составу из-за эволюционного алгоритма, но, надеюсь, отличия будут несущественными. Давайте пройдемся по кластерам и посмотрим, как этот алгоритм разделил покупателей.
2. Кластерный анализ, часть I Рис. 2-43. Медианы 5 кластеров Сортировка кластера 1: похоже, это мелкооптовый кластер (рис. 2-44). В кластер 2 попали покупатели, приобретающие только игристые вина. Шампанское, просекко и игристое доминируют в первых 11 позициях кластера (рис. 2-45). Интересно отметить, что подход k-средних не очень явно демонстрирует кластер любителей шипучего при k равном 4 или 5. Кластер 3 — кластер франкофилов. Пять самых крупных сделок — на французские вина (рис. 2-46). Разве они не знают, что калифорнийские вина лучше? Что касается кластера 4, то здесь только крупные сделки. И все самые популярные сделки — с большой скидкой и еще не прошли ценовой максимум (рис. 2-47). Кластер 5 снова оказался кластером пино нуар (рис. 2-48). Так почище, не правда ли? Это оттого, что метод k-медиан, используя асиметричные методы измерения расстояний вроде равенства косинусов, позволяет кластеризировать клиентов, основываясь больше на их предпочтениях, чем на антипатиях. Ведь нас интересует именно это! 95
96 Много цифр Рис. 2-44. Сортировка кластера 1 — мелкооптовые покупатели Рис. 2-45. Сортировка кластера 2 — шипят не только змеи
2. Кластерный анализ, часть I Рис. 2-46. Сортировка кластера 3 — франкофилы Рис. 2-47. Сортировка кластера 4 — большие объемы 19 сделок подряд 97
98 Много цифр Рис. 2-48. Сортировка кластера 5 — пино нуар держит позиции Вот на что способна мера расстояния! Теперь вы можете взять привязки к этим пяти кластерам, импортировать их обратно в MailChimp.com как объединенное поле в списке писем и использовать эти значения для настройки вашей маркетинговой рассылки по кластерам. Это должно помочь вам лучше подбирать покупателей и управлять продажами. Подытожим В этой главе было описано много разных отличных приемов. Вспомним все, что вы увидели и узнали: евклидово расстояние; • кластеризацию методом k-средних с использованием «Поиска решения» • для оптимизации центров; как понимать кластеры, раз уж они у вас есть; • как рассчитать силуэт, данный по k-средним; • k-медианную кластеризацию; • манхэттенское расстояние / расстояние городского квартала; • близость и расстояние по косинусу. • Дочитав главу до конца, вы должны научиться не только кластеризировать данные, но еще и понять, на какие вопросы ведения бизнеса можно ответить
2. Кластерный анализ, часть I с помощью кластеризации, а также как подготовить свои данные к кластеризации. Кластеризация методом k-средних определенно является стартовой площадкой для всех ищущих сегментации и пытающихся извлечь полезную информацию из данных о покупателях. Но это не самая «общеупотребительная» техника кластеризации. В главе 5 вы познакомитесь с сетевыми графами, помогающими находить сообщества покупателей, пользуясь все тем же набором данных. У вас даже будет экскурсия во внешний мир (относительно Excel), правда, очень краткая, для пущей наглядности данных. Вы хотите самостоятельно продвинуться в кластеризации по k-средним? Не забывайте, что стандартный Excel способен управиться только с 200 переменными «Поиска решения», поэтому советую обновить надстройку на нелинейный решатель получше (к примеру, PremuimSolver с сайта Solver.com или просто мигрировать в LibreOffice), чтобы кластеризировать данные во многих измерениях сделок и пользоваться большими значениями k. Большинство программ для статистики предлагает возможности кластеризации. Например, R выпускается с функцией k-средних; так или иначе, более широкие возможности открывает пакет fastcluster, в который входят k-медианы и набор функций расстояния. В главе 10 вы познакомитесь с пакетом skmeans для применения сферических k-средних. 99

3 Наивный байесовский классификатор и неописуемая легкость бытия идиотом В предыдущей главе вы отлично справились с началом неконтролируемого машинного обучения. Вы ознакомились с кластеризацией по k-средним, которая похожа на куриный наггетс в измерении извлечения данных (data mining) — простой, интуитивный и практичный. И к тому же вкусный. В этой главе мы перейдем от неконтролируемого машинного обучения к моделям контролируемого искусственного интеллекта, а тренироваться будем на наивной байесовской модели, которая, простите за недостаток хороших метафор, тоже похожа на куриный наггетс, несмотря на контролируемость. Как уже упоминалось в главе 2, в случае с контролируемым искусственным интеллектом вы «обучаете» свою модель делать расчет, пользуясь уже классифицированными данными. Самое распространенное применение «наивного Байеса» — классификация документов. Является ли это электронное письмо спамом или наоборот, долгожданной новостью? Эта запись в Twitter — благодушная или сердитая? Нужно ли передавать этот перехваченный звонок по сотовому для дальнейшего исследования федеральным агентам? Вы предоставляете «данные для обучения», например, классифицированные примеры документов, обучающему алгоритму, который в дальнейшем сможет «разбить» новые документы на те же категории, используя имеющиеся знания. Пример, над которым мы будем работать в этой главе, мне особенно близок. Позвольте объяснить. Называя продукт Mandrill, ждите помех вместе с сигналами Недавно компания, в которой я работаю, начала новый проект под названием Mandrill.com. Логотип у этого проекта — самый страшный из всех мною виденных (рис. 3-1).
102 Много цифр Mandrill — это транзакционный сервис для отправки электронных писем, предназначенный разработчикам приложений, которые хотят, чтобы их детища отправляли одноразовую информацию: письма, счета, восстановленные пароли и все остальное, что передается лично, из рук в руки. Так как он позволяет отслеживать открытие отдельного транзакционного письма и переходы по ссылкам, вы можете подключить этот сервис к своей личной почте и следить, действительно ли ваши родственники открывают и рассматривают все фото вашего котика, которые вы им непрерывно присылаете. Рис. 3-1. Гипнотизирующий логотип Mandrill Но с момента запуска Mandrill меня постоянно раздражала одна вещь. При том, что MailChimp придумали мы же, Mandrill — тоже примат — стал занимать его экологическую нишу! И они оба довольно популярны. А ведь еще Дарвин называл разноцветный зад мандрила «экстраординарным». К чему я клоню? Зайдя в Twitter и посмотрев записи с упоминанием продукта Mandrill, вы увидите то, что изображено на рис. 3-2. Нижний твит — о новом модуле, подключающем язык программирования Pearl к Mandrill. И это единственный релевантный твит. Те два, что выше, — про Spark Mandrill из игры Megaman X для Super Nintendo и группу под названием Mandrill. Ужас! Даже если вам в школьные годы нравился Megaman X, многие записи нерелевантны вашему поиску. Разумеется, туда попадает еще куча твитов о группе,
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Рис. 3-2. Три твита — и только один из них имеет отношение к нашему проекту об игре, о животных, а также других пользователях Twitter, в имени которых есть «mandrill», и всего три — о Mandrill.com. Это называется помехами. Много помех. Так возможно ли создание модели, которая способна отличить сигнал от помех? Может ли модель ИИ извещать вас только о твитах о почтовом продукте Mandrill? Итак, мы столкнулись с типичной проблемой классификации документов. Если документ, такой, как твит о Mandrill, может принадлежать к нескольким классам (он может быть о Mandrill.com, а может — о других мандрилах), то к какому классу его следует отнести? Самый распространенный подход к решению этой проблемы — это использование модели «набор слов» (bag of words) в сочетании с наивным байесовским классификатором. Модель «набор слов» воспринимает документ как беспорядочное множество слов. «Джонни съел сыр» для него то же самое, что «сыр съел Джонни» — и то и другое состоит из одного и того же множества слов:{«Джонни», «съел», «сыр»}. Наивный байесовский классификатор снабжается обучающим набором уже классифицированных «наборов слов». К примеру, можно загрузить в него несколько наборов о-приложении-Mandrill и несколько — о-других-мандрилах и обучать его отличать одно от другого. В будущем вы сможете скормить ему неизвестный набор слов, и он классифицирует его для вас. Именно этим мы и займемся в данной главе — созданием наивного байесовского классификатора документов, который воспринимает твиты о мандрилах как наборы слов и выдает вам классификацию. И это будет весьма забавно. Почему? Потому что наивный байесовский классификатор часто называют «идиотским Байесом». Как вы увидите ниже, придется делать множество неуклюжих, идиотских предположений насчет ваших данных, и все равно они сработают! Это что-то вроде рисования брызгами в моделировании ИИ. Из-за крайней 103
104 Много цифр простоты исполнения (он может уложиться в 50 строк кода) компании постоянно их используют для простых классификационных задач. С его помощью можно классифицировать электронную почту организации, записи поддержки пользователей, новостную рассылку, журнал полицейских приводов, медицинские документы, обзоры кинофильмов — что угодно! Перед тем, как начать применять эту замечательную штуку в Excel (что, на самом деле, довольно просто), вам придется освоить немного теории вероятности. Прошу прощения. Если вы запутаетесь в математике, просто втягивайтесь в процесс. Все окажется крайне просто, вот увидите! Самое быстрое в мире введение в теорию вероятности В двух следующих разделах я буду применять выражение р() для обозначения вероятности. Например: р(следующий фильм Майкла Бэя будет ужасным)= 1 р(Джон Форман когда-нибудь станет вегетарианцем)= 0,0000001 Извините, очень маловероятно, что я когда-либо откажусь от копченых колбасок — единственной вещи, которая мне нравится в Алабаме! Суммируем условную вероятность Ну что ж, предыдущие два примера были просто вероятностями, но в этой главе мы будем работать в основном с условной вероятностью. Вот как она выглядит: р(Джон Форман станет вегетарианцем | вы заплатите ему миллиард долларов)= 1 Вероятность того, что я когда-нибудь стану вегетарианцем очень низка. Однако если вы дадите мне за это превращение миллиард долларов, она немедленно возрастет до 100%. Этот вертикальный значок «|» используется для отделения события от условий в выражении. Как совместить вероятность перехода на вегетарианство в 0,0000001 с какой-то условной вероятностью? С помощью закона о полной вероятности. Вот как он работает: вероятность того, что я стану вегетарианцем, равна сумме вероятностей того, что я стану вегетарианцем при всех возможных условиях, умноженной на вероятность того, что они произойдут:
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом р(вегетарианство) = р(миллиард долларов) × (вегетарианство | миллиард долларов) + р(не миллиард долларов) × (вегетарианство | не миллиард долларов) = 0,0000001 Полная вероятность — это взвешенная сумма всех условных вероятностей, умноженная на вероятность этих условий. А вероятность условия, что вы дадите мне миллиард долларов, равна нулю (практически уверен в справедливости утверждения). Это означает, что р(не миллиард долларов) = 1, и у нас получается р(вегетарианство) = 0×р(вегетарианство | миллиард долларов) + р(вегетарианство | не миллиард долларов) = 0,0000001 р(вегетарианство) = 0×1 + 1×0,0000001 = 0,0000001 Совместная вероятность, цепное правило и независимость Есть еще одно понятие теории вероятности — совместная вероятность, которая есть не что иное, как хитрый способ сказать «и». Вспомните свои вступительные экзамены. Вот вероятность того, что сегодня на обед я съем тако белл: р(Джон ест тако белл) = 0,2 Обычно я делаю это раз в неделю. А вот вероятность того, я буду слушать сегодня какую-нибудь попсовенькую электронную музычку: р(Джон слушает электронную музычку) = 0,8 Это очень вероятно. А каковы же шансы того, что я буду делать сегодня и то и другое? Это называется совместной вероятностью и записывается следующим образом: р(Джон ест тако белл, Джон слушает электронную музычку) Просто разделяем два события запятой. Эти события, в нашем случае, независимы. Это значит, что прослушивание электронной музыки никак не связано с поеданием тако. Зная об их независимости друг от друга, можно просто перемножить эти две вероятности и получить совместную вероятность следующим образом: 105
106 Много цифр р(Джон ест тако белл, Джон слушает электронную музычку) = 0,2 × 0,8 = 0,16 Это называется одним из правил умножения вероятностей. Отметим, что совместная вероятность всегда ниже вероятности происхождения какого-либо одного из событий, что весьма логично. Выигрыш в лотерею в тот день, когда вас ударит молнией, гораздо менее вероятен, чем любое из этих событий в отдельности. Один из способов увидеть эту зависимость — цепное правило вероятности, которое выглядит так: р(Джон ест тако белл, Джон слушает электронную музычку) = р(Джон ест тако белл) × р(Джон слушает электронную музычку | Джон ест тако белл) Совместная вероятность — это вероятность происхождения одного события, умноженная на вероятность происхождения второго при условии, что произойдет первое. Но так как эти два события не зависят друг от друга, условие не имеет значения. Я буду слушать попсовое техно в том же объеме, несмотря на обед: р(Джон слушает электронную музычку | Джон ест тако белл) = р(Джон слушает электронную музычку) Это сводит цепное правило к простому: р(Джон ест тако белл, Джон слушает электронную музычку) = р(Джон ест тако белл) × (Джон слушает электронную музычку) = 0,16 Что же с зависимыми событиями? Я введу новую вероятность — вероятность того, что сегодня я буду слушать Depeche Mode: р(Джон слушает Depeche Mode) = 0,3 Есть 30%-ная вероятность, что я запилю немного DM сегодня. Не судите меня. Теперь у меня есть два события, зависящие друг от друга: прослушивание электроники или DM. Почему? Да потому что DM и есть попсовое техно! А это значит: р(Джон слушает электронную музычку | Джон слушает DM) = 1 Если я слушаю Depeche Mode сегодня, то есть 100%-ная вероятность, что я слушаю попсовое техно. Это тавтология. Так как Depeche Mode достаточно
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом попсовый, вероятность того, что я слушаю попсовое техно при том, что я слушаю Depeche Mode, равна 1. А это значит следующее: если я хочу вычислить совместную вероятность этих событий, я не просто их перемножаю. Следуя цепному правилу, р(Джон слушает электронную музычку, Джон слушает DM) = р(Джон слушает DM) × (Джон слушает электронную музычку | Джон слушает DM) = 0,3 × 1 = 0,3 Правило Байеса Так как я определил Depeche Mode как попсовое техно, вероятность того, что я слушаю попсовое техно при том, что я слушаю Depeche Mode, равна 1. Но нет ли других способов? У нас еще нет вероятности для этого утверждения: р(Джон слушает Depeche Mode | Джон слушает попсовое техно) В конце концов, существуют же другие популярные группы, которые играют техно. Может, Kraftwerk? Или новый альбом Daft Punk? Один милый джентльмен по фамилии Байес придумал правило: р(попса) × р(DM | попса) = р(DM) × р(попса | DM) Это правило позволяет вам рассчитать отношение условного события к вероятности, если событие и условие меняются местами. Перейдя к сокращенным названиям переменных, мы видим, что можно изолировать вероятность, которая нам неизвестна (вероятность того, что я слушаю DM при том, что я слушаю попсовое техно): р(DM | попса) = р(DM) × р(попса | DM) / р(попса) Эта формула — самый распространенный вид правила Байеса. В общем-то это способ крутить условными вероятностями. Когда вам известна условная вероятность только с одной стороны, а также полные вероятности события и условия, вы можете легко все перевернуть. Подставляя значения, получим: р(DM | попса) = 0,3 × 1 / 0,8 = 0,375 Я буквально имею 30%-ный шанс слушать Depeche Mode в любой день. Так или иначе, если я знаю, что собираюсь послушать какое-нибудь попсовое 107
108 Много цифр техно сегодня, шансы, что это будет Depeche Mode подскакивают до 37,5%! Отлично. Использование правила Байеса для создания моделирования Ну что ж, пора оставить в покое мои музыкальные вкусы и вернуться к проблеме твитов о мандрилах. Каждая запись для нас представляет набор слов, то есть мы разбиваем каждый твит на слова (часто называемые жетонами — token) пробелами и пунктуацией. Есть два класса твитов: о приложении — твиты о Mandrill.com, и другие — все остальные твиты. Нам важны эти две вероятности: р(приложение | слово1, слово2, слово3, …) р(другое | слово1, слово2, слово3, …) Это вероятность того, что твит либо о приложении, либо о чем-то другом, при том, что мы видим слова «слово1», «слово2», «слово3» и т. д. Стандартное применение наивной байесовской модели классификатора — это создание нового документа на основе того, к какому классу вероятнее всего относятся твиты, если рассматриваются слова, из которых они состоят. Другими словами, если р(приложение | слово1, слово2, слово3, …) > р(другое | слово1, слово2, слово3, …) то данный твит — о Mandrill.com. Правило, использованное для решения этой задачи — по которому выбирается наиболее вероятный класс, опираясь на слова, — известно как правило апостериорного максимума (МАР). Но как же вычислить эти две вероятности? Первый шаг — использование правила Байеса. С помощью него можно переписать условную вероятность приложения как р(приложение | слово1, слово2, слово3, …) = р(приложение) р(слово1, слово2, слово3, …| приложение) / р(слово1, слово2, слово3, …) Точно так же р(другое | слово1, слово2, слово3, …)= р(другое) р(слово1, слово2, слово3, … | другое) / р(слово1, слово2, слово3, …)
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Но, заметьте, у обоих этих вычислений в делителе р(слово1, слово2, слово3, …) Такая конфигурация — просто вероятность того, что эти слова вообще встретятся в документе. Так как эта величина не меняется от класса к классу, вы можете сократить на нее неравенство МАР, еще и при том, что вас интересует только наибольшее значение из р(приложение) р(слово1, слово2, слово3, …) р(другое) р(слово1, слово2, слово3, …) Но как подсчитать вероятность наличия набора слов, зная, что эта запись — про приложение или, наоборот, о чем-то другом? И тут все действительно начинает становиться идиотским! Предположим, вероятности наличия этих слов в документах не зависят одна от другой. Тогда получаем р(приложение) р(слово1, слово2, слово3, …| приложение) = р(приложение) р(слово1| приложение) р(слово2 |приложение) р(слово3| приложение)… р(другое) р(слово1, слово2, слово3, …| другое) = р(другое) р(слово1|другое) р(слово2 | другое) р(слово3| другое)… Предположение о независимости позволяет разбить эту совместную условную вероятность набора слов при известном классе на вероятности нахождения каждого слова в данном классе. И что же в этом идиотского? Да то, что слова в документе зависят друг от друга! Если вы классифицируете спам и у вас в документе два слова — «эректильная» и «дисфункция» — то это значит р(эректильная, дисфункция | спам) = р(эректильная | спам) р(дисфункция | спам) Ну это же идиотизм, не так ли? Это наивность, потому что если бы я вам сказал, что у меня есть письмо-спам со словом «дисфункция» и предложил бы отгадать предшествующее ему слово, вы бы почти наверняка сказали «эректильная». Это зависимость, которая откровенно игнорируется. Самое смешное, что, несмотря на широкое практическое применение, этот идиотизм никого не волнует. Это из-за того, что правилу МАР все равно, что 109
110 Много цифр вы правильно рассчитали вероятности своих классов. Для него имеет значение лишь то, какое из неправильно рассчитанных значений вероятности больше. Принимая слова как независимые, мы вносим в этот расчет множество ошибок, но, по крайней мере, эта небрежность повсеместна. Неравенства, используемые в правиле МАР, обычно проявляются так же, как если бы вы применяли разностороннее понимание лингвистики в модели. Высококлассные вероятности часто считаются равными Напомню, что в случае с приложением Mandrill мы хотим классифицировать твиты, основываясь на том, которая величина больше: р(приложение) р(слово1, слово2, слово3, …| приложение) = р(приложение) р(слово1| приложение) р(слово2 |приложение) р(слово3| приложение)… р(другое) р(слово1, слово2, слово3, …| другое) = р(другое) р(слово1|другое) р(слово2 | другое) р(слово3| другое)… Так какова же вероятность р(приложение) и р(другое)? Вы можете войти в Twitter и увидеть, что р(приложение) на самом деле около 20%. 80% записей, содержащих слово «mandrill», совсем о другом. Несмотря на то, что сейчас это верно, со временем все может измениться, и я бы предпочел огромное количество твитов, классифицированных как твиты о приложении (но на самом деле таковыми не являющихся — ложноположительных), отфильтровке нескольких релевантных (ложноотрицательных), так что я оцениваю свои шансы примерно 50/50. Вы постоянно будете встречать это предположение в наивном байесовском классификаторе в реальном мире, особенно в фильтрации спама, где процент спама в почте все время меняется и измерить его в глобальных масштабах довольно сложно. Но если мы примем и р(приложение), и р(другое) за равные 50%, то во время сравнения двух величин с помощью правила МАР вы можете просто не обращать на них внимания. Таким образом, классифицируйте твит как относящийся к приложению, если р(приложение) р(слово1|приложение) р(слово2 |приложение) р(слово3| приложение)… >= р(слово1|другое) р(слово2 |другое) р(слово3| другое)… Но как вычислить вероятность слова в классе? К примеру, рассмотрим такую вероятность: р(«блестеть» | приложение)
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Для этого нужно взять тренировочный набор твитов о приложении, разбить их на слова, подсчитать эти слова и найти процент слов, являющихся словом «блестеть». Почти наверняка это будет 0, потому что большинство твитов о мандрилах, содержащее слово «блестеть» относятся к видеоигре. Остановитесь на секунду и подумайте об этом. Чтобы построить модель наивного байесовского классификатора, вам нужно лишь отследить частоту использования слов, связанных и не связанных с приложением, за промежуток времени. А это несложно! Еще немного деталей классификатора Перед началом работы с Excel нужно понять, что делать с двумя практическими препятствиями применения наивного Байеса в Excel или любом другом языке программирования: редкие слова; • исчезновение порядка (антипереполнение). • Что делать с редкими словами Первая проблема — это проблема редких слов. Что, если в записи, которую вы собрались классифицировать, есть слово «Тубал-Каин»? Основываясь на данных из тренировочного набора, можно сделать вывод, что ни в одном из классов такого слова нет. Место, где такое часто происходит в твиттере — это сокращенные адреса страниц, так как каждая новая ссылка, помещенная в Twitter, должна иметь новый код, никогда не использованный ранее. Вы можете предположить: р(«Тубал-Каин» | приложение) = 0 Но тогда вы получите: р(«Тубал-Каин» | приложение) р(слово2 | другое) р(слово3 | другое)… = 0 Тубал-Каин эффективно обнуляет все вычисление вероятности. Предположим, что вы все же встречали слово «Тубал-Каин» однажды. Можно поступить так со всеми редкими словами. Но постойте — это же несправедливо по отношению к словам, которые вам действительно однажды встречались! Ну ладно, прибавьте и к ним 1. Но тогда это несправедливо для слов, которые встретились вам дважды. Ладно, добавьте 1 на каждый счет. 111
112 Много цифр Это называется дополнительным сглаживанием и часто используется для приспособления неведомых ранее слов к модели наборов слов (bag of words). Что делать с исчезновением порядка Теперь, когда мы разобрались с редкими словами, перейдем к следующей проблеме — исчезновения порядка. Многие из встречаемых слов — редкие, поэтому в итоге получаются очень маленькие вероятности. В нашем случае большинство слов имеет вероятности менее 0,001. И из-за предположения о независимости приходится еще и перемножать эти ничтожные вероятности друг с другом. Что, если у вас есть запись из 15 слов, вероятность каждого из которых меньше 0,001? В итоге в неравенстве МАР вы получите микроскопическое значение вроде 1 × 10–45. На самом деле Excel вполне способен обработать настолько малую величину. Он начинает спотыкаться только на сотне-другой нулей после запятой. Так что для классификации твитов такая величина вполне может сойти. Но для более объемных документов (например, писем, новостных статей) маленькие величины могут нанести серьезный ущерб вычислениям. Просто чтобы больше не думать об этом, давайте поищем способ не делать умножение в МАР напрямую: р(слово1|приложение) р(слово2 |приложение) … >= р(слово1|другое) р(слово2 |другое) … Эту проблему можно решить, используя функцию логарифма (натуральный логарифм в Excel задается формулой LN). Вот вам забавный факт из математики. Допустим, у вас есть произведение: 0,2 × 0,8 Если вы прологарифмируете его, будет верно следующее: ln(0,2 × 0,8) = ln(0,2) + ln(0,8) Вычисляя натуральный логарифм любого числа между 0 и 1, вместо мизерного значения с кучей нулей после запятой вы получаете четкое отрицательное число. Так что вы можете взять натуральный логарифм от каждой вероятности и сложить их, чтобы получить максимум для последующего сравнения. Это дает значение, на которое не будет ругаться компьютер. Если вы немного растерялись, не волнуйтесь. В Excel все станет ясно и понятно.
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Да начнется Excel-вечеринка! ЗАМЕТКА Электронная таблица Mandrill.xslx, используемая в этой главе, находится на сайте книги, www.wiley.com/go/datasmart. Эта таблица содержит все исходные данные для того, чтобы вы могли работать вместе со мной. Можете также просто следить за ходом повествования, используя листы, в которых все расчеты уже совершены. В электронной таблице для этой главы — Mandrill.xslx, есть два листа с исходными данными. Первый, AboutMandrillApp, содержит 150 твитов, по одному на строку, относящихся к приложению Mandrill. Второй, AboutOther, содержит 150 твитов об остальных мандрилах. Перед началом хочу сказать — добро пожаловать в мир обработки естественного языка (Native Language Processing, NLP)! NLP пережевывает текст, написанный человеком, и выплевывает знания. «Человеческое» содержимое (например, записи в Twitter) готово для потребления компьютером. Перед этим необходимо провести несколько мелких операций. Убираем лишнюю пунктуацию Первый шаг в создании набора слов из твита — это токенизирование слов, разделенных пробелами. Но не все, что отделено пробелами, является словами. Нужно перевести все буквы в строчные и удалить пунктуацию, потому что в Twitter пунктуация далеко не всегда что-то значит. Причина понижения регистра в том, что «e-mail» и «E-mail» не различаются по значению. Поэтому в ячейку В2 на обоих листах добавьте формулу: =LOWER(A2) =СТРОЧН(А2) Это переведет первую запись в строчной вид. В С2 вырежем все фразы. Не стоит кромсать ссылки, так что вырежем все части, после которых есть пробел с помощью команды SUBSTITUTE/ПОДСТАВИТЬ: =SUBSTITUTE(В2,". "," ") =ПОДСТАВИТЬ(В2,". "," ") Эта формула заменяет знаки ". " единичным пробелом " ". Вы также можете указать ячейку D2 в С2 и заменить все двоеточия с пробелами после них единичными пробелами: 113
114 Много цифр =SUBSTITUTE(С2,": "," ") =ПОДСТАВИТЬ(С2,": "," ") В ячейках от Е 2 до Н2 необходимо сделать такие же замены знаков "?", "!", ";" и ",": =SUBSTITUTE(D2,"?"," =SUBSTITUTE(E2,"!"," =SUBSTITUTE(F2,";"," =SUBSTITUTE(G2,","," =ПОДСТАВИТЬ(D2,"?"," =ПОДСТАВИТЬ(E2,"?"," =ПОДСТАВИТЬ(F2,"?"," =ПОДСТАВИТЬ(G2,"?"," ") ") ") ") ") ") ") ") Не нужно добавлять пробел после знаков препинания в предыдущих четырех формулах, потому что они почти не встречаются в ссылках (особенно в сокращенных). Выделите ячейки В2:Н2 на обоих листах и кликните дважды на формуле, чтобы разослать ее дальше по листу до строки 151. Получатся два листа, вроде того, что изображен на рис. 3-3. Рис. 3-3. Подготовленные данные о твитах Разное о пробелах Теперь создайте два новых листа и назовите их AppTokens и OtherTokens. Вам необходимо сосчитать, сколько раз каждое слово используется в записях данной категории. Это значит, что вам нужно собрать все слова из твитов в одном столбце. Резонно предположить, что каждый твит содержит не более
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом 30 слов (но вы смело можете увеличить их количество до 40 или даже 50), так что если вы собираетесь присваивать каждому жетону отдельную строку, вам понадобится 150 × 30 = 4500 строк. Для начала назовите ячейку А1 на обоих листах «Tweet». Выделите А2:А4501 и с помощью специальной вставки вставьте значения твитов из столбца Н двух начальных листов. Таким образом вы получите список всех обрабатываемых твитов, как показано на рис. 3-4. Обратите внимание: так как вы вставляете 150 твитов в 4500 строк, Excel повторяет все за вас. Восхитительно! Это означает, что если вы выделите первое слово из первого твита в строке 2, этот самый твит повторится для выделения второго слова в строке 152, третьего — в 302 и т. д. Рис. 3-4. Исходный лист AppTokens В столбце В вам нужно отметить положение каждого следующего пробела между словами в записи. Можете назвать этот столбец, например, Space Position. Так как в начале каждого твита больше нет пробелов, начните с помещения 0 в ячейки А2:А151, чтобы отметить, что слова начинаются с первого символа каждого твита. Начиная с В152 после первого полного повтора твитов можно рассчитать положение следующего пробела: =FIND(" ",A152,B2+1) =НАЙТИ(" ",A152,B2+1) Формула FIND/НАЙТИ будет искать в твитах следующий пробел, считая знаки от предыдущего, упомянутого в В2, который находится 150 строками выше, как показано на рис. 3-5. 115
116 Много цифр Рис. 3-5. Положение второго слова в твите, рассчитанное по знакам, строка 152 Так или иначе, помните, что эта формула выдаст ошибку, как только закончатся символы в записи — если в ней, к примеру, меньше 30 слов, которые вы планировали. Чтобы справиться с этим, вам нужно вставить формулу в утверждение IFERROR/ЕСЛИОШИБКА и просто прибавить 1 к длине твита, чтобы найти положение после последнего слова: =IFERROR(FIND(" ",A152,B2+1),LEN(A152)+1) =ЕСЛИОШИБКА(НАЙТИ(" ",A152,B2+1),LEN(A152)+1) Затем вы можете кликнуть дважды на этой формуле, чтобы распространить ее по таблице до А4501. Так получится лист, изображенный на рис. 3-6. Рис. 3-6. Положение каждого пробела в твите Затем в столбце С можно начать извлекать единичные жетоны (token) из твитов. Назовите столбец С Token и начиная с С2 перетаскивайте
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом подходящие слова с помощью функции MID/ПСТР. Эта функция извлекает из строки текста начальное положение и количество символов. Так, в С2 наш текст находится в А2, начальное положение — 1 после последнего пробела (В2+1), а длина — это разница между последующим положением пробела в В152 и текущим в В2 минус 1 (не забываем, что твиты повторяются через каждые 150 строк). Получается следующая формула: =MID(A2,B2+1,B152-B2–1) =ПСТР(A2,B2+1,B152-B2–1) Теперь еще раз вернемся к коротким твитам в конце строки, в которых у нас рано заканчивались слова. Если есть ошибка, превратите этот жетон в комбинацию «.», которую потом легко будет проигнорировать: =IFERROR(MID(A2,B2+1,B152-B2–1),".") =ЕСЛИОШИБКА(ПСТР(A2,B2+1,B152-B2–1),".") Теперь вы можете распространить эту формулу на весь лист двойным щелчком, чтобы токенизировать каждый твит, как показано на рис. 3-7. Добавьте столбец Length в D и в ячейке D2 получите длину жетона в С2 в символах: =LEN(C2) =ДЛСТР(С2) Можете также распространить это на весь лист двойным кликом. Это значение позволяет вам находить и удалять любой жетон в три или менее символов, которые практически всегда бессмысленны. Рис. 3-7. Каждый твитовый жетон 117
118 Много цифр ЗАМЕТКА Обычно в таком типе обработки натурального языка кроме удаления всех коротких слов существует еще список стоп-слов для отдельного языка (в данном случае, английского), которые также удаляются. Стоп-слова — это слова с очень низким лексическим содержанием, которое подобно содержанию питательных веществ для модели «набор слов». К примеру, «потому что» и «вместо» могут быть стоп-словами из-за того, что они обычные и не особенно помогают отличить один документ от другого. Самые распространенные стоп-слова в английском почти всегда короткие: «a», «and», «the» и т. д., поэтому в данной главе будет рассмотрен наиболее простой, но и наиболее драконовский способ удаления коротких слов из твитов. Если вы все делали вместе со мной, у вас должен получиться лист AppTokens, показанный на рис. 3-8 (лист Other Tokens идентичен ему, за исключением твитов, вставленных в столбец А). Рис. 3-8. Жетоны для приложения, соответственно, со своей длиной Подсчет жетонов и вычисление вероятностей Теперь, токенизировав свои твиты, вы готовы к расчету условной вероятности жетона, р(жетон | класс). Чтобы произвести расчет, вам нужно определить, сколько раз использовался каждый жетон. Начните с листа AppTokens, выбирая жетон и область длины С1:D4501 и потом вставьте данные в сводную таблицу. Переименуйте полученную сводную таблицу в AppTokensProbability. В конструкторе сводных таблиц отфильтруйте жетоны по длине и поставьте их по горизонтали, а в окне значений установите значение для подсчета количества каждого жетона. Настройка конструктора показана на рис. 3-9.
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом В самой сводной таблице в фильтре по длине снимите галочки с жетонов длиной в 0, 1, 2 и 3, чтобы не использовать их (в Windows нужно проинструктировать Excel, что вы собираетесь сделать множественный выбор в выпадающем меню). Это тоже видно на рис. 3-9. Рис. 3-9. Настройка конструктора сводных таблиц для подсчета жетонов Теперь у вас есть только длинные жетоны из каждого твита, и все они подсчитаны. Настало время «пристегнуть» вероятность к каждому жетону. Перед запуском расчета примените оговоренную ранее функцию дополнительного сглаживания, добавив 1 к каждому жетону. Назовите столбец С Add One To Everything и установите С5 = В5 + 1 (С4 + В4 в Windows, где Еxcel строит сводные таблицы на строку выше, просто чтобы рассердить читателей). Вы можете распространить формулу двойным щелчком. Так как вы добавили 1 ко всему, вам понадобится новый подсчет жетонов. Внизу таблицы (строка 828 на листе AppTokensProbability) введите в ячейку 119
120 Много цифр сумму всех ячеек, находящихся над ней. Еще раз отмечу, что если вы работаете с Windows, то все сведется на одну строку выше (С4:С826 для суммирования): =SUM(С5:С827) =СУММА(С5:С827) В столбце D можно рассчитать вероятность для каждого жетона, основываясь на его количестве в столбце С, деленном на общее число жетонов. Назовите этот столбец P(Token|App). Вероятность для первого жетона находится в D5 (D4 в Windows) и рассчитывается так: =C5/C$828 Обратите внимание на абсолютную ссылку в общем числе жетонов. Это позволяет вам отправить формулу на весь столбец D двойным щелчком. Затем в столбец Е (назовем его LN(P)) можно поместить натуральный логарифм вероятности из D5: =LN(D5) Применив эту формулу ко всему листу, получаем все необходимые значения для правила МАР, как на рис. 3-10 Рис. 3-10. Логарифмированные вероятности для жетонов, относящихся к приложению Точно так же поступаем с жетонами о других мандрилах и создаем лист OtherTokensProbabilities.
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом У нас есть модель! Воспользуемся ею В отличие от регрессивной модели (которая встретится вам в главе 6), оптимизационного этапа здесь не будет. Никакого «Поиска решения», никакой подгонки модели. Модель байесовского классификатора — не что иное, как две таблицы условной вероятности. Это одна из причин, по которым эту модель любят программисты. Здесь нет сложного этапа подгонки — достаточно подбросить побольше жетонов и сосчитать их. А еще вы можете сохранить получившийся словарь жетонов у себя на диске для дальнейшего использования. Гениально просто! Теперь, когда модель классификатора «обучена», настало время ее использовать. На листе TestTweets в «Рабочей тетради» вы найдете 20 твитов, 10 о приложении, 10 — о другом. Вам нужно подготовить эти твиты, токенизировать их (ради интереса сделаем это немного по-другому), рассчитать логарифмированные вероятности для жетонов обоих классов и определить их наиболее вероятную принадлежность. Для начала скопируем ячейки В2:Н21 из листа AboutMandrillApp и вставим их в D2:J21 листа TestTweets. Получаем лист, изображенный на рис. 3-11. Рис. 3-11. Подготовленные тестовые твиты 121
122 Много цифр Теперь создадим новый лист и назовем его TestPredictions. Вставим в него столбцы Number и Class из TestTweets. Назовем столбец С Prediction, который впоследствии заполним предполагаемыми значениями классов. Затем назовем столбец D Tokens и вставим в D2:D21 значения из столбца J из листа TestTweets. Получается лист, изображенный на рис. 3-12. Рис. 3-12. Лист TestPredictions В отличие от построения таблиц вероятности, не нужно комбинировать жетоны, содержащиеся во всех твитах. Следует оценивать каждый твит отдельно, что делает токенизирование довольно простым. Сначала выделите твиты в D2:D21 и выберите «Текст по столбцам» во вкладке меню «Данные». В появившемся «Мастере текстов», выберите «С разделителями» и нажмите «Далее». Второй шаг мастера — выберите знаки табуляции и пробела в качестве разделителей. Также можно выбрать «Считать последовательные разделители одним» и убедиться, что ограничитель строк установлен на {нет}. Настройка мастера показана на рис. 3-13. Нажмите «Готово». Это разбросает твиты по столбцам всего листа до столбца AI, как на рис. 3-14. Под списком жетонов в столбце D в строке 25 нужно найти вероятность отношения к приложению для каждого жетона. Для этого можно использовать функцию VLOOKUP/ВПР (в главе 1 эта функция описана более подробно), начиная с ячейки D25:
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Рис. 3-13. Настройка мастера текстов Рис. 3-14. Жетоны из тестовых твитов =VLOOKUP(D2,AppTokensProbability!$A$5:$E$827,5,FALSE) =ВПР(D2,AppTokensProbability!$A$5:$E$827,5,FALSE) Функция VLOOKUP/ВПР берет соответствующий жетон из D2 и пытается найти его в столбце А листа AppTokensProbability. Если таковой находится, функция берет значение из столбца Е. Но этого недостаточно, потому что вам нужно иметь дело с редкими словами, которых нет в таблице просмотра, — такие жетоны получат значение N/A 123
124 Много цифр от функции. Как обсуждалось ранее, эти редкие слова должны иметь вероятность, равную 1, деленную на общее число жетонов в ячейке В828 на листе AppTokensProbability. Имея дело с редкими словами, нужно вложить VLOOKUP/ВПР в проверку ISNA/ЕНД и работать с логарифмированными вероятностями редких слов, если есть такая необходимость: IF(ISNA(VLOOKUP(D2,AppTokensProbability!$A$5:$E$827,5, FALSE)),LN(1/AppTokensProbability!$C$828), VLOOKUP(D2,AppTokensProbability!$A$5:$E$827,5,FALSE)) ЕСЛИ(ЕНД(ВПР(D2,AppTokensProbability!$A$5:$E$827,5,ЛОЖЬ)), LN(1/AppTokensProbability!$C$828),ВПР(D2, AppTokensProbability!$A$5:$E$827,5,ЛОЖЬ)) Единственное, что не учитывает данное решение, — это маленькие жетоны. Есть соблазн их выкинуть. Так как мы будем суммировать эти логарифмированные вероятности, вы можете установить логарифмированную вероятность любого маленького жетона на 0 (это, по сути, то же самое, что и выставление вероятности редких слов на 1, только наоборот — жетоны отбраковываются). Для проведения этой операции нужно снова вложить всю формулу в еще одно утверждение IF/ЕСЛИ, проверяющее длину: =IF(LEN(D2)<=3,0,IF(ISNA(VLOOKUP(D2,AppTokensProbability! $A$5:$E$827,5,FALSE)),LN(1/AppTokensProbability!$C$828), VLOOKUP(D2,AppTokensProbability!$A$5:$E$827,5,FALSE))) =ЕСЛИ(ДЛСТР(D2)<=3,0,ЕСЛИ(ЕНД(ВПР(D2,AppTokensProbability! $A$5:$E$827,5,ЛОЖЬ)),LN(1/AppTokensProbability!$C$828), ВПР(D2,AppTokensProbability!$A$5:$E$827,5,ЛОЖЬ))) Обратите внимание: на листе AppTokensProbability используются абсолютные ссылки, так что вы можете перемещать формулу, как того пожелаете. Когда жетоны твитов достигнут столбца AI, протащите эту формулу из D25 до AI44, чтобы учесть каждый жетон. Так получается рабочий лист, изображенный на рис. 3-15. Начиная с ячейки D48 можно использовать ту же формулу, что и в D25. Имейте в виду, что она должна ссылаться на лист OtherTokensProbability, диапазон использования функции VLOOKUP//ВПР изменится на $A$5:$E$810 и общее число жетонов окажется в $C$811. Все это приводит нас к листу, показанному на рис. 3-16. В столбце С можно просуммировать каждую строку вероятностей, что показано на рис. 3-17. К примеру, С25 — это просто
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Рис. 3-15. Логарифмированные вероятности, относящиеся к приложению, соотнесенные с жетонами Рис. 3-16. Оба набора логарифмированных вероятностей, соотнесенные с тестовыми твитами =SUM(D25:AI25) =СУММА(D25:AI25) В ячейке С2 можно классифицировать первый твит, просто сравнив его показатели в ячейках С25 и С48, используя следующее утверждение: =IF(C25>C48,"APP","OTHER") =ЕСЛИ(C25>C48,"APP","OTHER") Копируя эту формулу дальше до С21, вы получаете классификации для каждого твита, как показано на рис. 3-18. Попадание — 19 из 20! Неплохо. Если взглянуть на неправильно классифицированный твит, можно увидеть, что написан он весьма расплывчато — показатели близки к неопределенным. 125
126 Много цифр Рис. 3-17. Суммы прологарифмированных условных вероятностей жетонов Рис. 3-18. Классифицированные тестовые твиты Вот и все. Модель построена, предположения сделаны.
3. Наивный байесовский классификатор и неописуемая легкость бытия идиотом Подытожим Эта глава — сверхкороткая, по сравнению с остальными в этой книге. Почему? Потому что наивный Байес очень простой! И за это все его любят. Кажется, что он делает что-то сложное волшебным образом, хотя на самом деле он просто полагается на хорошую память компьютера, помнящего, насколько часто каждый жетон появляется в каждом классе. Есть такая пословица: «Опыт — отец мудрости, а память — ее мать». К «наивному Байесу» она подходит на 100%. Полнота «псевдомудрости» программы состоит из загруженных и хранящихся данных и кусочка математической изоленты. «Наивный Байес» даже немного приспособлен к простому применению в коде. Например, вот как он выглядит в С#: http://msdn.microsoft.com/en-us/magazine/jj891056.aspx небольшой кусочек, написанный кем-то на Python и выложенный в Сеть: http://www.mustapps.com/spamfilter.py вот на Ruby: http://blog.saush.com/2009/02/11/naive-bayesian-classifiers-andruby/ Одно из замечательных свойств этой модели — то, что она отлично работает, даже если кругом куча элементов (feature) — вводных данных модели ИИ, с помощью которых вы строите свои предположения (в случае с нашими данными, каждое слово представляет собой элемент). Но, несмотря на это, не забывайте, что у простой модели набора слов (bag of words) тоже есть свои недостатки. Если честно, наивная часть модели может стать причиной появления проблем. Приведу пример. Предположим, я создал «наивный байесовский» классификатор, который пытается классифицировать твиты по отношению к написанному на положительные и отрицательные. И когда кто-то пишет что-то вроде: Новый фильм Майкла Бэя — это дымящаяся куча шовинистского мусора, полная взрывов и убогой игры актеров, не выражающей ничего. Но лично мне понравилось! Правильно ли обработает модель эту запись? В ней пачка отрицательных жетонов, но в конце — несколько положительных. 127
128 Много цифр Так как модель набора слов не учитывает структуру текста и принимает все жетоны за беспорядочную кучу, возникает проблема. Многие наивные байесовские модели на самом деле рассматривают в качестве жетонов фразы, а не отдельные слова. Это помогает немного контекстуализировать слова (и делает предположения классификатора еще более нелепыми, но кому какая разница!). Для выполнения такой работы нужно больше тренировочных данных, потому что количество возможных фраз из N слов гораздо больше, чем количество возможных слов. Для записей, подобных этому отзыву на фильм, может понадобиться модель, которая учитывает положение слов. За какой фразой последнее слово? Получение подобной информации немедленно устраняет все мысли о простой концепции «набора слов». Конечно, это все придирки. «Наивный Байес» — это простой и многофункциональный инструмент ИИ. Его легко прототипировать и испытывать. Попробуйте помоделировать с помощью этого классификатора разные идеи, и если они будут достаточно хорошо работать — вы молодец. Если результаты многообещающи, но убоги — можно обратить свой взор на что-нибудь «помясистее», вроде комплексной модели (ensemble model), рассмотренной в главе 7.
4 Оптимизационное моделирование: этот «свежевыжатый апельсиновый сок» не смешает себя сам Н едавно Business Week опубликовала статью, посвященную новым разработкам Coca-Cola. С помощью большой аналитической модели компания пытается определить, как смешать свежий апельсиновый сок разных сортов и создать идеальный «продукт-не-из-концентрата». Я обсуждал статью с коллегами, и один из них посетовал, что компании, мол, не пришлось бы напрягаться, имей она в своем распоряжении модель искусственного интеллекта. На мой взгляд, он был неправ. Да, Coca-Cola пользуется не моделью искусственного интеллекта, а оптимизационной моделью. Давайте разберемся, в чем же разница. Модель искусственного интеллекта предсказывает результаты, основываясь на вводных данных. Но задача Coca-Cola в данном случае другая. Ей не нужно знать, что получится, если смешать сок А и сок В. Ей принципиально понять, какие соки из А, В, С, D и т. д. следует закупать и в каких пропорциях смешивать. На основе анализа данных и исходных условий (в том числе имеющегося инвентаря, спроса, характеристик и т. д.) Coca-Cola должна решить, как именно смешать разные по своим свойствам соки (к примеру, один сок слишком сладкий, а другой, наоборот, недостаточно), чтобы добиться «правильного» вкуса по минимальной стоимости и с максимальной прибылью. В этих действиях нет ничего, что можно было бы предсказать. Модель создается для изменения будущего. Оптимизационное моделирование — это аналитическое арминианство в сравнении с кальвинизмом искусственного интеллекта*. Компании любого профиля используют оптимизационные модели каждый день, чтобы найти ответы на вопросы типа: * Арминианство — направление в протестантском богословии, утверждающее решающую роль свободы воли в деле спасения. Кальвинизм — одно из направлений протестантской церкви, возникший в Швейцарии в XVI в. Кальвинизм осуждает расточительство, отстаивает бережливость. — Прим. ред.
130 Много цифр как составить расписание для сотрудников колл-центра, чтобы оно соот• ветствовало их отпускным запросам, сбалансировало переработки и исключало убийственные круглосуточные дежурства, складывающиеся из нескольких смен подряд для каждого сотрудника? Какие возможности бурения нефтяных скважин использовать для полу• чения максимального дохода, держа при этом под контролем все риски? Когда следует делать новые заказы в Китае и как их доставлять, чтобы ми• нимизировать стоимость и соответствовать ожидаемому спросу? Оптимизация — это искусство математической формулировки бизнес-задач, а затем и поиск лучшего решения. И, как отмечено в главе 1, целью оптимизации всегда является «максимизация» или «минимизация», где лучшее решение всегда означает что-то самое большое или самое маленькое: самая низкая цена, самая высокая прибыль или хотя бы минимальная вероятность оказаться в тюрьме. Самая распространенная и понятная форма математической оптимизации — это линейное программирование, секретная разработка советских инженеров конца 1930-х годов, ставшая популярной в ходе Второй мировой войны. Линейное программирование использовалось для планирования транспортировки и распределения ресурсов с учетом минимизации стоимости и рисков и максимизации поражения противника. В этой главе я подробно расскажу о линейной части линейного программирования. Кстати, слово «программирование» в данном словосочетании является пережитком военной терминологии того времени и не имеет ничего общего с компьютерным программированием. Просто не обращайте на него внимания. В этой главе рассказывается о линейной, целочисленной и немного о нелинейной оптимизации. Основная цель — сформулировать задачу бизнеса на понятном компьютеру языке. Также я уделю много внимания стандартным промышленным методам оптимизации, встроенным в «Поиск решения» Excel, и тому, как эта надстройка разбирается с вышеупомянутыми проблемами и выдает лучшие решения. Зачем ученым, работающим с данными, нужна оптимизация? Если вы посмотрите фильмы о Джеймсе Бонде или «Миссия невыполнима», то заметите, что довольно много чего происходит еще до вступительных титров. И главное, что заставляет зрителей прирасти к экрану, — это взрыв.
4. Оптимизационное моделирование Предыдущие главы о добыче данных и искусственном интеллекте как раз и играли роль подобных «взрывов». Ну а теперь, как в любом хорошем фильме, сюжет должен развиваться. В главе 2 мы немного пользовались оптимизационным моделированием для нахождения оптимального расположения кластерных центров, но все достаточные для этого знания об оптимизации вы почерпнули из главы 1. Теперь же мы погрузимся в оптимизацию с головой и обретем бесценный опыт построения моделей для решения задач бизнеса. Искусственный интеллект в последнее время стал вызывать беспокойство из-за активного использования в технических компаниях и стартапах. Оптимизация же, напротив, больше похожа на Fortune 500 бизнес-практики. Перепроектирование цепочки снабжения для уменьшения затрат на топливо выглядит не слишком привлекательно. Но оптимизация, чего бы она ни касалась — срезания жира или сверхэкономной развески, — представляет собой фундамент успешного развития бизнеса. Говоря о науке о данных, нельзя не признать, что оптимизация и здесь — фундаментальное понятие. Как вы узнаете из этой книги, она является не только стоящей аналитической практикой сама по себе — каждый уважающий себя практик по научной работе с данными неизбежно сталкивается с ней в процессе применения других методов работы с данными. В одной только этой книге оптимизация играет ведущую роль в четырех главах: определение оптимальных кластерных центров методом кластеризации • по k-средним в главе 2; максимизация модульности для определения сообществ (глава 5); • тренировочные коэффициенты для модели ИИ (подгонка регрессии • в главе 6); оптимальная установка параметров сглаживания в модели прогнозирова• ния (глава 8). Задачи оптимизации служат своего рода объединяющим началом различных областей науки о данных, так что желающим продвинуться на этом поприще необходимо осваивать искусство их решения. Без них — никуда, можете мне верить. Начнем с простого компромисса Этот раздел я начну с двух любимых «пунктиков» экономистов — пушек и масла. 1941 год, вы десантированы за линию фронта под именем Жереми (или Амелин) Гальендо, хозяина французской молочной фермы. 131
132 Много цифр Ваша работа днем: дойка коров и продажа сладкого сливочного масла местному населению. Ваша работа ночью: сборка и продажа автоматов французскому Сопротивлению. Ваша жизнь сложна и полна опасности. Вы начисто отрезаны от штаба и вам остается лишь работать на ферме, стараясь не попасться на «крючок» нацистам. Денег в вашем бюджете хватает только, чтобы свести концы с концами, собирая автоматы и сбивая масло. Вы должны продержаться до конца войны. Нельзя потерять ферму, ведь это — прикрытие! После долгих раздумий о своем нелегком положении, вы смогли охарактеризовать его тремя составляющими. Цель. Вы получаете $195 (ой, простите, франков, хотя, честно говоря, мой • Excel настроен на доллары, и я не собираюсь менять настройки ради этого примера) за каждый автомат, который продаете своему доверенному лицу — Пьеру. Вы получаете $150 за каждую бочку проданного на рынке масла. Вам нужно получать как можно больший доход, чтобы окупать ферму. Задача. Вам необходимо выяснить, сколько автоматов и сколько масла вам • нужно продать за месяц, чтобы получить максимальную прибыль. Условия и ограничения. Производство одной бочки масла обходится вам • в $100, а сборка одного автомата — в $150. Ваш месячный бюджет на производство новой продукции — $1800. Вам приходится хранить эту продукцию в своем 21-кубометровом подвале. Автомат занимает половину кубометра, бочка масла занимает полтора кубометра. Ни автоматы, ни масло невозможно хранить в другом месте: первые заметят нацисты, а второе испортится. Представим проблему в виде политопа Проблема, представленная подобным образом, называется линейной программой. Линейная программа определяется как набор решений, необходимый для оптимизации объекта в свете некоторых условий, где и объект, и условия линейны. Линейность в данном случае означает, что каждое уравнение будет лишь добавлять решения, вычитать их, умножать на константы или все упомянутое вместе. В линейном программировании вы не можете применять для решения нелинейные функции, к которым, к примеру, относятся: перемножение решений (автоматы, помноженные на масло, неприменимы); • применение логических циклов, таких как ЕСЛИ («Если хранить в подвале • только масло, то можно сделать небольшое отверстие в полу, и тогда полезный объем подвала увеличится до 22 кубических метров»).
4. Оптимизационное моделирование Как вы увидите в дальнейшем, ограничения лишь стимулируют творческий подход. Вернемся к нашей проблеме. Начнем с графического определения «области допустимых значений» для этой проблемы. Допустимые значения — это множество возможных решений. Можно ли не производить ни масла, ни автоматов? Конечно. Бездействие не увеличит прибыль, но теоретически оно возможно. Можете ли вы делать по 100 автоматов и 1000 бочек масла в месяц? Нет, с данным бюджетом и в вашем тесном подвале это невозможно. Так с чего же начать построение графика? Ну, во-первых, нельзя производить отрицательные количества автоматов и масла. Мы же не занимаемся теоретической физикой. Поэтому нам нужен только первый квадрант координатной плоскости. В терминах бюджета, при цене $150 за штуку вы можете собирать по 12 автоматов в месяц, используя бюджет в $1800. А по цене $100 за бочку вы можете произвести 18 бочек масла. И если изобразить бюджетное ограничение как линию на графике, то эта линия пойдет аккурат через 12 автоматов и 18 бочек масла. Как показано на рис. 4-1, область допустимых значений в данном случае представляет собой треугольник положительных чисел, согласно которому вы можете произвести максимум 12 автоматов или 18 бочек масла в месяц, или некоторую линейную комбинацию их меньших значений. 50 Автоматы 40 30 20 Ог ра 10 ни че ни яб юд же 10 та 20 30 40 50 Масло Рис. 4-1. Бюджетное ограничение делает область допустимых значений треугольной 133
Много цифр Для этого треугольника есть более общее название — политоп. Политоп — это не более чем геометрическая фигура с плоскими сторонами. Наверняка вы слышали термин «полигон». Полигон — это просто двумерный политоп. Если у вас в обручальном кольце есть внушительный камень — бах! бриллиант, радуйтесь: это политоп. Во всех линейных программах области допустимых значений могут быть выражены в качестве политопов. Некоторые алгоритмы, как вы не замедлите убедиться, используют этот факт для ускоренного решения линейных проблем. Но не отвлекаемся от масла и оружия! Пришло время рассмотреть второе ограничительное условие — подвал. Если бы вы производили только автоматы, их можно было бы уместить там 42 штуки. С другой стороны, в такой подвал может уместиться не более 14 бочек масла. Добавив это ограничение к политопу, мы отсекаем часть области допустимых значений, как показано на рис. 4-2. 50 40 Огр 30 я по чени ани Автоматы 134 20 ра ни а 10 двал Ог че ни яб юд же 10 та 20 30 40 50 Масло Рис. 4-2. Ограниченный объем подвала отрезает кусок области допустимых значений Решение путем сдвигания линии уровня функции После определения области допустимых значений у вас может возникнуть вопрос: «И где же в этой области находится идеальное соотношение автоматов и масла?» Чтобы на него ответить, введем в задачу такое понятие, как линия уровня функции. Линией уровня для вашей оптимизационной модели будет та область, в которой все значения приносят одинаковый доход.
4. Оптимизационное моделирование Так как функция вашей прибыли — это $150 × масло + $195 × автомат, каждая линия ее уровня может быть определена как прямая $150 × масло + $195 × × автомат = С, где С — фиксированная величина прибыли. Рассмотрим случай, где С = $1950. Для линии уровня $150 × масло + $195 × × автомат = $1950 обе точки — (0,10) и (13,0) — принадлежат ей, как и любая комбинация из масла и автоматов, при которой $150 × масло + $195 × автомат равняется $1950. Эта линия уровня изображена на рис. 4-3. Используя идею линии уровня, можно начать думать над проблемой максимизации прибыли, сдвигая линию уровня по направлению нарастания прибыли (это направление будет перпендикулярно самой линии) до последнего возможного значения, находящегося в области допустимых значений. На рис. 4-3 линия уровня нарисована пунктиром, а стрелка, отходящая от нее, представляет собой целевую функцию. 50 Автоматы 40 30 20 10 Ли ни яу ро вн 10 я 20 30 40 50 Масло Рис. 4-3. Линия уровня и функция для оптимизации прибыли Симплекс-метод: все по углам Повторяю: если вы хотите знать, какие значения из области допустимых значений оптимальны — просто сдвиньте линию уровня функции в направлении нарастания дохода. Прямо на границе, где линия вот-вот выйдет из области политопа, и находятся эти точки. И вот один замечательный факт: одна из этих оптимальных точек на границе всегда будет лежать в углу политопа. 135
Много цифр Проверьте это по рис. 4-3. Положите карандаш на линию уровня и сдвигайте его вверх и вправо, в направлении увеличения дохода. Видите, как она выходит из политопа через угол? Что же в этом замечательного? А то, что политоп с рис. 4-3 имеет бесконечное количество допустимых значений. Проверять каждое из них можно до самой смерти. Даже границы содержат бесконечное количество точек! Но углов всего 4. В одном из них и кроется оптимальное решение нашей проблемы. Оказывается, для проверки углов существует специальный алгоритм. И он весьма эффективен даже в задачах с сотнями миллионов решений! Называется этот алгоритм симплексным методом. Смысл его заключается в следующем: начиная с угла политопа он скользит по краям по направлению увеличения целевой функции. Когда ему встречается угол, чьи стороны направлены в противоположном направлении — он считает его лучшим. В случае торговли автоматами и маслом, предположим, мы начали с точки (0,0). Это угол, но он приносит $0 прибыли. Безусловно, вы можете лучше. Как видно на рис. 4-3, на нижнем краю политопа прибыль увеличивается по мере движения вправо. Поэтому, двигаясь по нижней границе вправо, мы встречаем угол (14,0) — 14 бочек масла и никаких автоматов, что приносит прибыль в $2100 (рис. 4-4). 50 40 Автоматы 136 30 20 10 10 20 30 40 Масло Рис. 4-4. Проверка «цельномасляного» угла 50
4. Оптимизационное моделирование От этого «масляного» угла двигаемся в направлении увеличения прибыли по линии ограничения объема подвала. Следующий угол на нашем пути — (12,9; 3,4), который обещает доход, немного не дотягивающий до $2600. Обе стороны угла направлены в стороны с меньшей прибылью, так что мы на месте. Согласно рис. 4-5, это оптимум! 50 Автоматы 40 30 20 10 10 20 30 40 50 Масло Рис. 4-5. Найден оптимальный угол Работа в Excel Перед тем, как перейти от этой небольшой задачи к вещам более серьезным, я хочу построить и решить ее в Excel. Первое, что вам нужно сделать на чистом листе — это создать пространство для целевых переменных и переменных решения. Назовите ячейку В2 местом, куда будет записываться общая прибыль, а ячейки В4:С4 — областью, куда будут занесены решения по продукции. Под целевой секцией и секцией решения добавьте информацию о размерах и стоимости автоматов и масла, ограничения площади для хранения и бюджета, а также вклад каждого вида товара в прибыль. Готовая для заполнения таблица должна выглядеть как на рис. 4-6. К этим данным следует добавить немного расчетов, а именно расчет ограничений и расчет прибыли. В столбце Е, следом за ячейками с ограничениями Limit, умножьте количество произведенных автоматов и масла на их относительный объем и стоимость, а затем сложите все полученное в столбце Used. Например, в ячейку Е 7 можно записать используемую площадь подвала с помощью формулы: 137
138 Много цифр Рис. 4-6. Данные об автоматах и масле, с любовью помещенные в Excel =SUMPRODUCT(B4:C4,B7:C7) =СУММПРОИЗВ(B4:C4,B7:C7) Замечу, что эта формула является линейной, потому что только одна область, В4:С4, — область решения. Другая область просто содержит коэффициенты хранения. Вы можете произвести аналогичные вычисления, чтобы узнать общую сумму, потраченную на масло и автоматы. Для вычисления целевой функции вам нужно взять SUMPRODUCT/СУММПРОИЗВ от заказанного количества в строке 4 с прибылью в строке 9. Ввод допустимых значений, таких как 1 автомат и 1 бочка масла, дает нам лист с решением, как на рис. 4-7. Рис. 4-7. Расчет прибыли и ограничений в рамках проблемы автоматов и масла
4. Оптимизационное моделирование Хорошо, но как теперь заставить Excel установить оптимальные значения переменных решения? Для этого есть «Поиск решения»! Начните с открытия пустого окна «Поиска решения» (как на рис. 4-8). Подробнее об использовании этой опции читайте в главе 1. Как упоминалось выше, необходимо снабдить «Поиск решения» целью, формулировкой задачи и условиями. Цель — прибыль, ячейка В1. Также убедитесь, что выбрали опцию «Max» и максимизируете, а не минимизируете свою прибыль в расчетах. Если бы вам в очередной задаче пришлось рассчитывать себестоимость или риски в качестве целевой функции, вы бы использовали опцию «Min». Решения находятся в В4:С4. После того, как вы добавили их в поле «Изменяя ячейки», окно «Поиска решения» должно выглядеть как на рис. 4-8. Рис. 4-8. Окно «Поиск решения» 139
140 Много цифр Что касается ограничений, то их вам нужно добавить два. Начните с ограниченного объема подвала. Нажмите кнопку «Добавить» рядом с полем ограничений. При заполнении небольшого поля следует указать, что значение в ячейке Е7 должно быть меньше или равно (<=) значению в ячейке D7 (рис. 4-10), а объем используемой площади — меньше ограничения. ЗАМЕТКА Обратите внимание, что «Поиск решения» добавит абсолютные ссылки ко всем переменным в ваших формулах. И это ничего не меняет. Если честно, я не знаю, зачем он это делает, потому что вы не можете перетаскивать формулы в контексте модели «Поиска решения». Для более подробного описания абсолютных ссылок обратитесь к главе 1. Рис. 4-9. Цель и решения, внесенные в «Поиск решения» Нажмите «ОК», добавив ограничение, а затем точно так же добавьте бюджетное ограничение (Е 8 ≤ D8). Убедитесь, что отмечена опция «Сделать переменные без ограничений неотрицательными», чтобы количество произведенных автоматов и масла не стало вдруг отрицательным по непонятной причине (вы можете добавить ограничение В4:C4 ≥ 0, но просто отметить опцию проще).
4. Оптимизационное моделирование ЗАМЕТКА Перед тем, как нажать «ОК», посмотрите, какие еще типы ограничений предлагает вам «Поиск решения». Кроме стандартных ≤, ≥ и = есть довольно занятные, например int, bin и dif. Эти странные условия можно поместить в ячейки, чтобы значения стали целыми, бинарными (0 или 1) или «все разные». Запомните условие «int». Немного погодя мы к нему вернемся. Теперь выберем способ решения — это должен быть «поиск решения линейных задач симплекс-методом». Все готово (рис. 4-11)! Рис. 4-10. Окно добавления ограничений ИСПОЛЬЗОВАНИЕ EXCEL 2007 В Excel 2007 нет опции «Сделать переменные без ограничений неотрицательными». Вместо этого откройте настройки «Поиска решения» и снимите галочку с опции «Неотрицательные значения». Также здесь нет возможности выбора метода решения. Вместо этого поставьте галочку «Линейная модель», чтобы включить симплексный алгоритм. После нажатия кнопки «Выполнить» Excel быстро находит решение проблемы и открывает окошко, чтобы сообщить вам об этом. Вы можете либо принять это решение, либо изменить значения переменных решения (рис. 4-12). Если вы нажмете «ОК» и примете это решение, то увидите, что оно состоит из 3,43 автомата и 12,86 бочек масла, в точности как на вашем графике (рис. 4-13). 141
142 Много цифр Рис. 4-11. Готовый к поиску соотношения автоматов и масла «Поиск решения» Рис. 4-12. «Поиск решения» сообщает о решенной задаче Но вы же не можете сделать 3,43 автомата! Теперь ваше французское альтер эго наверняка кричит: «Zut alors! Черт возьми!» Но почему? Да потому что вы не можете сделать 43% автомата. Я поясню этот момент. Во время работы с линейным программированием мы частенько получаем дробные значения решений, что, безусловно, раздражает. Если бы вы производили миллионы автоматов и бочек масла, то это можно было бы проигнорировать без особого ущерба для решения и размера прибыли. Но в нашем случае числа настолько малы, что приходится заставлять «Поиск решения» делать их целыми.
4. Оптимизационное моделирование Рис. 4-13. Оптимизированная таблица автоматов и масла Так что возвращаемся к окошку «Поиска решения» и добавляем целочисленное ограничение для ячеек В4:С4 (рис. 4-14). Нажмем «ОК», чтобы вернуться к окошку параметров «Поиска решения». Рис. 4-14. Делаем количество автоматов и бочек масла целыми числами В параметрах раздела «Поиск решения задач симплекс-методом», есть опция «Игнорировать целочисленные ограничения». Убедитесь, что она не отмечена. Нажмите «ОК». Запустите «Поиск решения» — и тут же выскочит окошко с ответом. Прибыль в нем равна $2580, что значит, вы теряете всего около $17. Неплохо! Заметьте, что вводя целочисленное ограничение, вы не можете увеличить прибыль, а только уменьшите, так как накладываете еще одно ограничение на готовое решение. Автоматов стало больше на целых 4 штуки, а вот масло уменьшилось до 12 бочек. И, несмотря на полностью израсходованный бюджет, у вас остался еще неиспользованный кубометр подвала! Так почему же не делать все решения целыми числами? Ну, на самом деле, это нужно далеко не всегда. К примеру, если вы смешиваете жидкости, дробные значения совсем не мешают. 143
Много цифр Тайком от вас «Поиск решения» все же рассчитывает дробные результаты, а уж потом применяет ограничения. Алгоритм, который он использует, если встречает целочисленные или бинарные ограничения, называется «Ветви и границы», и работает он таким образом, что запускает один и тот же линейный алгоритм над разными частями исходной задачи, пока не найдет целочисленные решения для каждого этапа. Просто для смеха сделаем нашу задачу нелинейной Даже несмотря на то, что вы добавили целочисленное ограничение решения, основная проблема все же осталась линейной. Допустим, вы будете получать призовые $500 от вашего доверенного Пьера, если каждый месяц сможете делать на 5 автоматов больше. Добавьте функцию IF/ЕСЛИ в ячейку с прибылью, которая поступает от производства автоматов — В4: =SUMPRODUCT(B9:C9,B4:C4)+IF(B4>=5,500,0) =СУММПРОИЗВ(B9:C9,B4:C4)+ЕСЛИ(B4>=5,500,0) Как только вы добавляете это условие — IF/ЕСЛИ — целевая функция становится нелинейной. Оно изображено на графике (рис. 4-15), где вы можете легко увидеть большой нелинейный разрыв в точке 5 автоматов. $500 Бонус Пьера 144 $0 5 10 15 20 Автоматы Рис. 4-15. График $500 бонуса Пьера Если бы вы попытались открыть «Поиск решения» и снова использовать линейный симплексный алгоритм для решения этой задачи, Excel бы вежливо пожаловался на то, что «не выполнены условия линейности, требуемые алгоритмом» (рис. 4-16). К счастью, для решения этой задачи у «Поиска решения» есть два других алгоритма, а именно «Эволюционный» и «Поиск решения нелинейных задач
4. Оптимизационное моделирование Рис. 4-16. Excel не дает вам использовать логические операторы в линейном алгоритме методом ОПГ». На этот раз мы дадим шанс эволюционному алгоритму, с которым уже знакомы по главе 2 (в Excel 2007 нет возможности выбора алгоритма, поэтому просто снимите галочку с опции «Линейная модель»). Работа эволюционного алгоритма приблизительно повторяет принципы работы биологической эволюции: генерирует пул исходных решений (что-то вроде генетического пула) раз• ной степени вероятности; каждое решение имеет некий уровень пригодности к выживанию; • решения размножаются перекрестным переносом, то есть их компоненты • выбираются из двух или трех существующих решений и затем комбинируются; существующие решения мутируют в новые; • имеет место локальный поиск, в процессе которого генерируются новые • решения вблизи лучшего на данный момент решения в популяции; происходит отбор: случайно выбранные неуспешные кандидаты в реше• ния выбрасываются из генетического пула. Обратите внимание, что в данном приближении нет наследования типа алгоритма: линейного, квадратичного или какого-то еще. В какой-то степени каждая задача может рассматриваться как черный ящик. Это означает, что, моделируя задачи линейного программирования в Excel, вы ограничены такими условиями, как знаки +/-, формулами SUM/СУММА и AVERAGE/СРЗНАЧ, где решения находятся только в рамках одной последовательности. Но если вы используете эволюционный алгоритм, выбор доступных формул существенно увеличивается. Вы можете применить любую функцию, какую только захотите, в том числе эти полезные нелинейные функции. 145
146 Много цифр Логические проверки: IF/ЕСЛИ • COUNTIF/СЧЁТЕСЛИ • SUMIF/СУММЕСЛИ • Статистические функции: MIN/МИН • MAX/МАКС • MEDIAN/МЕДИАНА • LARGE/НАИБОЛЬШИЙ • NORMDIST/НОРМРАСП, BINOMDIST/БИНОМРАСП, и т. д. • Функции поиска: VLOOKUP/ВПР • HLOOKUP/ГПР • OFFSET/СМЕЩ • MATCH/ПОИСКПОЗ • INDEX/ИНДЕКС • Я вижу, вы уже готовы воспарить от восторга, так что позвольте мне немного «приземлить» вас. С эволюционным алгоритмом все же возникают некоторые проблемы. Нет никакой гарантии, что он найдет оптимальное решение. Все, что в его • силах — это контроль лучшего решения в популяции, пока не закончится время, либо популяция не изменится в достаточной степени для продолжения, либо вы принудительно не остановите «Поиск решения» нажатием кнопки Escape. Вы можете модифицировать эти критерии остановки эволюционного алгоритма в разделе параметров «Поиска решения». Эволюционный поиск решения работает довольно медленно. А если об• ласти допустимых значений сложные, он часто ругается, не найдя даже места, с которого начать. Если вы хотите заставить эволюционный алгоритм хорошо работать в Excel, • вам придется определить жесткие границы для каждой переменной решения. Даже если ваше решение более или менее неограниченное, вам все же придется ограничить его каким-то большим числом. Принимая во внимание последний пункт, для решения задачи с автоматами и маслом вам нужно добавить ограничение, согласно которому оба решения не должны быть больше 25, как показано на рис. 4-17.
4. Оптимизационное моделирование Рис. 4-17. Настройка эволюционного «Поиска решения» Нажмите «ОК», а затем «Выполнить». Алгоритм запущен и должен каким-то образом выдать нам решение, состоящее из 6 автоматов и 9 бочек масла. Так, эволюционный алгоритм решил отблагодарить Пьера за приз! Неплохо. Но обратите внимание, что даже такая маленькая задача заняла некоторое время. Около 30 секунд на моем ноутбуке. Задумайтесь, что это может значить для промышленной модели. Монстр в конце главы Все проблемы, рассмотренные нами до этого момента, были воображаемыми. В следующей части я собираюсь продемонстрировать способности «Поиска решения» на чем-то более осязаемом. Вы снова проведете какое-то время, учась моделировать нелинейные функции (вроде пьеровского бонуса) линейными способами, так что можете продолжать пользоваться «Поиском решения линейных задач симплекс-методом». Если вы с нетерпением ждете перехода к следующей теме, обнадежу вас: сейчас вы знаете большую часть того, что нужно знать для успешного изучения последующих глав. Останьтесь со мной хотя бы до раздела с ограничениями IfThen/Если-То и «Большого М» этой главы, чтобы научиться тому, что понадобится 147
148 Много цифр в главе 5 для кластеризации графов. А еще лучше — втягивайтесь и работайте над всеми оставшимися задачами вместе со мной! Сразу предупреждаю: два последних смоделированных бизнес-правила в этой главе — настоящие монстры! ДРУГИЕ ИНСТРУМЕНТЫ Большие модели не очень-то хорошо идут в Excel. Версия «Поиска решения», встроенная в него, позволяет иметь только 100–200 переменных решений и ограничений, в зависимости от версии. Это ограничивает размер задач, с которыми вы сталкиваетесь в этой книге. Если вы хотите и дальше пользоваться Excel, купите расширенную версию «Поиска решения» у Frontline Systems. Еще лучше, особенно если у вас Windows, использовать OpenSolver, как мы будем делать в конце этой главы. OpenSolver, описанный в главе 1, обращается к открытому ресурсу под названием COIN Branch and Cut (http://www.coin-or.org), который идеален для проблем оптимизации среднего размера. Я вполне эффективно использовал OpenSolver для сотен и тысяч переменных. Есть и программы для линейного программирования пожирнее, например Gurobi и CPLEX. Разработчикам и остальным любителям «облачных сервисов» я особо рекомендую Gurobi, ибо CPLEX, принадлежащий IBM, — лучшее корпоративное решение. Интерфейс у таких мощных промышленных программ встречается разный. К примеру, CPLEX идет в пакете со средой OPL, где можно писать модели на специальном языке, имеющем прекрасную привязку к электронным таблицам. В языках программирования есть множество подобных привязок для связи алгоритмов с моделями внутри промышленных систем. Мой любимый инструмент для встраивания в мощные системы поиска решений, такие как СPLEX и Gurobi, называется AIMMS (www.aimms.com). Программа позволяет построить свою оптимизационную модель, а затем «шлепнуть» на нее пользовательский интерфейс без необходимости писать его код. Также эта программа может общаться с электронными таблицами и базами данных. До конца этой книги вы вполне дотянете и с Excel и его «Поиском решения». Но вам следует знать о существовании сверхсовременных сред моделирования для решения больших задач на случай, если ваши нужды перерастут Excel. Свежий, из сада — прямо в стакан… с небольшой остановкой на модель смешивания В вашем далеком детстве наверняка однажды наступил такой знаменательный день, когда вам сказали, что никакого Деда Мороза не существует, кроме того краснорожего ряженого дядьки на утреннике.
4. Оптимизационное моделирование ЗАМЕТКА Электронная таблица Excel, использованная в данной главе, OrangeJuiceBlending.xlsx, доступна на сайте книги, www.wiley.com/go/datasmart. Эта таблица содержит все необходимые для работы исходные данные. Или же вы можете просто читать и следить за мной по таблицам, которые я уже заполнил. Так вот, сегодня я намерен разрушить еще один миф: ваш свежевыжатый сок премиум-класса, не восстановленный из концентрата, не был выжат вручную. На самом деле, мякоть в нем, скорее всего, из одних апельсинов, сок — из других, более того, он взят из разных бочек и смешан согласно математическим моделям, созданным для того, чтобы удостовериться, что каждый выпитый вами стакан имеет в итоге один и тот же вкус. Одинаковый вкус апельсинового сока круглый год — далеко не пустяк, с которым справится каждый. Во-первых, апельсины не зреют во Флориде круглогодично. Во-вторых, разные сорта созревают в разное время. Сорвешь слишком рано — вкус слишком «зеленый». Закажешь апельсины из другой страны, где сейчас сезон — сок может быть другого цвета. Или слаще. Потребители требуют постоянства. Может быть, для какого-нибудь Sunny D это просто, но как достичь идеала вам с вашей кучей бочек холодного свежевыжатого сока? Вы используете модель для смешивания В известном телесериале «Аббатство Даунтон» богатый лорд Грэнтэм вкладывает все деньги семьи в один-единственный железнодорожный венчур. Рискованно. И он много теряет. Очевидно, в начале ХХ века диверсификация не была популярной идеей. При усреднении рисков и возврате портфеля инвестиций по нескольким вложениям излишки по прибыльным направлениям не дадут вам внезапно разбогатеть, но меньше будут и излишки по убыточным направлениям, тянущие вас на дно. Точно такой же подход применим и к современному производству апельсинового сока. Сок можно доставить со всего мира, и он будет из разных апельсинов разных сезонов. У каждого продукта свои особенности: один чуть терпкий, другой — немного вяжущий, а остальные могут оказаться чудовищно сладкими. И только смешиванием этого «портфолио» может быть достигнут постоянный вкус. Вот проблема, с которой мы будем работать в этом разделе. Как построить модель смешивания, которая уменьшает стоимость и одновременно повышает 149
150 Много цифр качество? Какие типы инструментов следует задействовать при выполнении работ, которые по ходу дела постоянно требуют математической формулировки? Начнем с характеристик Допустим, вы — аналитик, работающий в ДжусЛэнде. Ваш босс, мистер Джус Р. Лэндингсли III (ваша компания страдает непотизмом), попросил вас распланировать закупки сока у поставщиков на январь, февраль и март наступающего года. Вместе с этим поручением мистер Лэндингсли протягивает вам список характеристик от поставщиков, содержащий страну происхождения и сорт, доступное для заказа количество на следующие три месяца и цену, а также стоимость пересылки за 1000 галлонов. В списке приведены характеристики цвета сока по шкале от 1 до 10 и три вкусовых компонента: отношение Брикс/кислотность: Брикс — это мера сладости сока, так что • Брикс/кислотность — это отношение сладости к терпкости (кислотности), что, в конце концов, и есть настоящий вкус апельсинового сока; кислотность (%): Кислотность в процентах от сока приведена отдельно, • потому что это определенное количество: неважно, насколько сладок сок, если он при этом слишком кислый; вяжущий вкус (шкала 1–10): мера «неспелости» сока. Это тот горький, не• зрелый, садовый привкус, который может закрасться в сок. Этот параметр оценивается группой специалистов на каждом производстве по выпуску сока по шкале 1–10. Все эти характеристики представлены в электронной таблице, изображенной на рис. 4-18. Какой бы сок вы ни выбрали, он будет доставлен на ваше производство в огромных асептических охлажденных бочках, торговым кораблем или по железной дороге. Поэтому отсутствует стоимость пересылки для апельсинов «валенсия» из Флориды — фабрика, смешивающая сок, находится прямо в вашей флоридской апельсиновой роще (где в старые добрые времена вы сами выращивали все нужные вам апельсины). Посмотрите на характеристики на рис. 4-18. Что вы можете о них сказать? Сок разных сортов и мест произрастания. Некоторые соки, например, мексиканские, дешевые, но слишком вяжут. В других сортах, как например, техасский «санстар», сок слаще и вяжет меньше, но и цена его выше.
4. Оптимизационное моделирование Рис. 4-18. Список характеристик для производства свежевыжатого апельсинового сока Выбор сока для заказа на следующие три месяца зависит от ответов на следующие вопросы: если вы минимизируете стоимость, сможете ли вы купить все, что захотите? • Сколько сока вам нужно? • Каковы ограничения по цвету и вкусу для каждой партии? • Возвращаемся к консистенции С помощью вкусовых тестов и опроса покупателей ДжусЛэнд определил, как должен выглядеть сок и каким он должен быть на вкус. Небольшой выход за пределы этих характеристик — и покупатели почти наверняка сочтут ваш сок ненастоящим, дешевым или, хуже того, восстановленным из концентрата. Фу! Мистер Лэндингсли III предъявляет вам следующие требования. Он хочет иметь план заказа по самым низким ценам на январь, февраль • и март, соответствующий ожидаемому спросу в 600 000 галлонов сока в январе и феврале и 700 000 галлонов в марте. Он имеет договор со штатом Флорида, предоставляющим налоговые льготы • при условии, что компания покупает не менее 40% сока каждый месяц у фермеров, выращивающих сорт «флорида валенсия». Нарушать договор нельзя ни при каких условиях. Отношение Брикс/кислотность (BAR) должно оставаться в пределах между • 11,5 и 12,5 в смеси каждого месяца. 151
152 Много цифр Уровень кислотности должен оставаться между 0,75% и 1%. • Уровень вяжущего вкуса должен быть 4 или ниже. • Цвет должен находиться в рамках 4,5–5,5. Не слишком темный, не слиш• ком водянистый. Из этих требований быстренько составляем план задачи для линейного программирования. Цель: Минимизация закупочной стоимости. Задача: Найти количество каждого сока для закупки каждый месяц. Условия: спрос; • поставки; • договор со штатом Флорида; • вкус; • цвет. • Вводим данные в Excel Чтобы смоделировать эту задачу в Excel, сперва создайте новый лист, на котором будет размещаться расчет. Назовем его Optimization Model. В ячейку А2 под заголовком Total Cost поместите указатель поля для заполнения — там будет результат. Под ней, в ячейку А5, вставьте таблицу характеристик таким образом, чтобы эти четыре столбца оказались между Region и Qty Available — создаем место для переменных решения и их сумм. Первые три столбца назовите, соответственно, January, February и March, а четвертый, где будет их сумма, — Total Ordered. В этом столбце расположите сумму трех левых столбцов, что в случае с бразильским «гамлином» в ячейке F6 будет выглядеть так: =SUM(C6:E6) =СУММА(С6:Е6) Можете растянуть ячейку F6 до F16. Применив условное форматирование на С6:Е 6, получаете таблицу, как на рис. 4-19. Ниже полей с ежемесячными заказами добавьте поля для ежемесячных поставок и стоимости пересылки. Для января, к примеру, поместите стоимость пересылки в ячейку С17 следующим образом: =SUMPRODUCT(C6:C16,$L6:$L16) =СУММПРОИЗВ(C6:C16,$L6:$L16)
4. Оптимизационное моделирование Рис. 4-19. Настраиваем таблицу смешивания Так как переменные решения содержатся только в столбце С, вычисление снова будет линейным. Точно такую же формулу нужно добавить в С18 для расчета стоимости доставки за месяц: =SUMPRODUCT(C6:C16,$M6:$M16) =СУММПРОИЗВ(C6:C16,$M6:$M16) Растягивая формулы на столбцы D и E, вы получаете расчет стоимости поставок и доставки. Теперь можно установить в ячейку А2 целевую функцию суммы С17:Е18. Получившаяся таблица представлена на рис. 4-20. Теперь добавим расчеты для удовлетворения условиям спроса и продажи флоридской «валенсии». В строке 20 сложим общее количество сока, поставленное в этом месяце, а в строке 21 разместим требуемые уровни 600, 600 и 700 в столбцах С — Е, соответственно. Что касается общего количества апельсинов «валенсия», заказанных у Флориды, то перенесите С8:Е8 на С23:Е23 и поместите необходимые 40% общего спроса (240, 240, 280) под этими значениями. Так мы получаем таблицу, изображенную на рис. 4-21. Теперь, когда мы внесли в таблицу целевую функцию, переменные решения, поставки, спрос и расчет количества флоридской «валенсии», все, что нам осталось — это расчет по показателям вкуса и цвета, основанный на том, что же мы, собственно, заказываем. 153
154 Много цифр Рис. 4-20. Добавление расчета стоимости в таблицу смешивания Рис. 4-21. Добавлены расчеты спроса и «валенсии»
4. Оптимизационное моделирование Начнем с отношения Брикс/кислотность. Поместите в ячейку В27 минимальное значение этого отношения в смеси, равное 11,5. Затем в ячейке С27 используйте SUMPRODUCT/СУММПРОИЗВ январских заказов (столбец С) и их отношения Брикс/кислотность в столбце Н, разделенные на общий спрос, — и вы получите среднее отношение Брикс/кислотность. ВНИМАНИЕ Не делите на спрос последовательно, так как вообще спрос является функцией переменных решения. Решения, поделенные на решения, ужасно нелинейны! Просто помните, что вы устанавливаете величину общего спроса, равную ожидаемому спросу, как ограничение, так что нет причины просто последовательно делить на спрос в процессе вычисления среднего отношения Брикс/ кислотность для смеси. Таким образом, ячейка С27 выглядит так: =SUMPRODUCT(C$6:C$16,$H$6:$H$16)/C$21 =СУММПРОИЗВ(C$6:C$16,$H$6:$H$16)/C$21 Можете растянуть эту формулу до столбца Е. В столбце F вы заканчиваете ряд, вбив максимальное значение этого отношения — 12,5. Затем можно повторить эти шаги для шкал кислотности, вязкости и цвета в строках с 28 по 30. Получившаяся таблица изображена на рис. 4-22. Постановка задачи «Поиску решения» Ну что ж, теперь у нас есть все необходимые данные и расчеты для постановки задачи смешивания. Первое, что нужно объяснить «Поиску решения», — это функция общей стоимости в А2, которую мы хотим минимизировать. Переменные решения — это величины ежемесячных заказов каждого сорта, расположенные в ячейках С6:Е16. Снова напомню, что переменные не могут быть отрицательными, так что убедитесь, что поставили галочку «Сделать переменные без ограничений неотрицательными» («Линейная модель» в Excel 2007). Когда дело доходит до добавления условий, задача начинает всерьез отличаться от примера с автоматами и маслом. А их множество. Первое условие — заказы в строке 20 должны быть равны спросу в строке 21 за каждый месяц. Точно так же заказы на флоридскую «валенсию» в строке 23 должны быть больше или равны требуемому количеству в строке 24. Также общее количество заказов из каждого региона, рассчитанное в F6:F16, должно быть меньше или равно доступному для заказа количеству в G6:G16. 155
156 Много цифр Рис. 4-22. Добавление в таблицу ограничений по вкусу и цвету Итак, ограничения поставок и предложения установлены, теперь очередь вкуса и цвета. Однако Excel не позволит вам ограничить два ряда с разной размерностью, поэтому если вы напечатаете C27:E30 ≥ B27:B30, он вас не поймет (что ужасно раздражает). Вместо этого нужно добавлять условия в столбцы С, D и Е по отдельности. К примеру, для январских заказов у вас есть условие C27:С30 ≥ B27:B30 и C27:С30 ≥ F27:F30. То же самое можно сделать для февраля и марта. После того, как вы добавили все эти ограничения, убедитесь, что установлен метод решения «Поиск решения линейных задач симплекс-методом». Окончательная таблица изображена на рис. 4-23. Запустив «Поиск решения», вы находите оптимальную стоимость закупок — $1,23 миллиона (рис. 4-24). Обратите внимание, что заказ флоридской «валенсии» проходит по нижней границе условия. Очевидно, эта сделка — не лучший вариант, но приходится смириться. Второй по популярности сорт — это «верна» из Мексики, которая чертовски дешева, но ровно настолько же ужасна. Модель балансирует этот горький и кислый сок смесью из «белладонны», «биондо коммуне» и «гарднера», которые мягче, слаще и дают лучший цвет. Миленько!
4. Оптимизационное моделирование Рис. 4-23. Заполненное окно «Поиска решения» для задачи смешивания Рис. 4-24. Решение задачи со смешиванием апельсинового сока 157
158 Много цифр Снижаем стандарты В полном восторге вы несете ваш план оптимального смешивания своему начальнику, мистеру Лэндингсли III. Вы объясняете, как пришли к такому варианту. Он разглядывает бумагу с подозрением. И даже, несмотря на ваши заверения в оптимальности плана, требует урезать стоимость еще на 5%. И объясняет свою очевидно бессмысленную позицию спортивными аналогиями «играй всеми нападающими» и «выдай мне 110%». Со спортивными аналогиями нет смысла спорить. Если именно $1 170 000 — подходящая цифра, то пусть так и будет. Вы объясняете, что достичь этого с имеющимися условиями качества невозможно, а он ворчит и говорит вам, что ваша задача — «немного прогнуть реальность». Хммм… Вы возвращаетесь к своей таблице взволнованным. Как можно получить смесь лучше за $1 170 000? После разговора по душам с мистером Лэндингсли вы понимаете: стоимость — больше не цель. Это теперь условие! А что же цель? Ваша новая цель, порожденная ворчанием начальника, формулируется как понижение качества ради снижения стоимости. А способ ее достигнуть — это вставка переменной решения в модель с тем, чтобы снизить ограничения качества. Что ж, вперед — копируем лист Optimization Model в чистую таблицу под названием Relaxed Quality. Эта задача не потребует больших изменений. Посидите минутку и подумайте, как и что можно изменить, чтобы модель соответствовала новым послаблениям в цели и цене. Не вставайте, пока не заболит голова! Первое, что вы должны сделать, — это внести $1 170 000 как ценовое ограничение в ячейку В2, прямо за старой целевой ячейкой. Также скопируйте старые минимальные и максимальные значения вкуса и цвета в столбцы H и I соответственно. А в строки 27–30 столбца G добавьте новую переменную решения под названием %Relaxed. Теперь подумайте, как вы можете использовать снижение значения отношения Брикс/кислотность в ячейке G27, чтобы понизить ограничение в 11,5. Текущее значение этого параметра варьируется от 11,5 до 12,5, то есть разница равна 1. Поэтому расширение этого «коридора» на 10% даст нам минимальное значение в 11,4. Следуя этому подходу, замените минимум в В27 на эту формулу: =H27-G27*(I27-H27) Берем старый минимум, находящийся теперь в Н27, и применяем к нему процентное послабление, умноженное на расстояние от старого максимума до старого
4. Оптимизационное моделирование минимума (127 минус Н27). Можете скопировать эту формулу вниз до строки 30. Точно так же примените новый максимум с послаблением в столбце F. Что касается целевой функции, возьмите среднее из решений с послаблением из G27:G30. Поместив этот расчет в ячейку D2, получаем новый лист, который выглядит как рис. 4-25. Рис. 4-25. Модель с пониженным качеством Откройте «Поиск решения» и замените целевую функцию на минимизацию среднего послабления качественных ограничений из ячейки D2. Также вам нужно добавить G27:G30 в список переменных решения и установить стоимость в А2 меньшей или равной ограничению в В2. Эти новые настройки показаны на рис. 4-26. Обобщим сделанное: мы превратили прошлую целевую стоимость в ограничение с верхней границей. Также мы превратили жесткие ограничения качества в мягкие, которые могут быть ослаблены изменением G27:G30. Ваша цель в D2 — минимизировать среднее снижение качества согласно характеристикам. Нажмите «Выполнить». 159
160 Много цифр Рис. 4-26. Модель с понижением качества в «Поиске решения» Excel находит решение: со средним снижением каждого ограничения на 35% возможно достижение результата в рамках указанного ценового ограничения, как показано на рис. 4-27. Теперь, когда есть готовая модель, единственное, что вы можете сделать еще — это предоставить мистеру Лэндингсли больше информации, чем он просил. Известно, что при стоимости $1,23 миллиона понижение качества составит 0%, так почему же не рассчитать пошагово понижение стоимости с максимальным шагом, предположим, в 20 или около того, и не посмотреть, к чему приводит снижение качества? При $1,21 миллионах это 5%, при $1,19 — уже 17% и т. д., включая 35, 54, 84 и 170%. Если попытаться опуститься ниже $1 миллиона, модель становится непригодна. Создав новый лист под названием Frontier, вы можете вставить в него все решения и создать для них графики, чтобы проиллюстрировать зависимость качества от стоимости (рис. 4-28). Чтобы создать график, как на рис. 4-28, просто выделите два столбца с данными на листе Frontier и вставьте диаграмму «График» со сглаживанием из меню «Диаграммы» (в главе 1 более подробно описан процесс вставки диаграмм).
4. Оптимизационное моделирование Рис. 4-27. Решение для модели с понижением качества Рис. 4-28. График зависимости стоимости от качества Удаление дохлых белок: правило минимакс Взглянув на решение с понижением качества при ограничении стоимости в $1,17 миллиона, можно увидеть потенциальную проблему. Конечно, среднее 161
162 Много цифр послабление по цвету и вкусу составляет 35% от прежних рамок, но для цвета это уже 80%, а для отношения Брикс/кислотность — 51%. Усреднение скрывает величину этого отклонения. В данной ситуации необходимо минимизировать максимальное снижение всех четырех качественных ограничений. Такая проблема называется проблемой минимакса, потому что минимизируется максимум (это слово забавно повторять быстро-быстро: минимакс, минимакс, минимакс…). Как достичь «поголовной» минимизации? Если сделать целевой функцией MAX(G27:G30)/МАКС(G27:G30), она будет нелинейной. Можно попытаться использовать эволюционный алгоритм, но компьютер будет обсчитывать его целую вечность. Однако существует линейный способ решения этой нелинейной задачи. Для начала скопируйте модель со сниженными ограничениями на новый лист и назовите его Minimax Relaxed Quality. А теперь скажите, кому из вас случалось находить дохлых зверушек и избавляться от них? Прошлым летом на моем жарком, как чистилище, чердаке здесь, в Атланте, подохла белка и запах от нее всполошил всю округу. Как я избавился от этой белки? Я отказался трогать ее и вообще иметь с ней дело непосредственно. Я выгреб ее с чердака лопатой, прижав сверху рукояткой от швабры. Это было похоже на работу гигантскими щипцами для салата или палочками для еды. В конечном итоге результат оказался точно таким же, как если бы я вытащил ее оттуда голыми руками, но чувствовал я себя не так мерзко. Вы можете справиться с расчетом MAX(G27:G30)/МАКС(G27:G30) точно так же, как я справился с той белкой. Так как вам больше не нужно среднее значение G27:G30, вы можете стереть целевую функцию из D2. В этой ячейке вы вычислите функцию MAX(), но пока оставьте ее пустой. Нужно найти значение функции, не имея с ней дела напрямую. Вот как можно это сделать: Назначить целевую ячейку D2 переменной решения, чтобы алгоритм мог • совершать над ней все необходимые действия. Не забывайте: если вы задали модели цель — минимизировать, симплексный алгоритм будет пытаться уменьшить значение в этой ячейке насколько это возможно. С помощью окна «Добавить условие» поставить следующее условие: та• кое, что G27:G30 должны быть меньше или равны D2. D2 нужно поставить в правую часть неравенства, чтобы разрешить Excel использовать разное число ячеек (4 ячейки из столбца G слева и одна справа, ограничивающая неравенство сверху). Единственный раз в этой главе вы можете использовать разное количество ячеек в неравенстве ограничения, потому что
4. Оптимизационное моделирование Excel умеет работать с вариантом, когда правая часть неравенства выражена единственной ячейкой. Отлично, и что же мы только что сделали? Симплексный алгоритм будет пытаться приблизить D2 к 0 как целевую функцию модели, в то время как ограничения по вкусу и цвету будут пытаться увеличить ее насколько возможно, чтобы получить пригодную для работы смесь. Где же остановится значение D2? Самое меньшее из возможных значений — максимальный процент из четырех сниженных в промежутке от G27 до G30. Когда целевая функция достигнет этого максимума, «Поиску решения» останется только тянуть его вниз. Как в случае с белкой, ограничения — это лопата под белкой, а минимизация — это ручка от швабры, прижимающая ее сверху. Вот мы и получили термин «минимакс». Неплохо, да? Или отвратительно… зависит от вашего отношения к дохлым белкам. И теперь, когда вы оставили пустой ячейку D2, «Поиск решения» будет настроен следующим образом (делаем D2 переменной и добавляем G27:G30 ≤ D2), как на рис. 4-29. Рис. 4-29. Настройка «Поиска решения» для снижения качества с помощью минимакса 163
164 Много цифр «Поиск решения» приводит нас к понижению качества на 58,7%, что, хотя и больше, чем средний процент 34,8 из прошлой модели, но гораздо лучше случая с ухудшением цвета на 84%. «Если… то» и ограничение «Большого М» Теперь, когда вы достаточно близко познакомились со стандартным линейным моделированием, можно добавить немного целых чисел. К вашей неимоверной радости, мистер Лэндингсли III внезапно утвердил ваш первоначальный план, но, когда вы приносите его в отдел снабжения, сотрудников перекашивает. Они отказываются поставлять сок в каком бы то ни было месяце от более чем четырех поставщиков. Видимо, слишком много бумажной работы. Хорошо, как же это описать внутри модели? Перед тем как продолжить, подумайте минутку о том, какие могут потребоваться изменения. Начнем с копирования первоначальной модели оптимизации с листа Optimization Model на новый лист, который назовем Optimization Model (Limit 4). Теперь, вне зависимости от количества закупаемого сока у поставщика, будь то 1000 галлонов или 1 000 000, считаем это заказом от одного поставщика. Другими словами, вам нужно щелкнуть счетчиком, если вы заказали у поставщика хоть каплю. В целочисленном программировании этот счетчик — бинарная переменная решения, являющаяся на деле ячейкой, которая может принимать лишь два значения — 0 и 1. Все, что вам нужно сделать — это определить диапазон такого же размера, что и переменные заказа, а состоять он будет из 0 и 1, где 1 означает существующий заказ. Эти переменные можно вставить в промежуток С34:Е44. Теперь, предполагая, что они примут значение 1, если заказ сделан, можно просуммировать каждый столбец в строке 45 и убедиться, что сумма меньше ограничения 4, которое можно установить в строке 46. Получившаяся таблица показана на рис. 4-30. Но есть здесь одна загвоздка. Вы не можете использовать функцию IF/ЕСЛИ, которая устанавливает индикатор на 1, если количество заказов выше ненулевое. Получится нелинейная функция, из-за которой придется использовать гораздо более медленный эволюционный алгоритм. Для действительно больших задач с условиями «если… то» медленные нелинейные алгоритмы становятся бесполезны. Так что вместо них приходится «включать» использование индикаторов в линейных условиях.
4. Оптимизационное моделирование Допустим, вы добавили ограничение: переменная-индикатор бразильского «гамлина» включается, когда создается заказ с использованием условия C34 ≥ C6. Если предполагать, что С34 — бинарная переменная, то это действие ограничит С6 до максимального значения, равного 1 (что означает 1000 заказанных галлонов). Таким образом вы моделируете неудобное условие «если… то»: «если заказ сделан, то бинарная переменная включается», используя нечто, в просторечии именуемое условием «большого М». Большое М — это просто число, причем очень большое, названное М. В случае с С34 М должно быть достаточно велико, чтобы вы никогда не заказали бразильского «гамлина» больше, чем М. Ведь вы не можете заказать сока больше доступного объема, верно? И для «гамлина» доступное количество — 672 тысячи галлонов. Пусть это число и будет М. Рис. 4-30. Добавление переменных-индикаторов в таблицу Теперь вы можете добавить условие, что 672 × C34 ≥ C6. Когда С6 равно нулю, С34 может принять значение 0). А когда С6 больше нуля, то С34 принудительно превращается в 1, чтобы поднять верхнюю границу от 0 до 672. Чтобы применить это условие в электронной таблице, создайте новый промежуток F34:Н44, где вы будете перемножать индикаторы слева на их 165
166 Много цифр относительные доступные количества из промежутка G6:G16. Результат изображен на рис. 4-31. Рис. 4-31. Установка значений ограничения «большого М» В «Поиске решения» добавьте С34: Е44 в спектр переменных решения. Необходимо сделать их бинарными, что выполняется путем добавления условия bin. Чтобы заработало ограничение «большого М», установите C6:E16 ≤ F34:H44. Затем проверьте счетчик поставщиков и убедитесь, что он не больше 4 с помощью неравенства C45:E45 ≤ C46:E46. Получившаяся таблица изображена на рис. 4-32. Нажмите «Выполнить». Вы заметите, что решение задачи требует больше времени из-за добавления бинарных переменных. При использовании бинарных и целочисленных переменных в формулировке «Поиск решения» покажет наиболее подходящее решение из найденных в строке состояния. Если по какой-то причине «Поиск решения» слишком затянул свои поиск, вы всегда можете нажать Escape и увидеть лучшее из найденных решений на данный момент. Как показано на рис. 4-33, оптимальное решение для модели, ограниченной четырьмя поставщиками в месяц, — это $1,24 миллиона, примерно на $16 000 больше, чем изначальный оптимум. Вооружившись этим планом, вы можете вернуться в отдел снабжения и спросить их, стоит ли уменьшение их бумажной работы лишних $16 000.
4. Оптимизационное моделирование Рис. 4-32. Запуск «Поиска решения» Учитывая таким образом появляющиеся условия, вы реализуете одну из отличительных черт применения оптимизационного моделирования в бизнесе. Помещая значок доллара в результаты своей деятельности, вы можете вынести взвешенное решение вопроса «Стоит ли оно того?». Вот таким образом устанавливаются ограничения «большого М»; вы еще встретитесь с ними в задаче кластеризации графа в главе 5. Еще больше переменных: добьем до 11 Перед тем как принять ваш план с ограничением количества поставщиков, вам говорят, что на производстве появились новые «снижатели кислотности». Используя ионообменный механизм и слой цитрата кальция, данная технология способна нейтрализовать 20% кислоты в соке, протекающем через прибор. Это не только снижает процент кислоты, но и повышает индекс Брикс/ кислотность на 25%. Но для «снижателя» нужна энергия и расходные материалы стоимостью $20 за 1000 галлонов сока. Не весь сок, поступающий от поставщиков, нужно прогонять через деацидификационный процесс, однако, если поставка 167
168 Много цифр Рис. 4-33. Оптимальное решение, ограниченное четырьмя поставщиками за период по какому-нибудь заказу прогоняется через ионообменник, то должен быть обработан весь ее объем. Можете ли вы придумать новый план с участием ионообменника для снижения оптимальной стоимости? Подумайте, как изменить задачу. Вам нужно сделать новый набор решений, основываясь на том, когда понижать кислотность, а когда нет. Как эти решения будут взаимодействовать с объемами поставок? Начните с копирования листа Optimization Model (Limit 4) в новый лист. Назовите его Optimization Model Integer Acid. Проблема с этим бизнес-правилом заключается в том, что естественный способ его моделирования — нелинейный и придется использовать медленный алгоритм для оптимизации. Можно ввести бинарную переменную, которая бы «включалась» при необходимости понизить кислотность партии. Это значит, что стоимость понижения будет следующей: понижающий кислотность реагент * объем партии * $20
4. Оптимизационное моделирование OPENSOLVER, НЕОБХОДИМЫЙ ДЛЯ EXCEL 2010 И EXCEL 2013 Последние абзацы были сложноваты, но это цветочки по сравнению со следующей моделью. Для этой задачи, пожалуйста, держите наготове заполненную электронную таблицу, чтобы сверяться с ней время от времени. Будет нелегко, но это стоит освоить, особенно если ваш бизнес часто сталкивается со сложными проблемами оптимизации. Если вы не осилите этот раздел, не огорчайтесь: на ваше дальнейшее понимание книги это не повлияет. Но все же советую вам попробовать. Если вы работаете в Excel 2010 или Excel 2013, вам понадобится загрузить и установить OpenSolver (в главе 1 описывается, как это сделать). В противном случае упомянутые версии Excel при решении задачи выдадут ошибку, в которой будет сказано, что оптимизационная модель слишком велика. Чтобы использовать OpenSolver в этой главе, вводите данные для решения как обычно, но когда дело дойдет до решения, используйте кнопку OpenSolver в меню. Вы не можете перемножить эти две переменные, не переключившись на нелинейный алгоритм. Парадокс заключается в том, что он никогда не отразит все нюансы этой модели. Должен быть способ получше. При работе с линейным программированием не забывайте: мало что нельзя линеаризовать с помощью разумного привлечения дополнительных переменных, манипулировать которыми можно с помощью дополнительных условий и целевой функции, как парой салатных щипцов. Первое, что вам понадобится — это набор бинарных переменных, которые «включаются», когда вы решаете снизить кислотность партии сока. Часть из них можно поместить в прямоугольник между заказами «валенсии» и ограничениями по качеству (ячейки С26:Е36). Более того, нельзя использовать произведение «понижающий кислотность реагент × объем партии», поэтому вы создаете новый ряд переменных под индикаторами, которые вам пригодятся для уравнивания данного количества без прямого их участия (типа случая с дохлой белкой). Вставьте эти пустые ячейки в С38:Е48. Теперь наша электронная таблица содержит два пустых ряда переменныхиндикаторов и общего количества сока, пропущенного через ацидоредуктор, как показано на рис. 4-34. Умножив переменную снижения кислотности на объем заказанных партий, что же мы получим в итоге? Есть несколько вероятных исходов: обе переменные — нули, равно как и индикатор и общее количество, со• ответственно, их произведение также равно 0; 169
170 Много цифр вы заказали сок, но решили не понижать кислотность — произведение • снова 0; вы решили понизить кислотность — произведение равно общему количе• ству сока. Рис. 4-34. Добавление индикаторов и переменных количества в решение с понижением кислотности В каждом случае общее возможное количество сока, кислотность которого можно понизить, ограничено индикатором понижения кислотности, умноженным на общее количество сока, доступное для заказа. Если вы не понижаете кислотность, то верхняя граница этого произведения упирается в ноль. Если решаете понизить — эта граница поднимается до максимального объема заказов. Это и есть ограничение «большого М», как и в предыдущем примере. Для бразильского «гамлина» в таком случае это ограничение может быть рассчитано путем умножения индикатора в ячейке С26 на объем, доступный для заказа, — 672 000 галлонов из ячейки G6. Добавляя этот расчет в ячейку
4. Оптимизационное моделирование рядом с переменными-индикаторами в G26, вы можете скопировать оставшиеся месяцы и сорта. Таким образом мы получаем лист, изображенный на рис. 4-35. С другой стороны, общее возможное количество сока, кислотность которого можно понизить, ограничено объемом, который вы решили заказать, указанным в С6:Е16. Так что теперь у нас есть две верхние границы для этого продукта: индикатор понижения кислотности × объем, доступный для заказа; • заказанное количество. • Рис. 4-35. Добавление расчета максимального количества сока для понижения кислотности Это — верхние границы для каждой переменной в нелинейном произведении. Но в таком виде задачу оставлять нельзя. Если вы решаете понизить кислотность партии, вам нужно пропустить через аппарат всю партию. Это значит, что 171
172 Много цифр нужно добавить нижнюю границу к двум верхним, чтобы получить количество с пониженной кислотностью в С38:Е48. Как насчет использования объема заказа в качестве нижней границы? В случае если вы решаете понижать кислотность, прием работает идеально. Нижняя граница выражается объемом заказа, а верхние — объемом заказа и общим количеством, доступным для заказа, умноженным на индикатор понижения кислотности, равный 1. Эти границы определяют объем сока, проходящий через аппарат понижения кислотности, который получается равным полной поставке, что вас полностью устраивает. А что же произойдет, если вы решите не понижать кислотность партии? В таком случае одна из верхних границ из-за индикатора, равного нулю, сама обращается в ноль, в то время как нижняя граница остается на уровне заказанного количества. В этом случае ненулевое заказанное количество, не подвергающееся деацидификации, становится невозможным. Хммм… Вам нужен способ «выключить» эту нижнюю границу в случае, если вы решаете не понижать кислотность. Вместо того, чтобы обозначить нижнюю границу объемом заказанного сока, давайте попробуем «открыть» ее следующим образом: заказанное количество – объем, доступный для заказа * * (1 – индикатор понижения кислотности) В случае если вы решаете понижать кислотность, эта нижняя граница поднимается до объема заказанной партии. В случае непонижения кислотности эта величина становится меньшей или равной нулю. Условие по-прежнему существует, но во всех случаях бесполезно. Звучит несколько сомнительно? Попробую объяснить это на примере. Вы покупаете 40 000 галлонов сока бразильского «гамлина» и решаете понизить его кислотность. Верхние границы объема, подвергающегося «урезанию», — это объем заказанного сока — 40 и индикатор понижения кислотности, помноженный на доступное количество — 672. Нижняя граница этого объема равна 40 – 672 × (1 – 1) = 40. Другими словами, у вас и верхняя и нижняя границы равны 40, так что вы «зажали» этот объем для деацидификации прямо в «индикатор понижения кислотности * заказанный объем», даже не рассчитывая это количество. Если же решать не понижать кислотность «гамлина», индикатор устанавливается на 0. В этом случае ваши верхние границы равны 40 и 672 × 0 = 0. Нижняя же граница выходит равной 40 – 672 × (1 – 0) = –632. А так как у вас стоит
4. Оптимизационное моделирование галочка в поле, делающем все переменные неотрицательными, это значит, что объем «гамлина», кислотность которого вы понижаете, «зажат» между 0 и 0. Отлично! Теперь добавьте эту нижнюю границу в таблицу справа от расчета верхней границы. В ячейке К26 напечатайте: =C6-$G6*(1-C26) Можете скопировать эту формулу для каждого сорта и месяца, получив в результате таблицу, изображенную на рис. 4-36. Рис. 4-36. Добавление нижней границы к понижению кислотности Рядом с разделом Total Reduce вычтите это значение из общего объема заказа в С16:Е16, чтобы получить оставшееся количество сока, не подвергшегося деацидификации. К примеру, в ячейку G38 поместите =C6—C38 173
174 Много цифр Можете перетащить данные на оставшиеся ячейки этого расчета (как на рис. 4-37). Рис. 4-37. Добавление расчета «Not Reduced» (сока без понижения кислотности) Подытоживая формулировку расчета, вам нужно изменить подсчет стоимости, отношения Брикс/кислотность и процента кислоты. Для расчета стоимости можно просто добавить $20, умноженные на сумму значений Total Reduce (общее количество сока с пониженной кислотностью) за месяц в ячейку Price. К примеру, расчет стоимости за январь в ячейке Price будет выглядеть как =SUMPRODUCT(C6:C16,$L6:$L16)+20*SUM(C38:C48) =СУММПРОИЗВ(C6:C16,$L6:$L16)+20*SUM(C38:C48) что вы с легкостью можете переместить на февраль и март.
4. Оптимизационное моделирование Отношение Брикс/кислотность и процент кислоты теперь будут рассчитываться отдельно для Total Reduced (общего количества сока с пониженной кислотностью) и Not Reduced (сока без понижения кислотности). Значения Not Reduced будут пропущены через SUMPRODUCT/СУММПРОИЗВ со своими первоначальными свойствами, в то время как та же самая формула для сока с измененной кислотностью будет изменена на 1,25 и 0,8 соответственно для отношения Брикс/кислотность и кислотности и добавлена к общему среднему за месяц. К примеру, индекс Брикс/кислотность за январь в С51 может быть рассчитан как =(SUMPRODUCT(G38:G48,$H6:$H16)+SUMPRODUCT (C38:C48,$H6:$H16)*1.25)/C21 =(СУММПРОИЗВ(G38:G48,$H6:$H16)+СУММПРОИЗВ (C38:C48,$H6:$H16)*1.25)/C21 Теперь необходимо модифицировать модель в «Поиске решения». Целевая функция остается прежней (сумма цены и доставки), но переменные решения включают индикаторы понижения кислотности и объемы сока, подлежащие этому понижению, расположенные в С26:Е36 и С38:Е48. Что касается ограничений, нужно отметить, что С26:Е36 — бинарные. Также, С38:С48 меньше или равны двум верхним границам в С6:Е16 и G26:I36. Еще вам нужно условие для нижней границы: С38:Е48 меньше или равно К26:М36. Таким образом получается новая модель, изображенная на рис. 4-38. Нажмите «Выполнить» и позвольте ветвям и границам сделать свое дело. В результате получится оптимальное решение, которое окажется на $4000 дешевле, чем предыдущий расчет. Изучив переменные нового решения, вы найдете эти две партии — одна из Аризоны, другая из Техаса — прошедшие через процесс понижения кислотности. Верхние и нижняя границы для этих двух партий точно подходят для того, чтобы поставить произведения переменных на место (рис. 4-39). Моделируем риски Последнее бизнес-правило было тяжеловатым, зато проиллюстрировало, как с помощью модели можно линеаризовать большинство задач бизнеса путем добавления условий и переменных. Неважно, впрочем, насколько просты или сложны были предыдущие задачи — у них есть одна общая черта: они свято чтут вводные данные. Эта точность не всегда соответствует реальности, в которой вынуждено действовать большинство бизнесменов. Не все партии отвечают заявленным 175
176 Много цифр Рис. 4-38. Настройка «Поиска решения» для задачи с понижением кислотности характеристикам, доставка не всегда приходит вовремя, спрос не соответствует прогнозам и т. д. Другими словами, в данных существует вариабельность и риск. Что же делать с этим риском и как его выразить в оптимизационной модели? Нормальное распределение данных В задаче с апельсиновым соком вы пытаетесь смешивать соки, чтобы исключить вариабельность. Резонно предположить, что и продукт, получаемый от поставщиков, также может варьироваться по характеристикам. Есть вероятность, что доставка апельсинового сока «биондо коммуне» из Египта не будет иметь точного отношения Брикс/кислотность в 13. Реальная цифра наверняка будет немного «плавать» вокруг этого значения. И частенько разница может быть охарактеризована с помощью распределения вероятности. Говоря простым языком, распределение вероятности дает процент возможности каждого исхода некоторой ситуации, и все вероятности в сумме дадут 1. Самое, наверное, известное и широко используемое распределение — это нормальное распределение, иначе называемое «колоколообразной кривой». Секрет популярности этой кривой заключается в том, что при наличии ряда
4. Оптимизационное моделирование Рис. 4-39. Решение с помощью модели с понижением кислотности независимых, комплексных, реальных факторов, наложенных один на другой, получаются случайные данные, которые часто распределяются нормальным, или колоколообразным, образом. Это называется центральной предельной теоремой. Проиллюстрирую вышесказанное небольшим экспериментом. Достаньте ваш мобильный и запишите последние четыре цифры каждого сохраненного в нем номера. Цифра 1, скорее всего, будет равномерно распределена между 0 и 9, то есть каждая из этих цифр будет встречаться примерно одинаковое количество раз. То же можно отнести и к цифрам 2, 3 и 4. А теперь возьмем эти четыре «случайные переменные» и сложим их. Наименьшее число, которое вы можете получить, это 0 (0 + 0 + 0 + 0). Наибольшее — 36 (9 + 9 + 9 + 9).Тот есть существует только один способ получить 0 и 36. Есть четыре способа получить 1 и четыре — получить 35, но уйма способов получения 20. Если вы проверите это утверждение на достаточном количестве телефонных номеров и выведете диаграмму различных сумм, то в итоге получится колоколообразная кривая, как на рис. 4-40 (для построения этой диаграммы я использовал 1000 телефонных номеров — да, я ровно настолько популярен). 177
Много цифр Результат сложения последних четырех цифр телефонных номеров в вашем мобильнике 80 70 Количество вхождений 178 60 50 40 30 20 10 0 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 Сумма четырех цифр Рис. 4-40. Комбинирование независимых случайных переменных для иллюстрации того, как они собираются в колоколообразную кривую Интегральная функция распределения Есть другой способ, который называется интегральное (или кумулятивное) распределение. Функция интегрального распределения дает вероятность исхода, меньшую или равную определенной величине. В примере с данными из мобильного только 12% случаев меньше или равны 10, в то время как 100% меньше или равны 36 (так как это наибольшее возможное значение). Интегральное распределение показано на рис. 4-41. У этого распределения есть одно замечательное свойство — его можно читать задом наперед и генерировать примеры из представления. К примеру, случайное число из этого распределения сумм последних четырех цифр номеров в записной книжке может составить случайный процент от 0 до 100. Допустим, 61%. Смотрим на вертикальную ось распределения — 61% пересекается с 19 на горизонтальной оси. Так можно делать снова и снова, генерируя случайные числа с помощью распределения. Обычное интегральное распределение может быть описано двумя числами: средним значением и среднеквадратичным отклонением. Среднее — не что иное, как центр распределения. Среднеквадратичное отклонение же измеряет вариабельность, или рассеяние, колоколообразной кривой вокруг среднего. Скажем, в случае с соком из Египта среднее значение отношения Брикс/ кислотность будет 13, а среднеквадратичное отклонение — 0,9. В данном примере 13 — это центр распределения вероятности, а 68% заказов будут в пределах +/– 0,9 от 13,95% будут в пределах двух среднеквадратичных отклонений
4. Оптимизационное моделирование Функция интегрального распределения для сумм четырех цифр номеров % меньший или равный сумме цифр 100% 90% 80% 70% 60% 50% 40% 30% 20% 10% 0% 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 Сумма цифр Рис. 4-41. Функция интегрального распределения для сумм контактов мобильного телефона (+/– 1,8), а 99,7% будут находиться в пределах трех среднеквадратичных отклонений (+/– 2,7). Это еще называется правилом «68–95–99,7». Другими словами, весьма вероятно, что из Египта вы получите сок с отношением Брикс/кислотность = 13,5, но получить партию с этим показателем = 10, — очень маловероятно. РАСЧЕТ ВЫБОРОЧНОГО СРЕДНЕГО И СРЕДНЕКВАДРАТИЧНОГО ОТКЛОНЕНИЯ Тех из вас, кто раньше не сталкивался с расчетом среднеквадратичного отклонения и заинтригован, я обрадую: все очень просто. На рис. 4-42 показаны 11 последних заказов сока «биондо коммуне» из Египта и их отношение Брикс/кислотность в столбце В. Выборочное среднее для этих значений будет равно 13, как и написано в таблице характеристик. Выборочная оценка среднеквадратичного отклонения — это просто квадратный корень из среднеквадратичной погрешности. Под словом «погрешность» я понимаю отклонение каждой партии от предполагаемого значения 13. В столбце С рис. 4-42 вы можете увидеть расчет погрешности, а в столбце D — квадрат погрешности. Среднеквадратичная погрешность — это AVERAGE(D2:D12)/ СРЗНАЧ(D2:D12), которая оказывается равной 0,77. И тогда квадратный корень из среднеквадратичной погрешности равен 0,88. 179
180 Много цифр На практике во время расчета среднеквадратичного отклонения для небольшого количества партий можно получить более точную оценку, если сложить квадраты погрешностей и разделить их поочередно на число, на 1 меньшее, чем общее количество заказов (в нашем случае — 10 вместо 11). Если вы примените такой подход, стандартное отклонение становится равным 0,92, как показано на рис. 4-42. Рис. 4-42. Пример расчета выборочного среднеквадратичного отклонения Генерируем сценарии из среднеквадратичных отклонений в задаче смешивания ЗАМЕТКА Точно так же, как в предыдущем разделе, пользователям Excel 2010 и Excel 2013 понадобится помощь OpenSolver. Ставьте задачу, формируйте решение, как обычно, и используйте кнопку выполнения OpenSolver в меню, когда дело дойдет до решения. Более подробно OpenSolver описан в главе 1. Представьте, что вместо таблицы характеристик вы получили среднеквадратичные отклонения вместе со всеми характеристиками в таблице под названием Specs Variability, показанной на рис. 4-43. Ваша цель — придумать план смешивания стоимостью меньше $1,25 миллиона, который наилучшим образом соответствует ожиданиям по качеству в свете вариабельности поставок. Можете создать копию первоначальной таблицы Minimax Relaxed Quality и назвать ее Robust Optimization Model, а новые среднеквадратичные отклонения поместить в N6:Q16 в соответствии со старыми характеристиками. Поместили. А что теперь?
4. Оптимизационное моделирование Рис. 4-43. Добавлена характеристика среднеквадратичного отклонения Используйте среднее и среднеквадратичное отклонение характеристик, чтобы применить имитационное моделирование по методу Монте-Карло. В этом методе вместо включения распределения в модель напрямую каким-либо образом берется образец распределения, создаются сценарии или обсчитывается каждый набор образцов, после чего они включаются в модель. Сценарий — это один из возможных ответов на вопрос: «Если это — распределения, основанные на статистике, на что же будет похож настоящий заказ?» Чтобы нарисовать такой сценарий, нужно посмотреть на функцию распределения — охарактеризованную средним и среднеквадратичным отклонением — наоборот, как описывалось ранее с рисунком 4-41. Формула Excel для прочтения функции распределения задом наперед (или в «инвертированном виде») называется NORMINV/НОРМОБР. Начнем генерировать сценарий в столбце В: с 33-й строки все уже заполнено. Можете назвать это Scenario 1. В В34:В44 у вас будет настоящий сценарий для значения отношения Брикс/ кислотность по всем поставщикам. В В34 сгенерируйте случайное значение для бразильского «гамлина» с учетом того, что отношение Брикс/кислотность составит 10,5 (Н6), а среднеквадратичное отклонение — 2 (N6), используя формулу NORMINV/НОРМОБР: =NORMINV(RAND(),$H6,$N6) =НОРМОБР(RAND(),$H6,$N6) Вы вводите случайное число от 0 до 100% в формулу NORMINV/НОРМОБР, а также среднее и среднеквадратичное отклонения, и в итоге получаете случайное значение отношения Брикс/кислотность. Растянем эту формулу до В44. 181
182 Много цифр Начиная с В45, можно делать то же самое с кислотностью, затем терпкостью и, наконец, с цветом. Область В34:В77 теперь содержит единый сценарий, случайно выведенный из отклонений. Растягивая его на все столбцы до CW (фиксируйте абсолютные ссылки, позволяющие это сделать), можно сгенерировать сто таких сценариев со случайными характеристиками. «Поиск решения» не понимает их, пока они не остаются в нелинейной форме, поэтому скопируйте их и вставьте в их же начала, но только в качестве обычных значений. Теперь сценарии существуют в виде закрепленных данных. Эти горы данных для сценариев в В34:CW77 изображены на рис. 4-44. Рис. 4-44. Сто сгенерированных сценариев характеристик соков Устанавливаем ограничения для сценариев Теперь нужно найти решение, которое менее всего снижает границы качества в каждом из сгенерированных вами сценариев. Фактически это решение, защищающее продукт.
4. Оптимизационное моделирование Итак, под первым сценарием в ячейке В79 рассчитайте отношение Брикс/ кислотность в январе: =SUMPRODUCT($C$6:$C$16,B34:B44)/$C$21 =СУММПРОИЗВ($C$6:$C$16,B34:B44)/$C$21 То же самое можно сделать и для февраля и марта в строках 80 и 81, а затем распространить весь расчет до самого столбца CW, чтобы получить значение этого отношения для каждого сценария. В итоге вы получаете расчеты для каждого сценария, показанные на рис. 4-45. Рис. 4-45. Расчет характеристик для каждого сценария Дальнейшая настройка модели не так уж сложна. Ставим верхнюю границу стоимости, равную $1,25 миллиона, в В2. Продолжаем минимизировать D2 — снижение качества — с настройками минимакса. Все, что нужно — это поместить во все сценарии границы качества, а не просто ожидаемые значения характеристик. Таким образом, в отношение Брикс/кислотность вы добавляете условие B79:CW81 ≥ B27 и ≤ F27, затем проделываете то же самое с кислотностью, вяжущей составляющей вкуса и цветом, получая в итоге формулировку, показанную на рис. 4-46. Нажмите «Выполнить». Решение найдется довольно быстро. Если вы генерировали случайные значения сами, а не использовали те, что находятся в файле 183
184 Много цифр Рис. 4-46. Настройка «Поиска решения» для более надежной оптимизации для загрузки, оно может отличаться. Для моей сотни сценариев наилучшим показателем, который мне удалось получить, является изменение качества на 133% с сохранением стоимости менее $1,25 миллиона. Ради смеха можно поднять верхнюю границу стоимости до $1,5 миллиона и решить все снова. Получится изменение на 144%, причем цена будет сильно недотягивать до верхней границы, оставаясь близкой к $1,3 миллиона. Видимо, увеличение стоимости выше этого значения не дает большого резерва для улучшения качества (решение на рис. 4-47). Ну, вот и все! Теперь у вас есть баланс стоимости и качества, удовлетворяющий условиям даже в случайных, близких к реальности ситуациях. Подытожим Если вы терпеливо составляли мне компанию на протяжении последних двух моделей — браво! Эти «взламыватели мозгов» — не игрушки. На самом деле это была, возможно, самая трудная глава книги. Дальше будет проще, честное слово!
4. Оптимизационное моделирование Рис. 4-47. Решение более надежной оптимизационной модели УПРАЖНЕНИЕ ДЛЯ ЧИТАТЕЛЯ Если вы экономны, чтобы не сказать больше, могу предложить вам на закуску еще одну формулировочку. В предыдущей задаче вы минимизировали имевшийся процент для понижения и повышения границ качества, причем решение должно было удовлетворять всем условиям. Но что, если бы вас устроило удовлетворение условий всего 95% сценариев? Вам по-прежнему понадобилось бы минимизировать процент снижения качества, но также появилась бы необходимость в новой переменной-индикаторе для каждого сценария, а также пришлось бы использовать ограничения, чтобы они обращались в 1, если условия качества сценария окажутся нарушены. В этом случае сумма индикаторов должна была бы быть ограничена условием ≤5. Попробуйте. Вдруг у вас получится. 185
186 Много цифр Вот небольшое обобщение того, чему вы научились в этой главе: простое линейное программирование; • правило минимакс; • добавление целочисленных переменных и ограничений; • моделирование логики «если… то» с использованием ограничения «боль• шого М»; линейное моделирование произведения переменных решения; • нормальное распределение, центральная предельная теорема, функции • интегрального распределения, метод Монте-Карло; использование метода Монте-Карло для моделирования риска в линей• ном программировании. У вас, должно быть, голова идет кругом от желания немедленно применить все эти математические премудрости в вашем бизнесе. Или, наоборот, вы только что допили стаканчик крепкого и решили никогда больше не связываться с линейным программированием. Надеюсь все-таки на первый вариант, ибо линейное программирование — чрезвычайно увлекательный инструмент для развития необычайной креативности и сообразительности. Модели с десятками миллионов переменных решений вы найдете во многих моделях бизнеса. ПРАКТИКА, ПРАКТИКА И ЕЩЕ РАЗ ПРАКТИКА! И ЕЩЕ СООТВЕТСТВУЮЩАЯ ЛИТЕРАТУРА Моделирование линейных программ, особенно если приходится проделывать трюки, подобные трюку с «дохлой белкой», порой не вдохновляет. Наилучший способ освоить его — это найти несколько возможностей в своей области, где бы вы могли с ним развернуться. Все запомнить невозможно — постарайтесь «намотать на ус» наиболее часто встречающие случаи. А это приходит только с практикой. Вот несколько бесплатных онлайн-ресурсов, которые я очень рекомендую тем, кто хотел бы ознакомиться с дополнительной литературой по линейному программированию: • книга по оптимизационному моделированию AIMMS /The AIMMS optimization modeling book, доступная на http://www.aimms.com/downloads/manuals/ optimization-modeling, — невероятный ресурс. Не пропустите две главы про трюки и подсказки — они поистине гениальны. • “Formulating Integer Linear Programs: A Rogue’s Gallery” из Brown and Dell of the Naval Postgraduate School: http://faculty.nps.edu/gbrown/docs/Brown_ Dell_INFORMS_Transactions_on_Education_January2 0 07.pdf.
5 В Кластерный анализ, часть II: сетевые графы и определение сообществ этой главе мы продолжим дискуссию о кластерной идентификации и анализе с использованием данных об оптовом магазине вина из главы 2. Прошу прощения за то, что в этой книге я вынужден часто перескакивать с одного примера на другой. Сейчас, например, я позволю себе порекомендовать вам освежить в памяти главу 2 — в дальнейшем я не буду возвращаться к этапу подготовки данных. Кроме того, вам снова понадобится косинусная мера (коэффициент Охаи), которая обсуждалась также в главе 2. Вслед за этим я попрошу вас вернуться к главе 4, где речь идет о техниках оптимизации с участием ограничения «большого М» — они тоже понадобятся нам в дальнейшей работе. Итак, в настоящей главе мы продолжаем прорабатывать задачу определения заинтересованных групп покупателей, основываясь на их заказах, но в этот раз подойдем к ней с совершенно противоположной стороны. Мы не будем представлять себе наших покупателей группирующимися вокруг флажков в актовом зале, как в случае кластеризации по k-средним (глава 2), а взглянем на проблему более абстрактно. Люди покупают похожие вещи и таким образом оказываются связанными друг с другом. При этом одна группа покупателей выказывает больше приверженности одним и тем же товарам, нежели другая. Поразмыслив над тем, каким образом каждый покупатель связан с остальными, можно выделить сообщества покупателей, не втыкая флажки в набор данных и не передвигая их до того момента, пока люди не почувствуют, что они дома. Ключевая концепция, которая позволяет использовать такой подход к кластеризации покупателей, называется сетевым графом. Сетевой граф, как вы узнаете из следующего раздела, — это простой способ сохранить и визуализировать сущности (например, покупателей), связанные между собой (в нашем случае данными о покупках). Сегодня визуализация сети и ее анализ очень модны, а техники, применяемые для извлечения решений из сетевых графов, часто работают лучше, чем
188 Много цифр традиционные (вроде кластеризации по k-средним из главы 2), так что современный аналитик не должен делать круглые глаза, когда речь заходит о сетевых графах. Применительно к сетям кластерный анализ часто называют «определением сообществ», что, несомненно, правильно, так как многие сетевые графы отображают социальные отношения, а их кластеры формируют сообщества. В этой главе я сосредоточусь на алгоритме определения сообществ под названием модульная максимизация. На высоком уровне модульная максимизация «награждает» вас каждый раз, когда вы помещаете в один кластер двоих хороших друзей, и «штрафует», когда вы помещаете вместе двоих незнакомцев. Собирая «награды» и избегая, по возможности, «штрафов», эта техника помогает вам добиться естественной кластеризации клиентов, причем, в отличие от кластеризации по k-средним вам не нужно выбирать k. Алгоритм делает это за вас! Таким образом, этот метод использует неконтролируемое машинное обучение на новом уровне знаний. Кроме того, безусловно привлекательная с математической точки зрения кластеризация по k-средним служит нам уже полвека. А техника, использованная в этой главе, разработана всего пару лет назад. Настоящий пирожок с пылу с жару! Что такое сетевой граф? Сетевой граф — это набор предметов, называемых вершинами графа, которые соединены друг с другом ребрами (или связями). Социальные сети, такие как Facebook, содержат много данных, которые легко можно объединить в сетевой граф — вы и ваши друзья, друзья друзей. Кстати, термин «социальный граф» последние годы стал чрезвычайно популярен. Вершины сетевого графа, конечно, не обязаны символизировать людей, а ребра — личные отношения. Кроме пользователей Facebook, вершины могут олицетворять и страницы понравившегося вам текста. Из этих «нравится» и состоят ребра графа. Точно так же вы можете создать сетевой граф остановок общественного транспорта вашего города — или всех направлений и путей сообщения авиакомпании Delta (чтобы лицезреть классический сетевой граф, достаточно зайти на сайт любой авиакомпании). Вы можете притвориться разведчиком и составить граф всех позвонивших по спутниковому телефону GPS из Аль-Каиды в страны Магриба. После утечки данных о попытках шпионской деятельности NSA, организованной Эдвардом Сноуденом, этот тип сетевого графа привлек большое внимание прессы. Один из примеров — дискуссия в конгрессе о способности NSA произвести «трехшаговый»
5. Кластерный анализ, часть II запрос — забраться в сетевой граф данных о звонках и найти людей на расстоянии трех шагов от известного террориста (вершины, связанные с террористом тремя ребрами на графе). Каким бы ни был ваш бизнес, у вас наверняка есть граф со спрятанными в нем данными. Один из моих любимых сетевых проектов для построения графов — DocGraph (http://notonlydev.com/docgraph/). Некоторые использовали закон о свободе информации для создания графа всех видов медицинских обращений. Одни доктора связаны с другими посредством обращений, а граф можно использовать для определения сообществ, их авторитетных представителей (докторов, к которым все ходят, чтобы получить итоговое заключение при нестандартном диагнозе) и даже случаев медицинского мошенничества и злоупотребления. Сетевые графы — пока редкое явление в мире аналитики. Они эстетичны и одновременно чрезвычайно практичны при хранении и выполнении обычного анализа. Они позволяют аналитикам с помощью алгоритмов или визуально разрабатывать новые методы всех сортов — кластеры, выбросы, местные источники влияния и мосты между различными группами. В следующем разделе мы визуализируем немного сетевых данных, чтобы вы поняли механизм работы. Визуализируем простой граф Сериал «Друзья» был одним из самых популярных комедийных шоу 1990-х и начала 2000-х годов. Действие разворачивается с участием шестерых друзей: Росса, Рейчел, Джоуи, Чендлера, Моники и Фиби. (Если вы никогда не слышали о них, то вы либо чрезвычайно юны, либо безвылазно провели всю жизнь в пещере.) Эти шестеро постоянно вовлечены в романтические отношения различного характера: настоящие романы, выдуманные романы, которые никогда ни к чему не приводят, романы на спор и т. д. Представьте, что эти персонажи — вершины (или узлы) графа, а их отношения — ребра. С ходу могу начертить такие ребра: Росс и Рейчел, разумеется; • Моника и Чендлер, которые, в конце концов, поженились; • Джоуи и Рейчел, у которых был недолгий роман, но в итоге они нашли, что • это «слишком странно»; Чендлер и Рейчел, которые встречались в серии про инцидент со столи• ком для бассейна. В этой серии Рейчел представляет, что было бы, если бы она встречалась с Чендлером; 189
190 Много цифр Чендлер и Фиби, которые играют в отношения и, в конце концов, вынуж• дены поцеловаться, потому что Чендлер отказывается признать, что он встречается с Моникой. Эти шесть персонажей и пять отношений могут быть представлены в виде графа, показанного на рис. 5-1. Росс Рейчел Джоуи Моника Чендлер Фиби Рис. 5-1. Диаграмма (псевдо)романов в сериале «Друзья» Довольно просто, не так ли? Вершины и ребра. Вот и все, что нужно для сетевого графа. Заметьте, насколько сетевые графы не похожи на графики, которые вам встречались: точечные диаграммы, линейные графики и столбчатые диаграммы. Они — совсем другие «звери». На рис. 5-1 изображен неориентированный сетевой граф, потому что отношения обоюдны по определению. А вот данные, например, из Twitter будут уже ориентированным графом: я могу подписаться на вас, но вы не обязаны подписываться на меня. Ребра ориентированного графа обычно изображаются стрелочками. Один из минусов использования Excel для работы с сетевыми графами состоит в том, что, в отличие от разнообразных графиков и диаграмм, граф нельзя визуализировать встроенными в Excel средствами. Так вот, в этой главе я намереваюсь отступиться от собственных правил и использовать стороннее программное обеспечение для расчетов и визуализации графов, а именно Gephi. Его подробное описание вы найдете в следующем разделе. Вы вправе игнорировать в этой главе все, что связано с Gephi, если хотите. Весь поиск и добыча сетевых данных могут быть выполнены без визуализации сети в Gephi, я прибегаю к нему просто потому, что оно мне нравится. Но если вы хотите работать с таким типом графов, то кроме визуализации вам понадобится числовое представление данных. Одно из подобных интуитивных
5. Кластерный анализ, часть II NODEXL Если вы пользуетесь Excel 2007 или 2010, то Social Media Research Foundation выпустила для вас шаблон NodeXL, благодаря которому вы можете строить сетевые графы в Excel. Я не буду его описывать в этой книге, потому что век развития программного обеспечения только начинается и этот шаблон не совместим с LibreOffice и Excel 2011 для MacOS. Если вам интересно, можете поискать NodeXL для вашей системы здесь: http://www.smrfoundation.org/nodexl/. представлений называется матрицей смежности. Матрица смежности — это просто таблица вершин, заполненная 0 и 1, где 1 в конкретной ячейке означает «ребро здесь», а 0 — «эти вершины не связаны». Вы можете создать матрицу смежности из данных о «Друзьях», вроде той, что изображена на рис. 5-2 (на мой взгляд, эта матрица похожа на лобстера, образованного космолетами из игры Galaga). Имена друзей расположены по вертикали и горизонтали, а отношения между ними показаны 1. Обратите внимание на симметричность матрицы по диагонали — оттого, что граф неориентированный. Если Джоуи имеет ребро с Рейчел, значит, верно и обратное — и матрица смежности показывает это. Если бы отношения были односторонними, матрица бы получилась несимметричной. Рис. 5-2. Матрица смежности для данных из «Друзей» 191
192 Много цифр Ребра здесь представлены единицами, однако это вовсе не обязательно. Ребрам можно добавить числовые значения, например вместимость: представьте самолеты разной вместимости, летящие по определенным маршрутам, или различные волновые диапазоны, использующиеся для разных целей в информационной сети. Матрица смежности со значениями также называется матрицей мер конвергенции. Краткое введение в Gephi Итак, давайте запустим Gephi, чтобы вы смогли импортировать и визуализировать набор данных из «Друзей» (в дальнейшем, когда вам станет все понятно, вы научитесь обходиться без него). Gephi — это открытый программный инструмент для визуализации сетей, написанный на Java, основной виновник происходящего за ширмой многих сетевых визуализаторов, с которыми вы сталкиваетесь сегодня в Интернете. Рисовать внушительные картинки достаточно просто. Но неискушенные люди, похоже, принимают их за чистую монету и набрасываются на них, как кролики на морковку. Причина, по которой я решил отступиться от своего принципа использовать только встроенные инструменты Excel, заключается в том, что Gephi заполняет нишу сетевой визуализации, притом совершенно бесплатно. К тому же оно совместимо с Windows, MacOS и Linux, так что неважно какой у вас компьютер — вы можете повторять все действия за мной. Разумеется, вы не обязаны осуществлять всю эту визуализацию. Можете просто следить за мной по рисункам, но я бы все же рекомендовал «запачкать руки» цифрами. В конце концов, это чертовски забавно! Но не стоит забывать, что эта книга не о Gephi. Если вы действительно хотите пуститься во все тяжкие с этим инструментом, загляните на wiki.gephi.org за более подробными инструкциями. Установка Gephi и подготовка файлов Чтобы загрузить Gephi, пройдите на gephi.org, а затем загрузите и установите пакет, следуя инструкциям для вашей операционной системы на http:// gephi.org/users/install/. С общим руководством по Gephi можно ознакомиться по ссылке https:// gephi.org/users/quick-start/. Для экстренных случаев программа имеет и собственный раздел помощи «Help» в меню. После установки Gephi подготовьте матрицу смежности для импорта в графическую форму.
5. Кластерный анализ, часть II Мне кажется, что импорт матрицы смежности в Gephi имеет один лишний шаг. Почему? Потому что Gephi не поддерживает матрицы смежности, разделенные запятыми. Каждое значение должно быть отделено от другого точкой с запятой. Несмотря на предостережение Курта Воннегута в «Человеке без родины»: «Не пользуйтесь точкой с запятой. Это гермафродит-трансвестит, не представляющий из себя абсолютно ничего. Все, на что способен этот знак — показать, что вы учились в колледже», Gephi проигнорировал этот дельный совет. Следуйте за мной — и я проведу вас целыми и невредимыми через процесс импорта. Я создал таблицу FriendsGraph.xlsx, доступную на сайте книги www.wiley. com/go/datasmart. Впрочем, при желании можете сами немного повозиться с небольшим набором данных и матрицей смежности с рис. 5-2. Первое, что необходимо сделать, чтобы импортировать этот граф в Gephi — это сохранить его как CSV, файловый формат, являющийся обычным текстом, разделенным запятыми. Для этого нажмите «Сохранить как» в Excel и выберите CSV из списка форматов. Имя файла будет FriendsGraph.csv. При сохранении Excel может ругаться на вас и выдавать различные предупреждения, но я разрешаю вам их игнорировать. После экспорта файла все запятые замените на точки с запятой. Для этого откройте файл в текстовом редакторе (например, в Блокноте, если вы используете Windows, или Текстовый редактор, если у вас MacOS) и с помощью «Найти и заменить» поменяйте запятые на точки с запятой. Сохраните файл. На рис. 5-3 этот процесс показан в текстовом редакторе. Рис. 5-3. Замена запятых точками с запятой в файле CSV FriendsGraph Проделав вышесказанное, откройте свежеустановленную копию Gephi и, используя опцию Open Graph File на стартовой странице (как на рис. 5-4), выберите файл FriendsGraph.csv, который вы только что отредактировали. При попытке открыть файл вам выскочит окошко сообщения об импорте. Обратите внимание: найдены шесть вершин и десять ребер. Почему десять? Дело в том, что матрица смежности симметрична, следовательно, все отношения 193
194 Много цифр Рис. 5-4. Открытие файла FriendsGraph.csv в Gephi продублированы. Чтобы избавиться от лишнего набора ребер, поменяйте тип графа (Graph Type) с ориентированного (directed) на неориентированный (undirected) в окошке импорта (как на рис. 5-5). Нажмите ОК. Визуализация графа Удостоверьтесь, что в верхнем левом углу программы выбрана вкладка Overview. Таким образом, ваш Gephi должен выглядеть примерно как мой на рис. 5-6. Вершины и ребра беспорядочно разбросаны по экрану. Увеличение на ужасном минимуме, так что вы еле различаете контуры. Изначально вы рассчитывали на нечто более удобоваримое, не так ли? Причешем немного наш граф. Можно приблизить изображение колесиком мышки и двигать его, удерживая правую клавишу. Нажимая на кнопку Т внизу окна просмотра, вы можете добавить названия вершинам графа, чтобы знать, какая вершина к какому персонажу относится. После увеличения, подгонки и добавления имен граф выглядит как на рис. 5-7.
5. Кластерный анализ, часть II Рис. 5-5. Импорт графа «Друзей» Рис. 5-6. Начальный вид графа «Друзей» 195
196 Много цифр Нужно, однако, чтобы он выглядел еще лучше. К счастью, у Gephi есть пачка алгоритмов для автоматизации этого процесса. Многие из них используют такие средства, как гравитация между соединенными вершинами и отталкивание между несоединенными для более удачного расположения элементов. Раздел отображения в Gephi — это нижнее левое окно панели обзора. Не стесняйтесь спонтанно выбирать пункты из этого меню, чтобы попробовать разные режимы. ЗАМЕТКА Имейте в виду, что некоторые алгоритмы внешнего вида могут сжать или растянуть ваш граф так, что придется увеличивать или уменьшать изображение, чтобы увидеть его целиком. Это относится и к названиям вершин — их размеры будут меняться совершенно хаотично, но, к счастью, можно использовать Label Adjust — функцию подгонки названий под выпадающим меню внешнего вида графа. Рис. 5-7. Граф «Друзей» уже разборчив, но все еще хаотичен
5. Кластерный анализ, часть II Чтобы добиться внешнего вида, который меня устраивает, я выбираю ForceAtlas 2 в меню внешнего вида и нажимаю «Run». Это немного сместит мои вершины на более подходящие места. Но названия вершин теперь огромны (рис. 5-8). Выберите функцию подгонки названий (Label Adjust) из меню и нажмите «Run». Теперь должно получиться кое-что получше. В частности, становится видно, что Рейчел и Чендлер в этом графе имеют больше всего связей. Очевидно, Моника и Росс далеки друг от друга, потому что они — брат и сестра, и т. д. Степень вершины Одно из понятий, весьма важное для понимания данной главы, — это степень вершины, то есть количество ребер, связанных с данной вершиной. У Чендлера степень равна 3, в то время как у Фиби — всего 1. Эти степени можно использовать в Gephi для изменения размера вершин. Рис. 5-8. Последствия запуска ForceAtlas 2 на графе «Друзей» 197
198 Много цифр Чтобы разобраться в средней степени нашего графа и в том, у кого именно какая степень, нажмите кнопку Average Degree (средняя степень) справа в разделе статистики. Нажатие вызовет всплывающее окошко типа того, что показано на рис. 5-9, где средняя степень графа равна 1,6667 при четырех вершинах со степенью 1 и двух — со степенью 3 (Рейчел и Чендлер). Закройте это окошко и переместитесь в область ранжирования (Ranking section) окна обзора (Overview) в верхнем левом отделе. Выберите раздел вершин (Nodes) и значок в виде рубина, который отображает изменение размера. Выберите степень (Degree) из выпадающего меню и перемещайтесь между минимальным и максимальным размером вершин. После нажатия «Применить» (Apply) Gephi изменит размер вершин согласно степени их важности. Этот раздел окна обзора изображен на рис. 5-10. Рис. 5-9. Расчет средней степени графа
5. Кластерный анализ, часть II Рис. 5-10. Изменение размеров графа согласно степеням вершин ПОЛУСТЕПЕНЬ ЗАХОДА, ПОЛУСТЕПЕНЬ ИСХОДА, ЗНАЧИТЕЛЬНОСТЬ И ПОВЕДЕНИЕ В ориентированном графе число ребер, подходящих к вершине, называется полустепенью захода. Количество же ребер, исходящих из вершины, — полустепенью исхода. Полустепень захода в социальной сети — это простой способ проверить авторитет вершины. Как правило, это первое, на что обращают внимание пользователи Facebook или Twitter, чтобы выяснить значительность: «Ах, у них куча подписчиков… наверное, они очень круты!» А теперь обыграем эту величину. Кто же эти подписчики, чьи ребра заходят в вашу вершину? Может, они фальшивые пользователи, которых вы подписали на себя сами, чтобы поднять свою репутацию? Google использует полустепень захода (для поисковой системы это количество обратных связей по ссылкам) в своем PageRank-алгоритме (алгоритме ранжирования 199
200 Много цифр страниц). Процесс, когда кто-то симулирует входящие ссылки на собственный сайт, чтобы повысить свой рейтинг и подняться в списке результатов поиска, называется массовым размещением ссылок, или попросту ссылочным спамом. В контекстах вроде интернет-поиска, где ранжирование — это большой бизнес, для вычисления подобного «плохого поведения» задействуйте более сложные показатели, вроде рейтинга, фактора влияния и централизованности. Как вы убедитесь на примере в главе 9, эти концепции сетевых графов полезны для определения выбросов. Кроме того, вы можете не только узнать, кто является центром вашего графа, но и кто еще находится на периферии. Приятная картинка Хотя эти картинки неплохо выглядят, вы вряд ли решитесь повесить их на стену. Чтобы подготовить граф к печати, зайдите на панель просмотра (Preview) вверху экрана. Под вкладкой настроек просмотра (Preview Setting) выберите пресет Black Background из выпадающего меню пресетов (теперь вы больше похожи на хакера) и нажмите на кнопку обновления страницы (Refresh) в нижнем левом углу окна. Gephi нарисует ваш граф потрясающе красивым и плавным (рис. 5-11). Обратите внимание, как вместе с самими вершинами изменились размеры подписей. Они просто великолепны! Ребра этого графа показались мне немного тонковатыми, так что я изменил их толщину в левой панели настроек с 1 до 3. Если вы хотите превратить это изображение в графический файл (к примеру, файл.png), нажмите кнопку Export в левом нижнем углу раздела настроек обзора. После этого вы можете разместить свой граф на сайте, вставить в презентацию PowerPoint и даже в книгу про науку о данных! Прикосновение к данным графа Перед тем как вернуться к Excel и приступить к решению задачи об оптовой торговле вином из главы 2, я бы хотел провести небольшую экскурсию по разделу Лаборатории данных (Data Laboratory) Gephi. Нажав на Data Laboratory вверху экрана, вы увидите данные за вашим графом — вы их импортировали в программу. Обратите внимание, что разделов с данными два: вершины (Nodes) и ребра (Edges). В разделе вершин можно увидеть шестерых персонажей. И, так как вы немногим раньше рассчитали среднюю степень графа, в набор данных
5. Кластерный анализ, часть II Рис. 5-11. Хорошенький граф «Друзей» о вершинах добавился столбец со степенью (Degree). Если хотите, экспортируйте этот столбец обратно в Excel нажатием кнопки «Export table» в меню, как на рис. 5-12. Кликнув на раздел ребер (Edges), вы получаете пять ребер с вершинами на концах. Каждое ребро имеет значение, равное 1, так как вы импортировали матрицу смежности, заполненную единицами. Если бы вы изменили значения некоторых из них на большие, в случае, скажем, состоявшейся свадьбы, то эти значения были бы отражены в этом столбце (а также повлияли бы на внешний вид, обеспеченный ForceAtlas 2). Отлично! Вот и закончен ваш девятикилометровый тур по Gephi. Вернемся теперь к кластеризации данных об оптовой торговле вином, а к Gephi вернемся позже для расчетов и визуализации. 201
202 Много цифр Рис. 5-12. Информация о вершинах с расчетом степени в разделе Data Laboratory Строим граф из данных об оптовой торговле вином ЗАМЕТКА Таблица Excel, использованная в этой главе, доступна для скачивания на сайте книги, www.wiley.com/go/datasmart. Она содержит исходные данные, на случай если вы хотите работать с ней. Если нет — просто следите за мной, используя уже заполненные листы. В этой главе я продемонстрирую, как можно определить кластеры в ваших данных о заказах с помощью представления их в виде графа. В некоторых видах бизнеса данные (такие как медицинские, с направлениями от одного специалиста к другому, которые я упоминал ранее) уже имеют форму графа. Но в этом случае матрица заказов вина из главы 2 не отражает отношений между покупателями напрямую. Для начала нужно сформулировать, как нам изобразить набор данных о продаже вина в виде сети. Имеется в виду конструирование некоей матрицы смежности, вроде той, что мы делали для «Друзей» (рис. 5-2). Оттуда вы сможете визуализировать и рассчитать все, что угодно, относящееся к графу. Я выбираю анализ с помощью вкладки Matrix в таблице WineNetwork.xlsx (доступной для скачивания вместе с этой книгой). Если помните, это та же самая вкладка Matrix, которую вы создали в начале главы 2 из транзакционных данных о продаже вина и оптовых метаданных.
5. Кластерный анализ, часть II Изображенные на рис. 5-13, строки вкладки Matrix дают нам информацию о 32 сделках по продаже вина, предложенных Винной Империей Джоуи Бэг О'Донатса в прошлом году. В столбцах таблицы расположены имена покупателей, а каждая ячейка (сделка, покупатель) имеет значение 1 в случае, если данный покупатель заключил данную сделку. Рис. 5-13. Вкладка Matrix, показывающая кто что купил Вам нужно превратить эти данные из главы 2 во что-то, похожее на матрицу смежности «Друзей». С чего же начать? Вы уже делали нечто подобное, создавая матрицу расстояний для силуэта по k-средним в главе 2. Для этого расчета вы создавали матрицу расстояний между всеми покупателями, основываясь на заключенных ими сделках (рис. 5-14). Этот набор данных был ориентирован на отношения «покупатель-покупатель», в точности как набор данных о «Друзьях». Связи между покупателями устанавливались по признаку того, как располагались их заказы. 203
204 Много цифр Рис. 5-14. Расстояния между покупателями из главы 2 Но есть пара проблем с матрицей расстояний между покупателями, созданной в главе 2: в конце главы 2 вы обнаружили, что в случае с данными о заказах асимме• тричное подобие и измерения расстояний между покупателями работают гораздо лучше евклидова расстояния. Вам важны заказы, а не их отсутствие; проведя ребро между двумя покупателями, вы руководствуетесь сходством • этих покупателей, а не различиями между ними, поэтому данный расчет нужно «перевернуть». Эта близость заказов видна благодаря близости косинусов, поэтому вам нужно создать матрицу близости, то есть смежности, в противовес матрице расстояний из главы 2. Создание матрицы близости косинусов В этом разделе мы возьмем вкладку Matrix и сконструируем из нее граф «покупатель-покупатель» с помощью близости косинусов. В Excel этот процесс с использованием пронумерованных строк и столбцов и формулы OFFSET/СМЕЩ идентичен тому, что использовался в главе 2 для построения таблицы евклидовых расстояний. Подробнее о функции OFFSET/СМЕЩ читайте в главе 1. Начнем с создания вкладки под названием Similarity, в которую вставим сеть из покупателей, где каждый пронумерован во всех направлениях. Не забывайте, что копирование и вставка покупателей из вкладки Matrix соответственно строкам возможно только с использованием меню «Специальная вставка» и галочки в поле «Транспонировать».
5. Кластерный анализ, часть II Готовая пустая сетка показана на рис. 5-15. Рис. 5-15. Пустая таблица для матрицы близости косинусов Начнем с вычисления близости косинусов между Адамсом и им же самим (которая должна равняться 1). Освежим в памяти определение близости косинусов между бинарными заказами двух покупателей, которое давалось в главе 2: Количество совпадающих заказов по двум векторам, разделенное на произведение квадратного корня из количества заказов по первому вектору, умноженного на квадратный корень из количества заказов по второму вектору. Вектор заказов Адамса — Matrix!$H$2:$H$33; так что для расчета близости косинусов в ячейке С3 используется следующая формула: =SUMPRODUCT(Matrix!$H$2:$H$33,Matrix!$H$2:$H$33)/(SQRT(SUM (Matrix!$H$2:$H$33))*SQRT(SUM(Matrix!$H$2:$H$33))) =СУММПРОИЗВ(Matrix!$H$2:$H$33,Matrix!$H$2:$H$33)/(КОРЕНЬ(СУММ (Matrix!$H$2:$H$33))*КОРЕНЬ(СУММ(Matrix!$H$2:$H$33))) В начале формулы берется SUMPRODUCT/СУММПРОИЗВ из векторов заказа, которые вас интересуют, и рассчитывается количество совпавших заказов. В знаменателе перемножаются квадратные корни из количества заказов, сделанных каждым покупателем. 205
206 Много цифр Теперь, когда эта формула работает для Адамса, вы можете растянуть ее на весь лист, чтобы не перепечатывать снова и снова. И для этого используется формула OFFSET/СМЕЩ. Заменяя Matrix!$H$2:$H$33 на OFFSET(Matrix!$H$2: $H$33,0,Similarity!C$1)//СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!C$1) для столбцов и OFFSET(Matrix!$H$2:$H$33,0,Similarity!$A3)//СМЕЩ(Matrix! $H$2:$H$33,0,Similarity!$A3) для строк, вы получаете формулу, которая использует номера покупателей в столбце А и строке 1 для сдвига векторов заказа, применяемых в расчете близости. Это приводит к несколько более уродливой (простите!) формуле для ячейки С3: =SUMPRODUCT(OFFSET(Matrix!$H$2:$H$33,0,Similarity!C$1), OFFSET(Matrix!$H$2:$H$33,0, Similarity!$A3))/(SQRT(SUM (OFFSET(Matrix!$H$2:$H$33,0, Similarity!C$1)))*SQRT(SUM (OFFSET(Matrix!$H$2:$H$33,0, Similarity!$A3)))) =СУММПРОИЗВ(СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!C$1), СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!$A3))/(КОРЕНЬ(СУММ (СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!C$1)))*КОРЕНЬ(СУММ (СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!$A3)))) Эта формула фиксирует Matrix!$H$2:$H$33 как абсолютную ссылку, так что как бы вы ни двигали ее по таблице, она останется неизменной. Similarity! C$1 изменит номера столбцов, но будет оставаться в строке 1, как вы и планировали, а Similarity!$A3 останется в столбце А. Но это еще не все. Вы хотели создать граф покупателей, которые похожи друг на друга, но наверняка не задумались о диагонали матрицы. Да, Адамс идентичен сам себе и имеет близость косинусов, равную 1, но вам не нужен граф с ребрами, которые замыкаются на ту же вершину, от которой исходят, поэтому придется сделать все подобные значения равными 0. Это просто означает свертывание расчета близости косинусов в утверждение с IF/ЕСЛИ, чтобы проверить, не равняется ли покупатель в строке покупателю в столбце. Таким образом, итоговая формула выглядит так: IF(C$1=$A3,0,SUMPRODUCT(OFFSET(Matrix!$H$2:$H$33,0,Similarity! C$1),OFFSET(Matrix!$H$2:$H$33,0,Similarity!$A3))/(SQRT (SUM(OFFSET(Matrix!$H$2:$H$33,0,Similarity!C$1)))*SQRT(SUM (OFFSET(Matrix!$H$2:$H$33,0,Similarity!$A3))))) ЕСЛИ(C$1=$A3,0,СУММПРОИЗВ(СМЕЩ(Matrix!$H$2:$H$33,0,Similarity! C$1),СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!$A3))/(КОРЕНЬ(СУММ (СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!C$1)))*КОРЕНЬ(СУММ (СМЕЩ(Matrix!$H$2:$H$33,0,Similarity!$A3)))))
5. Кластерный анализ, часть II Итак, теперь, когда у вас есть формула, которую можно перетаскивать куда угодно, возьмите ячейку С3 за нижний правый угол и растяните вправо до СХ3 и вниз до СХ102. В итоге в вашем распоряжении — матрица близости косинусов, которая показывает, какие покупатели похожи. Применяя условное форматирование, получаем результат, показанный на рис. 5-16. Построение графа N-соседства Лист Similarity — это граф со значениями. Каждая пара покупателей имеет между собой или 0 или ненулевое значение близости косинусов, которое отображает толщину ребра между ними. Таким образом, мы видим, что матрица близости — это матрица смежности. Рис. 5-16. Заполненная матрица близости косинусов покупателей Так почему бы не вынуть эту матрицу смежности из таблицы и не вставить поскорее в Gephi? Может, вы уже настроились анализировать все на графе. Конечно, экспорт CSV и дальнейший импорт в Gephi возможен и на этом этапе. Но позвольте мне предостеречь вас от такого шага и сразу показать картину графа (рис. 5-17) после импорта в Gephi. Это жуткая каша из ребер, торчащих отовсюду. Излишнее множество связей мешают алгоритму отображения правильно расположить вершины относительно друг друга, так что в итоге мы имеем неуклюжее месиво. Вы заключили около 300 сделок и превратили их в тысячи ребер графа. Некоторые из них можно отнести к случайным. В самом деле, может, мы с вами 207
208 Много цифр Рис. 5-17. Месиво близости косинусов межпокупательского графа совпали по одной сделке из десяти и у вас микроскопическая близость косинусов — так стоит ли проводить на графе это ребро? Для придания нашим данным осмысленности удалите некоторые не особо значимые ребра и оставьте только самые крепкие связи — те, в которых есть еще что-то, кроме случайного удачного совпадения сделок. Прекрасно, но какими именно ребрами можно пренебречь? Существуют две популярные техники удаления ребер из сетевых графов. Можно взять матрицу смежности и построить одно из двух: граф r-окрестности: здесь мы оставляем только ребра определенной тол• щины. К примеру, в матрице смежности числовое значение ребра может изменяться от 0 до 1. Возможно, стоит избавиться от всех ребер со значениями меньше 0,5. Тогда получится пример графа r-окрестности с r = 0,5; граф k ближайших соседей (k nearest neighbors, kNN): в этом случае вы • определяете максимальное число ребер, исходящих из одной вершины. Например, если установить k= 5, то при каждой вершине останутся только 5 ребер с наибольшими значениями.
5. Кластерный анализ, часть II Но ни тот, ни другой граф ничем не лучше второго. Все зависит от ситуации. В этой главе я сфокусируюсь на первом варианте, графе r-окрестности. А второй вариант с kNN оставлю вам как упражнение для решения этой задачи другим способом. Его довольно просто выполнить в Excel, используя функцию LARGE/НАИБОЛЬШИЙ (более подробно эта функция описана в главе 1). В главе 9 мы также воспользуемся kNN для определения выбросов. Так как же превратить вкладку Similarity в матрицу смежности r-окрестности? Для начала нужно определить r. В белом поле под матрицей близости подсчитайте количество ребер (ненулевых значений близости), которые есть у вас в матрице смежности, с помощью функции в ячейке С104: =COUNTIF(C3:CX102,">0") =СЧЁТЕСЛИ(C3:CX102,">0") Эта функция выдает нам 2950 ребер, созданных из исходных 324 сделок. Что, если оставить только 20% с наибольшими значениями? Каким для этого должно быть r? Попробуем прикинуть: при 2950 ребрах 80-м перцентилем по близости будет примерно то, что соответствует 590-му ребру. Так что под расчетом количества ребер в С105 можно использовать функцию LARGE/НАИБОЛЬШИЙ, чтобы узнать значение 590-го по порядку уменьшения значений ребра (рис. 5-18): Рис. 5-18. Вычисление 80-го перцентиля из значений ребер 209
210 Много цифр =LARGE(C3:CX102,590) =НАИБОЛЬШИЙ(C3:CX102,590) Функция выдает значение 0,5. Таким образом, можно оставить 20% ребер с наибольшими значениями, просто отбросив все, значения близости косинусов которых меньше 0,5. Теперь, когда с графа r-окрестности убрано все лишнее, сборка матрицы смежности будет очень простой. Создайте новый лист в вашей таблице и назовите его r-NeighborhoodAdj, а затем вставьте имена покупателей в столбец А и строку 1, чтобы получилась таблица. В любой ячейке этой таблицы нужно поставить 1, если значение близости из предыдущей таблицы Similarity больше 0,5. Таким образом, к примеру, в ячейке В2 можно использовать такую формулу: =IF(Similarity!C3>=Similarity!$C$105,1,0) =ЕСЛИ(Similarity!C3>=Similarity!$C$105,1,0) Функция IF//ЕСЛИ сравнивает соответствующие значения близости с величиной, выбранной нами как ограничение в Similarity!$C$105(0,5), и ставит 1, если эта величина достаточно велика. Так как Similarity!$C$105 содержит абсолютные ссылки, вы можете растянуть формулу на весь лист, чтобы заполнить матрицу целиком, как показано на рис. 5-19 (я использовал условное форматирование). Рис. 5-19. Матрица смежности окрестности 0,5 Теперь у вас есть граф r-окрестности данных о заказах покупателей. Вы трансформировали данные о заказах в отношения между покупателями и затем ограничили их до набора весьма значимых единиц.
5. Кластерный анализ, часть II Если бы вам нужно было сейчас экспортировать r-окрестность в матрицу смежности в Gephi и затем получить графическое изображение, то получилось бы гораздо лучше, чем в предыдущий раз, изображенный на рис. 5-17. Экспортируйте граф сами. Сделайте эти пару шагов с точкой с запятой и взгляните на результат вместе со мной. Как показано на рис. 5-20, в графе есть по меньшей мере два тесно связанных сообщества, похожие на опухоли. Одно из них довольно сильно отделено от остальной массы, что прекрасно, потому что это значит: интересы его участников отличны от остальных покупателей. Рис. 5-20. Визуализация r-соседского графа в Gephi А здесь мы видим старого доброго Паркера, единственного покупателя, у которого не нашлось ребер с близостью косинусов большей или равной 0,5. Так что он сам по себе одиноко плачет в уголке. Мне, честно, неудобно за этого парня, потому что алгоритмы отображения стараются расположить его как можно дальше от связанной части графа. 211
212 Много цифр Отлично! Итак, теперь у вас есть граф, который можно охватить взглядом. И на деле простое отображение графа и разглядывание его — зрительное разделение на группы — само по себе не так уж плохо. Вы взяли многомерные данные и дистиллировали их в нечто плоское, вроде пола актового зала из главы 2. Но если бы у вас были тысячи покупателей, а не сотни, глаза бы уже не так помогали. Конечно, даже сейчас на графе есть такие покупатели, которых трудно сгруппировать. В одной ли они группе или в нескольких? И в этот самый момент в игру вступает модульная максимизация. Алгоритм использует отношения между людьми на графе, чтобы делать предположения об их принадлежности к той или иной группе, даже если граф не умещается в ваше поле зрения. Числовое значение ребра: очки и штрафные в модулярности графа Представьте, что я — покупатель, зависающий где-то в нашем графе, и хочу узнать, кто еще входит в мою группу. Как насчет той дамы, связанной со мной ребром? Может быть. Наверное. Во всяком случае, мы связаны. А что насчет того парня с другой стороны графа, с которым я соединен ребром? Хммм, гораздо менее вероятно. Модулярность графа количественно выражает это интуитивное чувство, что группы определяются связями. Техника присваивает «очки» каждой паре вершин. Если две вершины не связаны, мне полагается штраф за расположение их в одной группе. Если две вершины связаны, нужно меня наградить. Какое бы я ни сделал предположение, модулярность графа использует сумму этих «очков» для каждой пары вершин, которые отнесены к одной и той же группе. Используя алгоритм оптимизации (вы знали — не обойтись без «Поиска решения»!), вы можете «испытать» другие предположения о принадлежности к группам графа и посмотреть, которое из них наберет больше всего «очков» и меньше всего «штрафных». Это и будет выигрышной комбинацией модулярности. Кто же такие «очки» и «штрафные»? Применяя модулярную максимизацию, вы даете себе одно «очко» каждый раз, когда группируете в один кластер две вершины, имеющие общее ребро в матрице. И получаете ноль очков, если группируете две несвязанные вершины. Проще простого.
5. Кластерный анализ, часть II Но что со штрафными? Вот где алгоритм модулярной максимизации становится по-настоящему креативным. Вспомним наш граф «Друзей», изображенный на рис. 5-1. Модулярная максимизация основывает свои штрафные на следующем утверждении, в котором фигурируют две вершины: Если бы взяли этот граф и стерли бы на нем середины всех ребер, а затем соединили бы их заново случайным образом несколько раз, сколько бы в этом случае ребер получилось между двумя вершинами? Вот это предполагаемое число и есть «штрафное». Почему предполагаемое число ребер между двумя вершинами — это штраф? Да потому, что вы не собираетесь давать столько «очков» модели за группировку людей, основанную на отношениях, которые бы с большой вероятностью возникли, так как обе стороны чрезвычайно социальны. Я хочу узнать, какая часть этого графа — это намеренные отношения и связи, а какая — нечто, произошедшее по причине «А, ну да, Чендлер связан с кучей людей, так что наверняка Фиби — одна из них». Это означает, что ребра между двумя очень разборчивыми людьми «менее случайны» и стоят больше, чем связи между двумя общительными. Чтобы понять это яснее, посмотрите на версию графа «Друзей», в которой я стер середины ребер. Эти недоребра называются «пеньками» (рис. 5-21). Росс Рейчел Джоуи Моника Чендлер Фиби Рис. 5-21. Обрубленный граф «Друзей» А теперь подумайте, как связать этот граф случайным образом. На рис. 5-22 я нарисовал один ужасный вариант. Да, при случайном соединении более чем вероятно соединение кого-то с собой самим, особенно если из их вершины торчит несколько «пеньков». Напоминает ужастик. 213
214 Много цифр Росс Рейчел Джоуи Моника Чендлер Фиби Рис. 5-22. Соединяем заново граф «Друзей» Рис. 5-22 — всего лишь один из возможных вариантов соединения, верно? Существует множество возможностей даже для графа, в котором всего пять ребер. Обратите внимание, что Росс и Рейчел снова вместе. Каковы были шансы, что это произойдет? Основываясь на той же вероятности, определим, каково предположительное число ребер между двумя вершинами, если вы соединяете граф заново снова и снова? Для проведения случайного ребра нужно выбрать два случайных «пенька». Так какова вероятность того, что будут выбраны «пеньки» одной вершины? Вот случай Рейчел: у нее три «пенька» из десяти возможных (это удвоенное количество ребер). У Росса всего один. Поэтому вероятность, что вы выберете Рейчел для любого ребра — 30%, а вероятность, что вы выберете «пенек» Росса — 10%. Вероятности выбора вершин показаны на рис. 5-23. 3 10 1 10 Росс 1 10 Рейчел 1 10 Джоуи 3 10 Чендлер Моника 1 10 Фиби Рис. 5-23. Вероятности выбора вершин графа «Друзей»
5. Кластерный анализ, часть II Так что если вы выбирали и связывали вершины случайным образом, то могли выбрать Росса, а затем Рейчел, или Рейчел, а затем Росса. Упростив, получаем 10%, умноженные на 30%, или 30%, умноженные на 10%, что является 2, умноженной на 0,3 и умноженной на 0,1. Выходит 6%. Но мы ведь рисуем не одно ребро, верно? Нужно нарисовать случайный граф с пятью ребрами, так что у вас есть пять попыток для выбора комбинации. Предполагаемое количество ребер между Россом и Рейчел в таком случае будет равно 6, умноженному на 5, или 0,3 ребра. Да, все верно, количество предполагаемых ребер может быть дробным. Похоже, я взорвал ваш мозг в духе фильма «Начало». Допустим, я подброшу доллар Сакагавеи, который достанется вам, если выпадет орел, а не решка. 50% за то, что вы его получите, а 50% — нет. Ваш предполагаемый выигрыш — 0,5 × $1 = $0,50, даже при том, что на самом деле в этой игре вы никогда не выиграете 50 центов. Аналогично и здесь — у вас просто есть графы, на которых Росс и Рейчел связаны, а есть такие, на которых нет, но тем не менее предполагаемое значение их общего ребра — 0,3. Подробно эти расчеты показаны на рис. 5-24. 1 10 3 10 Росс 1 10 Вероятность получения Росс-Рейчел: Рейчел 2 # пеньков Росса 2 * # ребер 1 # пеньков Рейчел =2 2 * # ребер 10 3 10 1 10 Джоуи 3 10 Чендлер Моника Предполагаемое количество ребер между Россом и Рейчел: 2 * ребра 1 10 Фиби = # пеньков Росса # пеньков Рейчел 2 * # ребер 2 * # ребер # пеньков Росса * # пеньков Рейчел 2 * # ребер = = 3 10 Рис. 5-24. Предполагаемое количество ребер между Россом и Рейчел Если свести вместе «очки» и «штрафные», все должно проясниться. Поместив Росса и Рейчел в одну группу, вы не получите целую 1. Это из-за штрафа в 0,3 очка, равного предполагаемому количеству ребер в случайном графе, которое они бы получили в любом случае. Так что вам остается 0,7. Если вы не сгруппировали Росса и Рейчел, то скорее получите 0, чем 0,7. 215
216 Много цифр С другой стороны, Рейчел и Фиби не связаны. Но у них все та же вероятность общего ребра — 0,3. Это означает, что если вы поместите их в одну группу, то все равно получите штраф, но вот очков не заработаете, так что в итоге выходит –0,3. Почему? Потому что факт отсутствия ребра между Рейчел и Фиби что-то значит! Предполагаемое число ребер равнялось 0,3, но на этом графе их нет, так что в итоге это возможно намеренное разделение должно считаться. Если вы не поместили Рейчел и Фиби в одну группу, то ни одна из них не получит никаких очков, так что при прочих равных лучше бы вам поместить их в два разных кластера. Подводя итог, можно сказать, что «очки» и «штрафные» отражают то, насколько фактическая структура графа отличается от предполагаемой. Нужно определить группы, которые отвечают за эти различия. Модулярность определения групп — это просто сумма этих «очков» и «штрафных» для пар вершин, помещенных в одну и ту же группу, разделенная на общее количество «пеньков» в графе. Деление на количество «пеньков» сохраняет максимальную модулярность в пределах 1, вне зависимости от размеров графа, что облегчает сравнение разных графов между собой. Подготовка к итоговому подсчету Но хватит слов! Давайте рассчитаем модулярность для каждой пары покупателей на графе. Для начала сосчитаем, сколько «пеньков» у каждого покупателя и сколько всего «пеньков» в нашем графе. Обратите внимание, что количество «пеньков» покупателя — это просто степень его вершины. Во вкладке r-NeighborhoodAdj вы можете подсчитать степень вершины простым суммированием столбца или строки. Если там 1, то это ребро, следовательно, «пенек», а значит — он посчитан. Так, например, сколько «пеньков» у Адамса? Можно просто поместить в ячейку В102 следующую формулу — и ответ найден: =SUM(B2:B101) =СУММ(B2:B101) Получается 14. Точно так же можно просуммировать строку 2, поместив в формулу СХ2: =SUM(B2:CW2) =СУММ(B2:CW2) В этом случае тоже получается 14, и это то, чего мы ожидали, так как граф неориентированный.
5. Кластерный анализ, часть II Копируя эти формулы вниз и вправо соответственно, вы можете подсчитать «пеньки» для каждой вершины. А суммируя столбец СХ в строке 102 можно получить общее количество «пеньков» на графе. Как показано на рис. 5-25, всего в графе 858 «пеньков». Теперь, имея количество «пеньков», создайте вкладку Scores в вашей электронной таблице, куда затем вставьте и имена покупателей — в строку 1 и столбец А, в точности как во вкладке r-NeighborhoodAdj. Рассмотрим ячейку В2, в которой находится модулярность Адамса относительно себя самого. Получает ли он «очко» или нет? На самом деле это можно прочитать в матрице смежности, 'r-NeighborhoodAdj'!B2. Если значение в матрице смежности –1, то она просто копируется. Элементарно. Что же касается подсчета предполагаемого количества ребер, которое вам нужно в качестве «штрафных», то они подсчитываются точно так же, как показано на рис. 5-24: вероятность покупателя А × вероятность покупателя В / общее количество «пеньков» Сводя вместе эти «очки» и «штрафные» в ячейке В2, вы приходите к такой формуле: ='r-NeighborhoodAdj'!B2(('r-NeighborhoodAdj'!$CX2*'r-NeighborhoodAdj'!B$102)/ 'r-NeighborhoodAdj'!$CX$102) Рис. 5-25. Подсчет «пеньков» ребер на графе r-окрестности 217
218 Много цифр Получилось 0/1 по смежности минус предполагаемое количество. Обратите внимание, что в формуле использованы абсолютные ссылки на ячейки с количеством «пеньков», так что если вы перемещаете формулу, все в ней меняется соответствующим образом. Растягивая ее вниз и вправо, вы получаете значения, показанные на рис. 5-26. Рис. 5-26. Таблица модулярностей Для проверки обратимся к ячейке К2. В ней находится модулярность для кластеризации Адамс/Браун. Значение — 0,755. Адамс и Браун имеют общее ребро в матрице смежности, так что вы получаете 1 очко за их кластеризацию в одну группу ('r-NeighborhoodAdj'!K2 в формуле), но у Адамса 14 «пеньков», а у Брауна — 15, так что их предполагаемое количество ребер равно 14 × 15 / 858. Эта вторая часть формулы выглядит так: (('r-NeighborhoodAdj'!$CX2*'r-NeighborhoodAdj'!K$102)/ 'r-NeighborhoodAdj'!$CX$102) что оказывается равным 0,245. Сводя все вместе, получаем 1 – 0,245 = 0,755.
5. Кластерный анализ, часть II Переходим к кластеризации! Теперь у вас есть все необходимые значения. Все, что вам нужно сделать — это запустить оптимизационную модель, чтобы найти оптимальное распределение по группам. Буду заранее честен с вами. Нахождение оптимальных групп с помощью модулярности графа требует несколько более сложной подготовки оптимизации, чем вы встречали в главе 2. Подобные задачи часто решаются сложной эвристикой, вроде популярного лувенского метода (подробнее здесь: http:// perso.uclouvain.be/vincent.blondel/research/louvain.html), но в этой книге я обещал не заставлять вас писать код, так что придется обходиться «Поиском решения». Мы будем атаковать задачу с помощью метода под названием разделяющая кластеризация, или иерархическое разбиение. Для начала необходимо найти наилучший способ разделения графа на две группы. Затем мы разделим эти группы на четыре, и т. д., до тех пор, пока «Поиск решения» не заключит, что наилучший способ максимизации модулярности — это перестать делить группы. ЗАМЕТКА Разделяющая кластеризация — это противоположность другому известному методу — агломеративной кластеризации. Если бы мы решали задачу таким методом, то каждый покупатель образовывал бы собственный кластер, а вы раз за разом объединяли бы по два ближайших кластера, пока цель не оказалась достигнутой. Деление 1 Итак, мы начинаем наш процесс разделяющей кластеризации с разделения графа на две группы, чтобы максимизировать модулярность. Создайте новый лист под названием Split1 и вставьте покупателей в столбец А. Принадлежность каждого покупателя к группе будет обозначена в столбце В, который нужно назвать Community. Так как вы делите граф пополам, пусть этот параметр будет бинарной переменной решения в «Поиске решения», где значение 0/1 будет означать принадлежность к группе 0 или 1. Ни одна из групп не лучше другой. Нет ничего плохого в том, чтобы быть в 0 группе. Считаем принадлежность каждого покупателя к группе В столбце С вычислим модулярность для каждого покупателя при отнесении его к соответствующей группе. Я имею в виду, если вы поместите Адамса в группу 1, 219
220 Много цифр то его часть общей модулярности будет суммой всех значений ячеек его строки во вкладке Scores, покупатели в которых также отнесены к группе 1. Рассмотрим, как добавить эту модулярность в формулу. Если Адамс в группе 1, то вам нужно сложить все значения ячеек из строки 2 вкладки Scores, которые относятся к другим покупателям, также попавшим в группу 1. Так как мы присваиваем только 0/1, можно использовать SUMPRODUCT/СУММПРОИЗВ для умножения вектора группы на вектор модулярности и сложения результата. Хотя значения модулярностей расположены слева направо, в оптимизационной модели они идут сверху вниз, так что здесь придется использовать TRANSPOSE/ТРАНСП (что, в свою очередь, означает использование формулы массива): {=SUMPRODUCT(B$2:B$101,TRANSPOSE(Scores!B2:CW2))} {=СУММПРОИЗВ(B$2:B$101,ТРАНСП(Scores!B2:CW2))} Формула умножает значения модулярности на значения принадлежности к группе. Остаются только те, которые относятся к членам группы 1, в то время как остальные обращаются в 0. SUMPRODUCT/СУММПРОИЗВ складывает все. Но что, если Адамс был отнесен к группе 0? Нужно всего лишь транспонировать принадлежность к группам путем вычета их из 1, чтобы заставить работать суммы модулярностей. {=SUMPRODUCT(1-(B$2:B$101),TRANSPOSE(Scores!B2:CW2))} {=СУММПРОИЗВ(1-(B$2:B$101),ТРАНСП(Scores!B2:CW2))} В идеальном мире вы бы могли соединить эти две формулы с помощью функции IF/ЕСЛИ, которая бы проверила принадлежность Адамса к той или иной группе, а затем использовала бы соответствующую формулу для сложения модулярностей тех или иных соседей. Но при использовании IF/ЕСЛИ пришлось бы задействовать нелинейную модель в «Поиске решения» (подробнее в главе 4). В данном случае максимизация модулярности слишком тяжела для нелинейного «Поиска решения», и он становится неэффективен. Следует сделать задачу линейной. Приводим расчет модулярности в линейную форму Если вы внимательно читали главу 4, то, конечно, помните метод моделирования формулы IF/ЕСЛИ с использованием линейных ограничений, таких как «большое М». Здесь мы тоже им воспользуемся. Обе предыдущие формулы линейны, так почему бы просто не установить переменную модулярности для Адамса — такую, чтобы она была меньше их обеих? Мы пытаемся максимизировать общую модулярность, поэтому модулярность
5. Кластерный анализ, часть II Адамса будет стремиться вверх, пока не наткнется на меньшую из ограничивающих формул. Но как понять, который из расчетов модулярности, относящихся к принадлежности Адамса к группе, наименьший? Никак. Чтобы разобраться с этим, вам нужно понять, которая из этих двух формул не используется. Если Адамс отнесен к 1, то первая формула становится верхней границей, а вторая формула отключается. Если у Адамса 0, то наоборот. Как выключается одна из двух верхних границ? Добавьте в него «большое М» — настолько большое, чтобы в сравнении с ним верхней границей можно было бы пренебречь, потому что настоящая граница располагается ниже. Посмотрите на эту модификацию первой формулы: {=SUMPRODUCT(B$2:B$101,TRANSPOSE(Scores!B2:CW2))+ +(1-B2)*SUM(ABS(Scores!B2:CW2))} {=СУММПРОИЗВ(B$2:B$101,ТРАНСП(Scores!B2:CW2))+ +(1-B2)*СУММ(ABS(Scores!B2:CW2))} Если Адамс отнесен в группу 1, то последняя часть формулы обращается в 0 (из-за умножения на 1–В2). В этом случае формула становится идентичной первой формуле, которую мы рассматривали. Но если Адамса отнесли в группу 0, то эта формула больше не подходит и ее нужно отключить. Поэтому часть формулы (1-B2)*SUM(ABS(Scores!B2:CW2)//(1-B2)*СУММ(ABS(Scores!B2:CW2) добавляет 1, умноженную на сумму всех абсолютных значений модулярности, которые Адамс может получить. Это действие гарантирует, что результат окажется выше, чем у ее перевернутой версии, которая работает теперь: {=SUMPRODUCT(1-(B$2:B$101),TRANSPOSE(Scores!B2:CW2))+ +B2*SUM(ABS(Scores!B2:CW2))} {=СУММПРОИЗВ(1-(B$2:B$101),ТРАНСП(Scores!B2:CW2))+ B2*СУММ(ABS(Scores!B2:CW2))} Все, что вы делаете — это заставляете модулярность Адамса быть меньше или равной правильному расчету и удаляете другую формулу из рассуждения, завышая ее значение. Это взломанная парнями из подворотни функция IF/ЕСЛИ. Таким образом, столбец С вы можете сделать столбцом модулярности, которая будет переменной решения, а в столбцы D и Е вашей электронной таблицы вставить эти две формулы в качестве верхних границ модулярности (рис. 5-27). Обратите внимание, что в значениях принадлежности к группам в формуле используются абсолютные ссылки, так что без проблем растягивайте формулу вниз — ничего не изменится. 221
222 Много цифр Рис. 5-27. Добавление двух верхних границ к переменной модулярности каждого покупателя Складывая значения модулярности в столбце G2 для каждого отнесенного к группе в столбце С, можно получить их общее значение и нормализовать его по общему числу «пеньков» в r-NeighborhoodAdj'!CX102, чтобы закончить вычисление: =SUM(C2:C101)/'r-NeighborhoodAdj'!CX102 =СУММ(C2:C101)/'r-NeighborhoodAdj'!CX102 В результате у нас получается лист, изображенный на рис. 5-28. Рис. 5-28. Заполненная вкладка Split1, готовая к оптимизации Запускаем линейную программу Теперь для оптимизации все готово. Откройте «Поиск решения» и отметьте, что вы максимизируете значение модулярности графа в ячейке G2. Переменные
5. Кластерный анализ, часть II решения — это значения принадлежности к группе в В2:В101 и значения модулярности в С2:С101. К значениям принадлежности к группе в В2:В101 нужно добавить условие бинарности. Также необходимо сделать переменные модулярности покупателей в столбце С меньше, чем обе верхние границы в столбцах D и Е. Как показано на рис. 5-29, затем следует сделать все переменные неотрицательными, отметив галочкой эту опцию и выбрав «Поиск решения линейных задач симплекс-методом». Рис. 5-29. Настройка симплексного алгоритма для первого деления Одна из проблем использования ограничения «большого М» заключается в том, что у «Поиска решения» частенько возникают сомнения в том, что он на самом деле нашел оптимальное решение. Он будет продолжать крутить свои шестеренки, даже имея отличное решение в кармане. Чтобы этого не происходило, нажмите кнопку «Параметры» в «Поиске решения» и установите значение Max Subproblems на 15 000. Это гарантирует нам, что «Поиск решения» остановится минут через 20 после нажатия кнопки «Выполнить». Жмите эту кнопку, независимо от того, чем вы пользуетесь — встроенным «Поиском решения» или OpenSolver (здесь кнопка находится на всплывающей 223
224 Много цифр боковой панели), — когда алгоритм завершит работу согласно ограничению, созданному пользователем. Он может сообщить вам, что нашел возможное решение, но оно не оптимальное. Это значит, что алгоритм просто не доказал оптимальность (точно так же на это не способны нелинейные алгоритмы), но не огорчайтесь: даже в этом случае можно быть уверенным, что решение не худшее. Когда вы найдете решение, вкладка Split1 будет выглядеть, как показано на рис. 5-30. ПРИ РАБОТЕ С EXCEL 2010 И 2013 СЛЕДУЕТ ИСПОЛЬЗОВАТЬ OPENSOLVER Если вы пользуетесь Excel 2010 или 2013 под Windows, то эта задача слишком трудна для встроенного «Поиска решения», поэтому вам придется задействовать OpenSolver, как в главах 1 и 4. Если вы применяете OpenSolver, введите условия задачи в обычный «Поиск решения», но перед выполнением запустите плагин OpenSolver, чтобы «разогнать» вашу систему. У OpenSolver те же проблемы сограничением «большого М», так что перед запуском модели зайдите в параметры OpenSolver и установите ограничение времени на 300 секунд. Если вы этого не сделаете, OpenSolver будет пользоваться ограничением времени по умолчанию (а оно огромно) и вращать свои шестеренки, пока вам не захочется убить Excel. Если у вас MacOS и Excel 2007 или 2011, то вы вполне справитесь и обычным «Поиском решения», хотя, если можете, лучше воспользуйтесь OpenSolver в Excel 2007. Если у вас LibreOffice, то все будет в порядке. Рис. 5-30. Оптимальное решение для первого деления
5. Кластерный анализ, часть II Мой поиск решения завершился на значении модулярности 0,464. Ваше решение может быть лучше, особенно если вы используете OpenSolver. Просматривая столбец В, вы видите, кто оказался в группе 0, а кто — в группе 1. Теперь встает вопрос: окончательное ли это решение? Действительно ли группы всего две или все же больше? Чтобы ответить на этот вопрос, вам стоит попытаться разделить эти группы пополам. Если решение окончательное, то «Поиск решения» не найдет больше групп. Но если разделение этих групп на три или четыре улучшит модулярность, то пусть «Поиск решения» так и сделает. Деление 2: электролатино! Разделим эти группы так, как делят ячейку. Начнем с копирования листа Split1 в новый лист и переименования его в Split2. Первое, что здесь нужно сделать — это вставить новый столбец после столбца со значениями принадлежности к группам (В). Назовите этот новый столбец С Last Run и скопируйте туда значения из В. Таким образом получается лист, изображенный на рис. 5-31. В этой модели подход тот же самый: каждому покупателю присваивается 1 или 0. Но стоит помнить, что если два покупателя получают в этот раз 1, это вовсе не значит, что они находятся в одной группе. Если в предыдущем делении они могли находиться в разных группах, то этот принцип сохраняется. Другими словами, единственное значение модулярности, которое может получить Адамс, будучи, скажем, в группе 1–0, зависит от покупателей, отнесенных в группу 0 в первом делении и в группу 1 во втором. Таким образом, нам необходимо поменять верхние границы расчета модулярности. Расчет в столбце Е (здесь показан в Е2) теперь требует сверки с результатами предыдущего деления в столбце С: {=SUMPRODUCT(B$2:B$101,IF(C$2:C$101=C2,1,0), TRANSPOSE(Scores!B2:CW2))} {=СУММПРОИЗВ(B$2:B$101,ЕСЛИ(C$2:C$101=C2,1,0), ТРАНСП(Scores!B2:CW2))} Логическое высказывание с оператором IF/ЕСЛИ IF(C$2:C$101=C2,1,0)/ ЕСЛИ(C$2:C$101=C2,1,0) предотвращает начисление «очков» Адамсу, пока его соседи не окажутся с ним в первом делении. Можно использовать этот оператор и здесь, потому что значения в столбце С больше не являются переменными решения. То деление было исправлено 225
226 Много цифр Рис. 5-31. Лист Split2 со значениями предыдущего деления перед запуском, так что в этом нет ничего нелинейного. Добавьте оператор IF/ЕСЛИ в часть формулы с «большим М», чтобы сделать окончательный расчет в столбце Е: SUMPRODUCT(B$2:B$101,IF(C$2:C$101=C2,1,0),TRANSPOSE (Scores!B2:CW2))+(1-B2)*SUMPRODUCT(IF(C$2:C$101=C2,1,0), TRANSPOSE(ABS(Scores!B2:CW2))) СУММПРОИЗВ(B$2:B$101,ЕСЛИ(C$2:C$101=C2,1,0),ТРАНСП (Scores!B2:CW2))+(1-B2)ЧСУММПРОИЗВ(IF(C$2:C$101=C2,1,0), ТРАНСП(ABS(Scores!B2:CW2))) Точно так же можно добавить этот оператор во вторую верхнюю границу в столбце F: =SUMPRODUCT(1-(B$2:B$101),IF(C$2:C$101=C2,1,0),TRANSPOSE (Scores!B2:CW2))+B2*SUMPRODUCT(IF(C$2:C$101=C2,1,0), TRANSPOSE(ABS(Scores!B2:CW2))) =СУММРПРОИЗВ(1-(B$2:B$101),ЕСЛИ(C$2:C$101=C2,1,0),ТРАНСП (Scores!B2:CW2))+B2*СУММПРОИЗВ(ЕСЛИ(C$2:C$101=C2,1,0), ТРАНСП(ABS(Scores!B2:CW2))) Совершенные нами действия можно назвать консервацией задачи: те, кто попал в группу 0 при первом делении теперь находятся в своем собственном мирке модулярностей, равно как и те, кого отнесли к группе 1 в первый раз. А вот и хорошая новость: в «Поиске решения» не нужно менять совсем ничего! Те же настройки, те же формулы. Если вы использовали OpenSolver, то он мог не сохранить настройки ограничения по времени из предыдущего расчета. Настройте его снова на 300 секунд. Нажмите «Выполнить».
5. Кластерный анализ, часть II В этот раз в Split2 у меня получилась модулярность, равная 0,546 (рис. 5-32), что является существенным улучшением по сравнению с 0,464. Это значит, что второе деление было хорошей идеей. (Ваше решение может отличаться и быть даже лучше моего.) Рис. 5-32. Оптимальное решение для второго деления И… деление 3: возмездие Хорошо, но стоит ли нам останавливаться на этом или стоит продолжить? Единственный способ узнать ответ — поделить еще раз. Если результат не будет лучше, чем 0,564 — значит, это конец. Начнем с создания листа Split3, переименования Last Run в Last Run 2 и вставки нового Last Run в столбец С. Затем скопируем значения из В в С. Добавим еще пару операторов IF//ЕСЛИ в верхние границы, чтобы проверять принадлежность к группе в предыдущем делении. Например, F2 превращается в следующее: =SUMPRODUCT(B$2:B$101,IF(D$2:D$101=D2,1,0),IF(C$2:C$101=C2,1 ,0),TRANSPOSE(Scores!B2:CW2))+(1-B2)*SUMPRODUCT (IF(C$2:C$101=C2,1,0),IF(D$2:D$101=D2,1,0), TRANSPOSE(ABS(Scores!B2:CW2))) =СУММПРОИЗВ(B$2:B$101, ЕСЛИ(D$2:D$101=D2,1,0),ЕСЛИ(C$2:C$101=C2,1,0), ТРАНСП(Scores!B2:CW2))+(1-B2)*СУММПРОИЗВ (ЕСЛИ(C$2:C$101=C2,1,0),ЕСЛИ(D$2:D$101=D2,1,0), ТРАНСП(ABS(Scores!B2:CW2))) 227
228 Много цифр И снова настройки «Поиска решений» остаются неизменными. Установите максимальное время решения, если это необходимо, нажмите «Выполнить» и дайте модели сделать свое дело. В случае моей модели никакого улучшения модулярности не произошло (рис. 5-33). Очередное деление не добавило нам ничего. Это означает, что модулярность была эффективно максимизирована в предыдущем делении — Split2. Давайте рассмотрим принадлежности к группам из этой таблицы поподробнее. Кодируем и анализируем группы Первое, что нужно сделать для изучения принадлежностей к группам, — это взять наше бинарное дерево, созданное в процессе успешных делений, и сделать эти столбцы единичными ярлыками кластеров (групп). Создайте вкладку под названием Communuties и вставьте туда имена покупателей, их группы и значения Last Run из вкладки Split2. Можете переименовать бинарные столбцы Split1 и Split2. Сделайте их бинарные значения числовыми, воспользовавшись чудо-формулой BIN2DEC//ДВ.В.ДЕС. В столбец D, начиная с D2, можно добавить: =BIN2DEC(CONCATENATE(B2,C2)) =ДВ.В.ДЕС(СЦЕПИТЬ(B2,C2)) Копируя эту формулу вниз, можно получить принадлежности к группам, показанные на рис. 5-34 (ваши значения могут отличаться). У нас получилось четыре кластера с ярлыками от 0 до 3 в десятеричной системе исчисления. Что же это за кластеры? Это можно выяснить тем же способом, что и в главе 2, — откопать наиболее популярные заказы покупателей, из которых эти кластеры состоят. Для начала, в точности как в главе 2, создайте вкладку под названием TopDealsByCluster и вставьте информацию о сделках из столбцов от А до G вкладки Matrix. За ними, со столбца Н до К, поместите ярлыки кластеров — 0, 1, 2 и 3. Так у вас получается лист, изображенный на рис. 5-35. Для ярлыка 0 в столбце Н найдите всех покупателей из вкладки Communities, которые были отнесены к группе 0, и сложите количество покупателей для каждой сделки. Точно так же, как и в главе 2 и предыдущих вкладках про деление, используется SUMPRODUCT/СУММПРОИЗВ и оператор IF/ЕСЛИ, и в итоге получается следующее: {=SUMPRODUCT(IF(Communities!$D$2:$D$101= TopDealsByCluster!H$1,1,0),TRANSPOSE(Matrix!$H2:$DC2))}
5. Кластерный анализ, часть II Рис. 5-33. Никаких улучшений модулярности в третьем делении Рис. 5-34. Итоговые ярлыки групп для модулярной максимизации Рис. 5-35. Новая вкладка TopDealsByCluster 229
230 Много цифр {=СУММПРОИЗВ(ЕСЛИ(Communities!$D$2:$D$101= TopDealsByCluster!H$1,1,0),ТРАНСП(Matrix!$H2:$DC2))} В этой формуле проверяется количество покупателей, получивших 0 в столбце ярлыков Н1, а затем складываются значения по первой сделке — была ли она ими заключена, или нет — из промежутка Н2:С2 вкладки Matrix. Обратите внимание: для вертикального расположения используется функция TRANSPOSE/ ТРАНСП. Это значит, что вычисления нужно будет производить, пользуясь формулами массива. Также отметьте использование абсолютных ссылок в значениях принадлежности покупателей к группам, строки матрицы для заголовков и столбцы для информации о заказах. Это позволяет вам растянуть формулу вправо и вниз, чтобы получилась полная картина самых популярных сделок для каждого кластера (рис. 5-36). Рис. 5-36. TopDealsByCluster с готовым количеством сделок Как и в главе 2, к таблице следует применить фильтр и отсортировать результаты сделок в группе 0 в столбце Н от большего к меньшему. Результат изображен на рис. 5-37 — небольшая группа покупателей (ваши кластеры могут отличаться по порядку и составу, в зависимости от того, на каком решении «Поиск решения» заканчивал каждый шаг).
5. Кластерный анализ, часть II Рис. 5-37. Самые популярные сделки в группе 0 Сортируя группу 1, вы получаете нечто, очень похожее на объемный кластер французского Шампанского (рис. 5-38). Замечательно. Рис. 5-38. Шипящие бутылочки в группе 1 Что касается группы 2, то она выглядит похожей на группу 0, за исключением мартовской сделки по игристому вину — она основная (рис. 5-39). 231
232 Много цифр Рис. 5-39. Люди, которым понравилась мартовское предложение по игристому вину И группа 3 — любители пино нуар. Ребята, вы когда-нибудь слышали о каберне-совиньон? К сожалению, у меня отвратительный вкус во всем, что касается вина (см. рис. 5-40). Вот и все! У вас четыре кластера, и, честное слово, три из них выглядят очень осмысленно, хотя я предполагаю возможное наличие группы людей, которые действительно просто захотели в марте игристое. И вы можете использовать это в своей работе — несколько нерасшифровываемых кластеров с выбросами. Рис. 5-40. Фанаты пино Обратите внимание, как похоже это решение на уже найденное нами в главе 2. Но тогда мы пользовались кардинально другой методологией, сохраняя вектор
5. Кластерный анализ, часть II сделок каждого покупателя и используя его для измерения расстояний от кластерного центра. Здесь же нет никакой концепции центра и даже совершенные покупателями сделки неочевидны. Важно расстояние до других покупателей. Туда и обратно: история Gephi Теперь, когда вы прошли через полный процесс кластеризации, я бы хотел вам показать, как выглядит то же самый процесс в Gephi. На рис. 5-20 мы рассматривали экспорт и визуализацию графа r-окрестности в Gephi, к которому я возвращаюсь в этом разделе. Этот этап пробудит в вас зависть, и он уже близок. В Excel вы находили оптимальную модулярность графа с помощью разделительной кластеризации. В Gephi есть кнопка Modularity. Вы найдете ее с правой стороны окна раздела Network Overview вкладки Statistics. При нажатии кнопки Modularity открывается окно настроек. Вам не нужно использовать веса ребер, так как вы импортировали матрицу смежности (окно настроек модулярности Gephi можно увидеть на рис. 5-41). Рис. 5-41. Настройки модулярности в Gephi Нажмите ОК. Запустится оптимизация модулярности с использованием алгоритма приближения. Этот алгоритм выполняется практически со скоростью света. Отображается отчет — модулярность равна 0,549, как и размер каждого из кластеров (рис. 5-42). Обратите внимание: если вы запускаете этот алгоритм в Gephi, решение может оказаться другим, так как расчет рандомизирован. Получив в Gephi кластеры, можно с ними позабавиться. 233
234 Много цифр Рис. 5-42. Результат модулярности в Gephi Перекрасьте граф в соответствии с модулярностью. Так же, как вы меняли размер графа «Друзей» с помощью степени вершины, зайдите в окно Ranking в верхнем левом углу экрана и откройте раздел Nodes (вершины). Выберите из выпадающего меню Modularity Class, подберите понравившуюся цветовую палитру и нажмите Apply, чтобы перекрасить граф (рис. 5-43). Отлично! Теперь вы видите, что эти два «гнезда» на графе — определенно группы. Рассеянная средняя часть графа разделена на три кластера. И бедного Паркера поместили в собственный кластер, не связанный ни с кем. Грустно и одиноко. Второе, что вы можете сделать с информацией о модулярности, — это экспортировать ее обратно в Excel для изучения, как вы поступали с вашими собственными кластерами. Для этого зайдите во вкладку Data Laboratory, где вы уже
5. Кластерный анализ, часть II Рис. 5-43. Граф покупателей, перекрашенный для выделения кластеров модулярности были раньше. Вы заметите, что классы модулярности уже заполнены в столбце таблицы Nodes. Нажав кнопку Export Table, выберите ярлык и столбцы класса модулярности, чтобы перевести их в файл CSV (рис. 5-44). Нажмите «Выполнить» в окне экспорта, чтобы перенести ваши классы модулярностей в формат CSV, а затем откройте этот файл в Excel. Здесь, в основной рабочей тетради, создайте новую вкладку под названием CommunitiesGephi, куда затем вставьте те классы, которые нашел для вас Gephi (рис. 5-45). Также можно воспользоваться фильтром для сортировки покупателей по имени, как они и расположены в остальных таблицах рабочей тетради. Просто для смеха докажем, что эта кластеризация лучше первоначальной по значению столбца С. Вы больше не связаны необходимостью строить только линейные модели, так что можно подсчитать итоговую модулярность для каждого покупателя с помощью следующей формулы (показанной здесь на примере Адамса, нашего любимого покупателя, в ячейке С2): {=SUMPRODUCT(IF($B$2:$B$101=B2,1,0),TRANSPOSE(Scores!B2:CW2))} {=СУММПРОИЗВ(ЕСЛИ($B$2:$B$101=B2,1,0),ТРАНСП(Scores!B2:CW2))} 235
236 Много цифр Рис. 5-44. Экспорт классов модулярности обратно в Excel Рис. 5-45. Классы модулярности по версии Gephi снова в Excel
5. Кластерный анализ, часть II Эта формула проверяет наличие покупателей в том же кластере, используя оператор IF/ЕСЛИ, раздает им значения 0 или 1, а затем использует SUMPRODUCT/ СУММПРОИЗВ для сложения их модулярностей. Вы можете кликнуть на этой формуле дважды, чтобы распространить ее на весь столбец С. Складывая значения в ячейке Е2 и деля их поочередно на общее число «пеньков» из r-NeighborhoodAdj'!CX102, вы, несомненно, получите общую модулярность, равную 0,549 (рис. 5-46). Так что эвристика Gephi выигрывает у эвристики разделительной кластеризации 0,003. О, да! Довольно близко. (Если вы использовали OpenSolver, то могли победить и Gephi.) Рис. 5-46. Модулярность групп, найденных Gephi Давайте посмотрим, какие кластеры нам нашла Gephi. Сначала скопируйте вкладку TopDealsByCluster и переименуйте ее в TopDealsByClusterGephi. Теперь отсортируйте их обратно по столбцу А, пренебрегая предыдущей сортировкой. Теперь, по версии Gephi, у вас есть 6 кластеров, пронумерованных от 0 до 5 (ваш результат может отличаться, поскольку Gephi использует рандомизированный алгоритм), так что добавим 4 и 5 в нашу смесь в столбцы L и М, соответственно. Нужно только немного подправить формулу в ячейке Н2, чтобы она обращалась к столбцу В вкладки CommunitiesGephi вместо столбца D вкладки Communities. А теперь можно растянуть формулу на весь лист, получая таблицу, изображенную на рис. 5-47. 237
238 Много цифр Рис. 5-47. Самые популярные заказы по кластерам по версии Gephi Еще раз отсортировав результаты по столбцам, вы увидите все те же знакомые кластеры — мелкий опт, игристое вино, франкофилы, любители пино, крупный опт и последняя, но не самая худшая — Паркер, собственной персоной. Подытожим В главе 2 мы рассматривали кластеризацию по k-средним. Используя те же самые данные, в этой главе вы сражались с сетевыми графами и окунались в кластеризацию через максимизацию модулярности. Вы уже должны довольно неплохо себя чувствовать в добыче данных, и даже обрести некоторую уверенность. Конкретизируем освоенные вами навыки: визуальное представление сетевого графа, а также отображение его в виде • матриц смежности и инцидентности; загрузка сетевого графа в Gephi для пущей уверенности в графической • несостоятельности Excel; удаление ребер из сетевых графов с помощью графа r-окрестности. Также • вы познакомились с концепцией KNN-графа, к которой я вам рекомендую вернуться и поразмыслить над ней подольше; определение степени вершины и модулярности графа, а также способы • расчета «очков» модулярности для группировки двух вершин; максимизация модулярности графа с использованием линейной оптими• зационной модели и разделительной кластеризации; максимизация модулярности графа в Gephi и экспорт результатов. •
5. Кластерный анализ, часть II А теперь вам наверняка любопытно, чего ради я окунул вас в процесс максимизации модулярности графа, если Gephi способна сделать это за вас? Вспомните, цель этой книги — не слепое нажатие клавиш, без осознания того, что же вы делаете. Теперь вы научились конструировать и подготавливать данные для определения кластеров. И знаете, как работает определение групп на графе. Вы это сделали. Так что в следующий раз, столкнувшись с этим «зверем», вы будете знать, что происходит по ту сторону экрана. Этот уровень понимания процесса неоценим. Хотя Gephi и является одним из лучших мест для подобного анализа, вам может потребоваться место для написания программного кода по данным графа, такое как библиотека igraph, которая имеет привязки к R и Python и великолепно подходит для работы с сетевыми графами. Также стоят упоминания базы данных графов Neo4J и Titan. Эти базы специально разработаны для хранения данных графов и последующих этапов доработки, независимо от сложности графа — интересует ли вас что-то простое, вроде «отображения любимых фильмов друзей Джона» или что-нибудь посложнее, вроде «нахождения кратчайшего путина Facebook от Джона до Кевина Бейкона». Ну вот и все. Идите вперед, составляйте графы, находите группы! 239

6 Бабушка контролируемого искусственного интеллекта — регрессия Погоди, ты что — беременна? В одной из недавних статей Forbes рассказывается о том, что компания Target создала модель искусственного интеллекта (ИИ). Модель способна определить, является ли покупательница беременной, чтобы затем использовать эту информацию для целевого маркетинга товаров и предложений, связанных с ожиданием и рождением ребенка. Молодые родители с удовольствием спускают кучу денег на товары, сопутствующие прибавлению в их семье, и трудно найти лучший момент для превращения их в лояльных покупателей, чем время до рождения малыша. «Подсев» один раз, они годами будут покупать подгузники вашей марки! Эта история про Target — лишь одна из множества заполонивших прессу в последнее время. «IBM Watson» выиграл в «Своей игре». Netfix предложили приз в миллион долларов за улучшение их рекомендательной системы. В своей кампании по переизбранию Обамы использовался ИИ для помощи в управлении рекламой, передачами в Интернете и телеэфире, а также акциями сбора средств. А теперь еще и Kaggle.com, где постоянно устраиваются соревнования по предсказанию чего угодно: от состояния водителя за рулем до суммы, которую тратит покупатель в бакалейной лавке. Но это все примеры из разряда газетных заголовков. ИИ способен найти применение практически в любой современной отрасли. Компания, выпустившая вашу кредитку, использует его, чтобы определить несвойственные вам операции. Враг в вашей любимой «стрелялке» на Xbox работает на ИИ. Фильтрация спама, обнаружение налогового мошенничества, автокоррекция орфографии и рекомендации друзей в социальных сетях — все это тоже ИИ. Легко догадаться, что хорошая модель ИИ может помочь в принятии бизнес-решений, увеличить продажи и прибыль, снизить стоимость. Модель ИИ может помочь вашим менеджерам расставить приоритеты в направлениях
242 Много цифр и оказывать клиентскую поддержку по телефону. ИИ может определить, кто лжет в анкете на сайте знакомств или у кого будет инфаркт в следующем году. Продолжите список сами — при наличии хорошего архива данных обученная модель ИИ способна на очень и очень многое. Не обольщайтесь! Люди, не знающие принципа работы модели ИИ, часто испытывают смесь восторга и ужаса, когда слышат, что те умеют предсказывать будущее. Но, перефразируя известный фильм 1992 года «Тихушники», взволнованных можно успокоить: «Не обольщайтесь — он не настолько умен». Почему? Потому что модель ИИ не умнее суммы своих частей. Проще говоря, вы скармливаете контролируемому алгоритму ИИ данные за некий период времени, к примеру, по заказам в Target, и говорите ему: «Эй, вот это заказали точно беременные, а вон то — не очень». Алгоритм «пережевывает» данные и «выплевывает» модель. Потом вы можете загрузить в эту модель данные о заказах покупателей и спросить: «А вот эта покупательница беременна?», и модель ответит: «Нет, это 26-летний оболтус, живущий у матери в подвале». Это, конечно, очень помогает, но все же модель — не волшебница. Она просто технично превращает данные о произошедших событиях в формулу или набор правил, которые затем использует для предсказания событий в будущем. Как мы видели на примере «наивного Байеса» в главе 3, эффективной модель делает ее способность вспоминать эти данные и ассоциированные с ними правила принятия решения, а также вероятности и коэффициенты. Наш неискусственный интеллект занимается этим всю нашу жизнь. К примеру, имея личные данные о моей жизни, мой мозг знает: если я съем огромный бутерброд с потемневшими ростками люцерны, то через несколько часов мне с высокой вероятностью станет плохо. Я взял данные из прошлого (о том, что отравился) и обучил с их помощью свой мозг, так что теперь у меня есть правило, формула, модель — называйте как хотите: темные ростки = гастроэнтерологический кошмар. В этой главе мы будем применять две разные регрессионные модели, просто чтобы посмотреть, насколько прямолинейным может быть ИИ. Регрессия — бабушка контролируемого предсказательного моделирования. Первые исследования с ее помощью были проведены еще в XIX веке. Она — старушка, но в этом ее сила: у нее была масса времени, чтобы развить во всех областях своего применения математическую точность, которой недостает некоторым новым технологиям ИИ. В противоположность макгайверовскому ощущению
6. Бабушка контролируемого искусственного интеллекта — регрессия от «наивного Байеса» в главе 3, в этой главе вы почувствуете вес статистической точности регрессии, особенно во время исследования достоверности. Мы будем использовать модели для классификации точно так же, как использовали «наивный Байес» в главе 3. Как вы увидите, задачи, находящиеся прямо под рукой, совсем не похожи на задачу о классификации документа методом «набора слов», с которой мы сталкивались ранее. Определение беременных покупателей РитейлМарта с помощью линейной регрессии ЗАМЕТКА Таблица Excel, использованная в этой главе, RetailMart.xlsx, доступна для скачивания вместе с книгой на сайте издательства www.wiley.com/go/datasmart. Она содержит все вводные данные, которые вам потребуются для работы. Вы также можете просто следить за ходом повествования, поглядывая на картинки, в которых я все уже сделал за вас. Представьте, что вы — менеджер по рекламе в головном офисе РитейлМарта и отвечаете за детские товары. Ваша обязанность — способствовать продажам как можно большего количества подгузников, молочной смеси, ползунков, кроваток, колясок, сосок и т. д. молодым родителям. У вас есть небольшая проблема. Из данных фокус-групп вы знаете, что у супругов, ожидающих прибавления, и родителей новорожденных покупка детских товаров легко входит в привычку. Они практически сразу находят подгузники, которые им нравятся, и магазины, в которых они дешевле всего. Они находят соску, которая нравится их ребенку, и уже знают, где купить экономичную упаковку. Вы хотите, чтобы РитейлМарт стал первым магазином на их пути. И хотите максимизировать его шансы стать для этих людей магазином детских товаров № 1. Но для этого необходимо, чтобы родители увидели вашу рекламу до того, как купят свою первую упаковку подгузников где-то еще. Они должны узнать о вас еще до рождения ребенка. Едва он появится на свет, родители получают ваш купон на подгузники и присыпку и, возможно, даже успеют им воспользоваться. Из этого можно сделать простой вывод: вам нужна прогностическая модель, способная определить потенциально беременных покупательниц для дальнейшего целевого маркетинга. 243
244 Много цифр Набор отличительных признаков В вашем арсенале есть секретное оружие для построения такой модели — данные учетных записей покупателей. Конечно, это далеко не все покупатели вашего магазина — шансы достучаться до молодожена, живущего в лесу и расплачивающегося наличными, практически равны нулю. Но что касается обладателей кредитки вашего магазина или учетной записи в вашем интернет-магазине с привязанной к ней кредиткой, то их заказы можно смело относить не только к покупателям лично, но и к их семьям. Так или иначе, вы не можете просто взять и загрузить в модель ИИ всю историю покупок как есть, неструктурированную, и ждать, что что-то произойдет. Вам бы неплохо догадаться выудить оттуда релевантные признаки нужных покупателей. Следует задаться вопросом: «Какие покупки совершает семья, в которой ждут пополнения, а какие — семья, в которой не ждут?» Первое, что приходит в голову — это тест на беременность. Если покупательница заказывает тест, то ее вероятность оказаться беременной выше, чем у среднестатистического клиента онлайн-магазина. Такие признаки часто называются features — отличительные черты, или независимые переменные, ведь, то, что мы пытаемся определить — «Беременна (да/нет)?» является зависимой переменной, в том смысле, что ее значение будет зависеть от данных, содержащихся в независимых переменных, которые мы и загружаем в модель. Отвлекитесь на минутку и прикиньте, какие возможные отличительные признаки могли бы подойти к этой модели ИИ. Какие истории заказов стоит в нее загружать? Вот мой список примерных отличий, который можно составить по заказам покупателей, а потом проассоциировать их с информацией из учетных записей: пол владельца учетной записи — мужской/женский/не указано; фамилию • можно сравнить с данными переписи населения; адрес владельца учетной записи — частный дом, квартира или абонент• ский ящик; недавно заказывал тест на беременность; • недавно заказывал противозачаточные; • недавно заказывал средства женской гигиены; • недавно заказывал препараты с фолиевой кислотой; • недавно заказывал витамины для беременных; • недавно заказывал DVD йоги для беременных; • недавно заказывал подушку для тела; • недавно заказывал имбирный эль; •
6. Бабушка контролируемого искусственного интеллекта — регрессия недавно заказывал браслеты от укачивания; • регулярно заказывал сигареты до недавнего времени, затем перестал; • недавно заказывал сигареты; • недавно заказывал продукты для бросающих курить (жвачку, пластырь • и т. д.); регулярно заказывал вино до недавнего времени, затем перестал; • недавно заказывал вино; • недавно заказывал одежду для беременных или кормящих. • Ни один из этих признаков не идеален. Люди не заказывают в РитейлМарте каждую мелочь, Они могли купить тест на беременность в ближайшей аптеке, а не у вас, а препараты для беременных получить по назначению врача. Но даже если покупатель заказывает в РитейлМарте решительно все, в семьях, ожидающих детей, все равно может быть курящий или пьющий человек. Одежду для беременных зачастую носят совсем не беременные девушки, особенно если в моде завышенная талия — слава Богу, в романе Джейн Остин не было РитейлМарта. Имбирный эль помогает от тошноты, но также хорош и с бурбоном. Такова общая картина. Ни один из этих признаков не ограничивает нашу модель, но есть надежда на то, что их объединенные силы сработают в стиле Капитана Планета и тогда модель сможет классифицировать покупателей сравнительно точно. Сборка обучающих данных По данным проведенных компанией опросов, 6% семей покупателей РитейлМарта ждут прибавления в любой момент времени. Вам нужно выбрать несколько образцов из этой группы в базе данных РитейлМарта и собрать из их историй заказов признаки для модели, причем еще до того, как родятся дети. Таким же образом вы должны собрать эти признаки для примеров покупателей, не ожидающих прибавления. Набрав с помощью этих отличий по пачке семей ожидающих и не ожидающих детей, вы можете их использовать как примеры для обучения модели ИИ. Но как быть с семьями, уже имеющими детей? Всегда есть вариант опроса покупателей для построения обучающей последовательности. Но сейчас вы просто делаете прототип, так что можете позволить себе считать семьи с уже родившимися детьми подходящими для изучения их покупательских привычек. Покупателей, внезапно начавших покупать подгузники для новорожденных и продолжающих время от времени покупать подгузники все большего размера хотя бы год, резонно считать таковыми. 245
246 Много цифр Таким образом, просматривая историю заказов покупателей до первой покупки подгузников, можно выбрать отличительные признаки «беременных» семей, перечисленные выше. Представьте, что вы выбрали 500 таких семей и извлекаете информацию об их отличиях из базы данных РитейлМарта. Что же касается «не-беременных» покупателей, то из базы данных вы можете извлекать историю покупок любых случайно выбранных клиентов РитейлМарта, которые не удовлетворяют критерию «постоянного заказа подгузников». Конечно, одна или две «беременные» семьи могут просочиться в «не-беременную» категорию, но так как «беременные» семьи составляют очень малый процент от общего количества покупателей РитейлМарта (и это еще до исключения покупателей подгузников), эта случайная выборка должна быть достаточно чиста. Представьте, что выбрали еще 500 примеров таких «не-беременных» семей. Составленная из этих данных таблица в 1000 строк (500 беременных, 500»небеременных») в Excel будет выглядеть, как изображено на рис. 6-1. Рис. 6-1. «Сырые» данные для обучения РЕШЕНИЕ ПРОБЛЕМЫ КЛАССОВОГО ДИСБАЛАНСА Теперь вы знаете, что беременными в любой момент являются всего 6% нашей «дикой» популяции покупателей, хотя в обучающей последовательности это соотношение — 50/50. Это называется выборкой с запасом. Беременность была бы меньшинством, «редким классом» данных, а сбалансировав образец, мы бы получили классификатор, заваленный данными о «не-беременных» покупателях. В конце концов, если вы оставите разделение естественным — 6/94, то простое объявление всех и каждого «не-беременным» даст нам те же 94% с учетом точности. Это опасно: ведь беременные — это, хоть и малочисленный, но все же интересующий вас класс, маркетингом в котором вы и занимаетесь.
6. Бабушка контролируемого искусственного интеллекта — регрессия Такая балансировка обучающих данных внесет в них некоторый сдвиг — модель «решит», что беременность встречается гораздо чаще, чем на самом деле. Но это не проблема, потому что в данном случае нас не интересует настоящая вероятность забеременеть. Как явствует ниже, главное — найти точку пересечения «очков» по беременности, выданных моделью, между положительными и ложноположительными результатами. В первых двух столбцах обучающих данных стоят категорийные данные пола и типа адреса. Остальные признаки бинарны, и 1 означает ПРАВДА. Так, к примеру, взглянув на первую строку таблицы, вы увидите, что этот покупатель считается беременным (столбец S). Это как раз тот столбец, значения в котором и должна научиться предсказывать ваша модель. Заглянув в историю заказов этого покупателя, вы найдете в ней тест на беременность и пару банок витаминов для беременных. Также эти семьи не заказывали в последнее время вино и сигареты. Пролистав данные, вы увидите все типы покупателей: у кого-то множество индикаторов, а у кого-то всего пара. Как и ожидалось, семьи в ожидании детей все же покупают время от времени вино и сигареты, а бездетные — заказывают товары, ассоциирующиеся с беременностью. Создание фиктивных переменных Вы можете считать, что модель ИИ — просто формула и ничего больше, она берет цифры, немного «жует» их и «выплевывает» прогноз, который должен выглядеть примерно как 1 (беременна) и 0 (нет) в столбце S нашей таблицы. Но проблема с вводными данными состоит в том, что первые два столбца вообще не являются числами. Они представлены в виде букв, обозначающих категории, например мужчину и женщину. Такая проблема — работа с категорийными данными, то есть с данными, сгруппированными в конечное число понятий без присвоения им числовых эквивалентов, — частенько настигает тех, кто работает над извлечением данных. Если вы разошлете своим покупателям опросник, в котором они должны будут написать, в какой сфере они работают, свое семейное положение, страну проживания, породу своей собаки или название любимой серии «Девочек Гилмор», то вы завязнете в обработке категорийных данных. Это некая противоположность числовым данным, которые уже выражены цифрами и готовы к поглощению технологиями добычи данных. Так что же нужно сделать с категорийными данными, чтобы можно было с ними работать? Если коротко, то вы должны превратить их в числовые. 247
248 Много цифр Иногда категорийные данные сами расположены в некотором порядке, который можно использовать для присвоения каждой категории числового значения. К примеру, если бы в вашем наборе данных была переменная, обозначающая ответ на вопрос, водят ли опрашиваемые Scion, Toyota или Lexus, то вы могли бы просто обозначить их ответы 1, 2 и 3. Вот вам и цифры! Но гораздо чаще встречаются категории, не имеющие порядка, например, пол. К примеру, мужчина, женщина и «не указано» — это отдельные категории без намека на порядковую нумерацию. В таких случаях, чтобы перевести категорийные данные в числовые, обычно используется техника под названием «фиктивная переменная», или «дамми» (dummy coding). Фиктивная переменная работает следующим образом: берется один столбец с категорийными данными (рассмотрим столбец Implied Gender — «Пол») и разбивается на несколько бинарных столбцов. То есть вместо одного столбца Implied Gender у нас их три: один для мужчин, другой для женщин и третий — для не указавших свой пол. Если в исходном столбце значение ячейки было «М», то теперь вместо этого у нас есть 1 в столбце Male, 0 в столбце Female и 0 в столбце Unknown. На самом деле здесь избыточное количество столбцов, потому что если и в столбце Male, и в столбце Female у вас 0, то уже подразумевается, что пол не указан. Вам не нужен третий столбец. Таким образом, при использовании фиктивной переменной для кодирования категорийных данных вам всегда нужно на один столбец меньше, чем количество имеющихся у вас категорий — последняя категория может быть выражена через остальные. Говоря языком статистики, категорийная переменная пола имеет всего две степени свободы, так как степеней свободы всегда на одну меньше, чем возможных значений переменной. В нашем конкретном примере стоит начать с копирования листа Training Data в новый лист под названием Training Data w Dummy Vars. Вы должны разделить первые два признака на два столбца каждый, так что смело стирайте все из столбцов А и В и вставляйте еще два пустых столбца слева от А. Назовите эти четыре пустых столбца Male, Female, Home и Apt (не указанный пол и абонентский ящик выражаются через остальные признаки). Как показано на рис. 6-2, теперь у вас должно быть четыре пустых столбца для размещения фиктивных переменных ваших двух категорийных переменных. Рассмотрим первую строчку обучающих данных. Чтобы превратить «М» в столбце пола в значение фиктивной переменной, нужно поместить 1 в столбец Male и 0 в cтолбец Female. (Единица в столбце Male сама по себе означает, что пол не является «не указанным».) Проверьте старое значение категории во вкладке Training Data, и если это «М», то в ячейке А2 вкладки Training Data w Dummy Vars поставьте 1:
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-2. Вкладка Training Data w Dummy Vars с новыми столбцами для фиктивных переменных =IF(‘TrainingData’!A2=”M”,1,0) =ЕСЛИ(‘TrainingData’!A2=”M”,1,0) То же самое относится к значению «F» в столбце Female, H в столбце Home и А в столбце Apt. Чтобы раскопировать эти четыре формулы во все строки, вы можете либо перетащить их, либо (что предпочтительнее), как описывалось в главе 1, выделить их все и затем кликнуть дважды в правом нижнем углу ячейки D2. Это заполнит весь лист до D1001 конвертированными значениями переменных. Сконвертировав эти две категории в четыре бинарных фиктивных переменных (рис. 6-3), вы готовы к началу моделирования. Рис. 6-3. Заполненный лист Training Data w Dummy Vars 249
Много цифр Мы сделаем свою собственную линейную регрессию! Каждый раз, когда я так говорю, по крайней мере один работник статистики теряет крылья, но я все равно гну свое: если вы хоть раз проводили линию тренда через облако точек на диаграмме, то вы уже строили модель ИИ. Вы, наверное, думаете: «Не может быть! Я бы знал, если бы создал робота, способного вернуться назад во времени и убить Джона Коннера!» Простейшая линейная модель Позвольте мне все объяснить с помощью простых данных на рис. 6-4. Рис. 6-4. Владение кошками и мое чихание В изображенной таблице мы видим количество кошек в доме в первом столбце и вероятность того, что я буду в этом доме чихать, во втором. Никаких кошек? 3% времени я все равно буду чихать от осознания того, что где-то все же существуют некие гипотетические кошки. Пять кошек? В таком случае я практически гарантированно буду чихать. А теперь мы можем сделать из этих данных точечную диаграмму в Excel и взглянуть на нее или на рис. 6-5 (больше информации о вставке диаграмм и графиков вы найдете в главе 1). Вероятность того, что я буду чихать у вас в гостях 100% Вероятность чихания 250 80% 60% 40% 20% 0% 0 1 2 3 Количество кошек 4 5 Рис. 6-5. Точечная диаграмма зависимости чихания от количества кошек
6. Бабушка контролируемого искусственного интеллекта — регрессия Кликая правой клавишей на точки диаграммы (нужно кликать прямо на точки, а не на поле диаграммы) и выбирая в меню «Добавить линию тренда», вы можете выбрать и добавить на график линейную регрессионную модель. В разделе «Параметры» окна «Линии тренда» выберите «Показывать уравнение на диаграмме». Нажав «ОК», вы увидите и линию тренда, и формулу для нее (рис. 6-6). Вероятность того, что я буду чихать у вас в гостях 100% Вероятность чихания y = 0,1529x + 0,0362 80% 60% 40% 20% 0% 0 1 2 3 Количество кошек 4 5 Рис. 6-6. Линейная модель, изображенная на графе Линия тренда на графике ясно показывает зависимость между чиханием и количеством кошек, которая описывается формулой: Y = 0,1529x + 0,0362 Другими словами, если х равен нулю, то линейная модель думает, что у меня есть 3–4%-ный шанс чихнуть и за каждую кошку щедро дает 15% сверху. Начальная точка графика на оси вероятности расположена на уровне 3–4%, что называется начальным отрезком, или свободным членом функции, а 15% за кошку — коэффициент переменной кошек. Предположения такого рода не требуют ничего, кроме будущих данных, которые затем комбинируются с коэффициентом и начальным отрезком модели. На самом деле, при желании вы можете скопировать из графика формулу «= 0,1529x + 0,0362» и вставить ее в ячейку, чтобы делать прогнозы, подставляя вместо x подходящие числа. К примеру, в будущем я зайду в дом с тремя с половиной кошками внутри (бедняга Тимми потерял свои задние лапы в лодочной аварии), затем вычислю «линейную комбинацию» коэффициентов и своих данных, добавлю начальный отрезок и получу свой прогноз: 0,1529 * 3,5 cats + 0,0362 = 0,57 251
252 Много цифр 57%-ный шанс чихнуть! Это является моделью ИИ в том смысле, что мы взяли независимую переменную (кошек), зависимую переменную (чихание) и попросили компьютер описать их взаимоотношения формулой, которая больше всего похожа на данные о событиях в прошлом. Теперь вам, наверное, интересно, как компьютер догадался, какая у этих данных линия тренда. Она неплохо выглядит, но откуда он знает, как? Выражаясь более человеческим языком, компьютер искал такую линию тренда, которая бы лучше всего подходила к данным, то есть чтобы сумма квадратов отклонений от данных была минимальной. Чтобы понять, зачем нам сумма квадратов отклонений и что она означает, подставим в уравнение линии тренда одну кошку: 0,1529 * 1 cat + 0,0362 = 0,1891 Обучающие данные дают нам здесь вероятность 20%, а не 18,91. Таким образом, отклонение линии тренда в этой точке от данных равна 1,09%. Величина отклонения возводится в квадрат, чтобы ее значение было положительным, независимо от того, по какую сторону от линии тренда оказалась наша точка. 1,09% в квадрате дают 0,012%. А если мы теперь сложим все квадраты отклонений от всех известных нам точек обучающих данных, у нас получится сумма квадратов отклонений (которую часто называют просто суммой квадратов). И это именно то, что Excel минимизирует, когда подгоняет линию тренда под график чихания. Хотя в ваших данных из РитейлМарта слишком много измерений, чтобы делать из них точечную диаграмму, в следующих разделах мы будем подгонять к нашим данным точно такую же линию. Вернемся к данным РитейлМарта Ну что ж, пришло время построить линейную модель вроде кошкочихательной на основе данных РитейлМарта. Для начала создайте новый лист и назовите его Linear Model, а затем вставьте туда данные из Training Data w Dummy Vars, начиная со столбца В и строки 8 — нужно оставить место вверху таблицы для коэффициентов линейной модели и других оценочных данных, за которыми вы будете следить. Чтобы сохранить порядок, вставьте снова строку с названиями в строку 1. В столбце U добавьте заголовок Intercept, потому что ваша линейная модель, как и предыдущая, будет начинаться не в нуле. Более того, чтобы было проще вставить в модель свободный член, заполните столбец Intercept (U8:U1007) единицами. Это позволит вам обсчитать модель, применяя функцию SUMPRODUCT/ СУММПРОИЗВ к строке коэффициентов и строке данных, что непременно потребует участия свободных членов.
6. Бабушка контролируемого искусственного интеллекта — регрессия Все коэффициенты этой модели мы поместим в строку 2, так что озаглавьте ее Model Coefficients и запишите стартовые значения, равные единице, в каждую ее ячейку. Вы также можете воспользоваться условным форматированием строки коэффициентов, чтобы увидеть изменения, когда они появятся. Теперь ваши данные выглядят так, как показано на рис. 6-7. Рис. 6-7. Настройка таблицы для линейной модели После установки коэффициентов в строке 2 можно вычислить линейную комбинацию коэффициентов (формула SUMPRODUCT/СУММПРОИЗВ) со строкой данных покупателя и получить прогноз о беременности. Получилось слишком много столбцов, чтобы рисовать такой же график, как в случае с кошками, так что придется вам обучать модель самим. Первый шаг в этом нелегком деле — добавление в таблицу столбца с прогнозом, в котором уже содержится одно готовое значение для какой-нибудь строки. В столбец W, следующий за данными покупателей, добавьте название Linear Combination (Prediction) в строку 7, а ниже поместите линейную комбинацию коэффициентов и данных покупателей (свободный член включен). Формула, которую вы вставляете в строку 8, чтобы проделать это с первым покупателем, выглядит так: =SUMPRODUCT(B$2:U$2,B8:U8) =СУММПРОИЗВ(B$2:U$2,B8:U8) Поместите в строку 2 абсолютную ссылку, чтобы можно было перетащить формулу вниз, распространив на всех покупателей, без изменения коэффициентов в строках. 253
254 Много цифр ПОДСКАЗКА Кроме того, вы можете выделить столбец W, кликнуть на нем правой клавишей мышки, выбрать «Форматирование ячеек» и отформатировать значения в них как числа с двумя знаками после запятой, что впоследствии убережет вас от сердечного приступа при виде их огромного количества. После добавления столбца ваша таблица будет выглядеть, как показано на рис. 6-8. Рис. 6-8. Столбец с прогнозами для линейной модели В идеале столбец с прогнозами (W) должен был бы содержать данные, совпадающие с теми, о которых известно, что они верны (столбец V), но использование единицы как коэффициента для каждой переменной дает неожиданный результат. Первый же покупатель получает прогноз, равный 5, при том, что беременность определяется 1, а ее отсутствие — 0. Что значит 5? Очень-очень беременна? Добавляем учет отклонений Вам нужно заставить компьютер определить коэффициенты модели за вас, но чтобы научить его это делать, придется дать машине понять, когда прогноз правильный, а когда — нет.
6. Бабушка контролируемого искусственного интеллекта — регрессия Для этого добавьте расчет отклонений в столбец Х. Используйте квадрат отклонения, который есть не что иное, как квадрат расстояния от значения Pregnancy (беременность, столбец V) до прогнозируемого значения (столбец W). Возведение в квадрат позволяет каждому отклонению быть положительным, чтобы вы смогли затем сложить их все вместе и получить общее отклонение для модели. И здесь вам совершенно не нужны положительные и отрицательные значения отклонения, уничтожающие друг друга при сложении. Поэтому для первого покупателя в таблице у вас будет следующая формула: =(V8-W8)^2 Вы можете растянуть эту ячейку вниз на весь столбец, чтобы у каждого покупателя был свой расчет отклонений. А теперь добавьте ячейку над прогнозами в Х1 (обозначенную в W1 как Sum Squared Error — сумма квадратов отклонений), в которой будет подсчитываться сумма значений столбца квадратов отклонений с помощью следующей формулы: =SUM(X8:X1007) =СУММА(X8:X1007) Ваша таблица теперь выглядит, как показано на рис. 6-9. Рис. 6-9. Прогнозы и сумма квадратов отклонений 255
256 Много цифр Обучение «Поиском решения» Теперь вы готовы к обучению вашей линейной модели. Нужно установить такие коэффициенты, чтобы сумма квадратов отклонений была как можно меньше. Если вам слышится что-то похожее на формулировку для «Поиска решения», то вы правы — это она. Точно так же, как в главе 2, а также 4 и 5, вам нужно открыть «Поиск решения» и заставить компьютер найти для вас лучшие коэффициенты. Вашей целевой функцией будет сумма квадратов отклонений в ячейке Х1, которую вы хотите минимизировать «изменением значений переменных» в ячейках от В2 до U2, которые, в свою очередь, являются коэффициентами в вашей модели. Далее, квадрат отклонения — это квадратичная функция ваших переменных решения, коэффициентов, поэтому для решения вы не можете воспользоваться линейным симплекс-методом, как в главе 4. Симплекс-метод работает очень быстро и гарантированно находит наилучшее решение, но модель понимает только линейные комбинации решений. Для «Поиска решения» вам потребуется эволюционный алгоритм. СПРАВКА Более развернутую информацию о нелинейных моделях оптимизации и внутреннем устройстве эволюционного алгоритма вы можете найти в главе 4. Если хотите, можете также поиграть с нелинейным оптимизационным алгоритмом в Excel под названием GRG. По сути, «Поиск решения» будет выискивать такие значения коэффициентов, которые заставляют сумму квадратов уменьшаться, пока ему не покажется, что найдено действительно хорошее решение. Чтобы эффективно использовать эволюционный алгоритм, нужно установить нижнюю и верхнюю границы. Чем ближе они друг к другу (но не слишком близко!), тем лучше работает алгоритм. Для этой модели я установил их на –1 и 1. Когда вы с ними разберетесь, настройка вашего «Поиска решения» будет выглядеть примерно, как показано на рис. 6-10. Нажмите «Выполнить» и ждите! Пока «Поиск решения» пробует различные коэффициенты для модели, вы увидите, как меняются их значения. Условное форматирование ячеек даст вам почувствовать разброс. Более того, сумма квадратов отклонений будет становиться то больше, то меньше, но в конечном итоге уменьшится. По окончании работы «Поиск решения» сообщит вам, что задача оптимизирована. Нажмите «ОК» и возвращайтесь к модели.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-10. «Поиск решения», настроенный для линейной модели На рис. 6-11 вы видите, что «Поиск решения» закончил с результатом 135,52 — вот чему оказалась равна сумма квадратов отклонений. Если вы повторяете за мной и запускаете свой «Поиск решения», то имейте в виду: два разных запуска эволюционного алгоритма никогда не закончатся одним и тем же значением — ваша сумма квадратов в конце концов может оказаться больше или меньше моей, да и коэффициенты модели в итоге могут немного отличаться. Оптимизированная линейная модель показана на рис. 6-11. ИСПОЛЬЗОВАНИЕ ФОРМУЛЫ LINEST/ЛИНЕЙН ДЛЯ ЛИНЕЙНОЙ РЕГРЕССИИ Некоторые читатели наверняка в курсе, что у Excel есть своя формула линейной регрессии — LINEST/ЛИНЕЙН. Одним махом эта формула, безусловно, может сделать то, что вы только что делали вручную. Однако при 64 отличительных признаках моделирования она вылетает, так что действительно большие регрессии вам все равно придется делать самим. Задействуйте формулу LINEST/ЛИНЕЙН применительно к нашей модели. Но будьте внимательны! Прочитайте справочный раздел Excel об этой формуле. Чтобы достать оттуда все свои коэффициенты, вам необходимо воспользоваться формулой массива (подробнее в главе 1). Имейте в виду: она выдает коэффициенты в обратном порядке (Male будет последним коэффициентом перед свободным членом), что очень раздражает. 257
258 Много цифр А вот где она действительно незаменима, так это в автоматическом вычислении многих значений, необходимых для выполнения статистической проверки вашей линейной модели, таких как запутанные расчеты коэффициента стандартного отклонения, которые вы встретите в следующем разделе. Но в этой главе вам придется делать все вручную, так что ваши новые знания о замечательной функции LINEST/ЛИНЕЙН (и функциях линейного моделирования других программных пакетов) просто должны помочь вам расслабиться — в будущем вы сможете смело на них положиться. К тому же ручная работа облегчает переход к логистической регрессии, которая не поддерживается Excel. Рис. 6-11. Оптимизированная линейная модель ИСПОЛЬЗОВАНИЕ МЕДИАННОЙ РЕГРЕССИИ ДЛЯ РАБОТЫ С ВЫБРОСАМИ В медианной регрессии минимизируется сумма абсолютных значений отклонений, вместо суммы их квадратов. И это единственное отличие от линейной регрессии. Зачем она вам? В случае с линейной регрессией выбросы (значения, сильно отстоящие от остальных) вашего обучающего набора данных довольно ощутимо «оттягивают» на себя модель в процессе подгонки тренда. Если их отклонения достаточно велики, линейная регрессия
6. Бабушка контролируемого искусственного интеллекта — регрессия будет больше «прогибаться» в сторону баланса между их большим отклонением и отклонениями остальных точек графика, чем при балансе, заложенном в медианной регрессии. В последнем случае линия, подходящая к данным, будет оставаться ближе к типичным входящим в модель данным, чем тяготеть к выбросам. Я не планирую затрагивать в этой главе медианную регрессию. Вы можете попробовать воспользоваться ею сами — в этом нет ничего сложного. Просто замените квадрат отклонения абсолютным значением (в Excel есть функция ABS) — и все готово к старту! Это означает, что если вы работаете в Windows и у вас установлен OpenSolver (см. главу 1), то у вас появилась большая проблема! Так как в медианной регрессии мы минимизируем отклонения, а абсолютное значение может также быть и максимумом функции (максимальным ее значением и –1, умноженной на это значение), попробуйте линеаризировать медианную регрессию в стиле модели минимакса (более подробно оптимизационная модель минимакса описана в главе 4). Подсказка: вам нужно будет создать по одной переменной на строку данных, поэтому придется использовать OpenSolver — встроенный в Excel «Поиск решения» не справится с тысячью решений и двумя тысячами переменных. Удачи! Статистика линейной регрессии: R-квадрат, критерии Фишера и Стьюдента ЗАМЕТКА Следующий раздел — самый замысловатый во всей книге. Он, без сомнения, содержит самые сложные вычисления — расчет стандартного отклонения коэффициентов модели. Я постарался объяснить все как можно доходчивее, но некоторые вычисления требуют объяснений на уровне, соответствующем сложности текста. А я не хочу здесь отвлекаться на курс лекций по линейной алгебре. Постарайтесь вникнуть в эти понятия насколько возможно. Применяйте их на практике. А если хотите узнать больше — возьмите учебник по математической статистике начального уровня (к примеру, «Статистика простым языком» — Statistics in Plain English by Timothy C. Urdan [Routledge, 2010]). Если вы все же застрянете — знайте, что к этой главе в остальной книге ничего не привязано. Пропустите ее, а потом вернитесь, если понадобится. 259
260 Много цифр Итак, у нас есть линейная модель, которую мы подгоняем, минимизируя сумму квадратов. Если взглянуть на прогнозы в столбце Y, то, на первый взгляд, они кажутся вполне похожими на правду. К примеру, беременная покупательница в строке 27, заказавшая тест на беременность, витамины для беременных и одежду для будущих мам, получила 1,07 баллов, а покупатель из строки 996, который заказывал только вино, получил 0,15. Таким образом, остаются вопросы: насколько регрессия в действительности подходит данным в количествен• ном смысле, а не приблизительно? Все это — лишь случайное совпадение или статистически значимый ре• зультат? Какой вклад вносит каждый отличительный признак в конечный результат? • Чтобы ответить на эти вопросы о линейной регрессии, вам нужно рассчитать R-квадрат, критерий Фишера и критерий Стьюдента для каждого из коэффициентов модели. R-квадрат — оценка качества подгонки Если бы вы ничего не знали о покупателе из набора обучающих данных (не было бы столбцов от В до Т), но сделать прогноз о беременности все равно было бы необходимо, то наилучшим способом минимизации квадрата отклонения в таком случае было бы помещение в таблицу среднего значения отклонений в столбце V. Тогда при распределении обучающих данных 500/500 среднее получилось бы равным 0,5. А так как каждое отдельное значение — это либо 0, либо 1, то каждое отклонение будет 0,5, а его квадрат — 0,25. Для 1000 прогнозов эта стратегия прогнозирования среднего дает сумму квадратов, равную 250. Это значение называется общей суммой квадратов. Это сумма квадратов отклонений каждого значения в столбце V от среднего значения этого столбца. Но Excel предлагает отличную формулу для его расчета в одно действие — DEVSQ/КВАДРОТКЛ. В ячейке Х2 вы можете рассчитать общую сумму квадратов: =DEVSQ(V8:V1007) =КВАДРОТКЛ(V8:V1007) Но если сложение значений по каждому прогнозу даст нам сумму квадратов отклонений, равную 250, то сумма квадратов отклонений, вычисленная с помощью линейной модели, которую мы недавно подгоняли, гораздо меньше — всего 135,52. То есть происхождение 135,52 из общей суммы квадратов 250 остается невыясненным, даже после подгонки регрессии (в таком контексте сумма квадратов отклонений часто называется остаточной суммой квадратов).
6. Бабушка контролируемого искусственного интеллекта — регрессия Если взглянуть на это значение с противоположной стороны, сумма квадратов с выясненным происхождением (которая буквально и является числом, которое мы выяснили с помощью модели) будет равна разнице между 250 и 135,52. Напишите в Х3: =Х2–Х1 В результате получаем 114,48 — сумму квадратов с выясненным происхождением (если ваша сумма квадратов отклонений отличается от 135,52, то и это значение может немного отличаться). Насколько хорошее это совпадение? В целом ответ на этот вопрос можно получить, взглянув на отношение «понятной» суммы квадратов к общей сумме. Это значение называется R-квадрат. Мы можем вычислить его в Х4: =Х3/Х2 Как показано на рис. 6-12, в результате получается 0,46. Если модель подогнана идеально, то квадрат отклонения будет равен 0, «понятная» сумма квадратов — равняться общей, а R-квадрат будет в точности равен 1. Если модель совсем не подходит, R-квадрат будет ближе к 0. Так что в случае с нашей моделью при таких обучающих вводных данных она может сгодиться для «хорошей, но не идеальной» работы по воспроизведению независимых переменных обучающих данных (столбец Pregnancy). Не стоит забывать, что расчет R-квадрата работает только для нахождения линейных отношений между данными. Если у вас бешеные нелинейные отношения (возможно, в форме V или U) между зависимыми и независимыми переменными в модели, то R-квадрат не сможет их отобразить. Критерий Фишера: статистическая значимость подгонки Частенько при анализе подгонки регрессии люди останавливаются на R-квадрате: «О, неплохо выглядит! Ну все, хватит!» Не делайте так. R-квадрат показывает нам лишь то, насколько хорошо подогнана модель. Но он не дает никакой информации о статистической значимости подгонки. Это просто, особенно в случаях с рассеянными данными (всего несколько точек) — получить модель, которая подогнана достаточно хорошо, но эта подгонка статистически не значима, то есть выраженное ею отношение между отличительными признаками и независимыми переменными может иметь очень отдаленное отношение к реальности. 261
262 Много цифр Рис. 6-12. R-квадрат линейной регрессии, равный 0,46 Может быть, то, что ваша модель подходит — просто случайность? Внезапная удача? Чтобы модель была статистически значимой, нужно отсеять все случайные совпадения. Представим же на мгновение, что вся наша модель — полнейшая случайность. Что вся подгонка — результат удачного выбора из 1000 случайно отобранных анкет РитейлМарта. Такое предположение в стиле адвоката дьявола называется нулевой гипотезой. Обычно нулевая гипотеза отвергается, если есть вероятность подогнать модель хотя бы на 5%. Эта вероятность часто называется величиной p. Для ее вычисления мы проводим проверку на критерий Фишера. Мы берем три параметра модели и создаем с их помощью распределение вероятности (для тех, кто забыл, что такое распределение вероятности — посмотрите обсуждение нормального распределения в главе 4). Вот эти три параметра: количество коэффициентов модели — в нашем случае 20 (19 отличитель• ных черт плюс свободный член); степени свободы — это количество вариантов данных за вычетом коли• чества коэффициентов модели; F-статистика — отношение «понятной» части суммы квадратов к «непо• нятной» (Х3/Х1 в таблице), умноженное на отношение количества степеней свободы к количеству зависимых переменных.
6. Бабушка контролируемого искусственного интеллекта — регрессия Чем больше F-статистика, тем ниже вероятность нулевой гипотезы. Как, приняв во внимание описание F-статистики, данное выше, сделать его больше? Увеличьте одно из двух отношений. Вы либо можете «объяснить» больше данных (и таким образом получить лучшую подгонку) или же раздобыть больше данных с таким же количеством переменных (и таким образом убедиться, что ваша подгонка работает и на других данных). Возвращаясь к таблице: нам нужно подсчитать количество записей и коэффициентов модели. Назовите ячейку Y1 Observation Count и в Z1 подсчитайте все значения из столбца V: =COUNT(V8:V1007) =СЧЁТ(V8:V1007) Количество записей, как вы и ожидали, равно 1000. В Z2 подсчитайте количество коэффициентов, суммируя строку 2: =COUNT(B2:U2) =СЧЁТ(B2:U2) У вас должно получиться 20, с учетом свободного члена. Затем в ячейке Z3 вы можете вычислить количество степеней свободы путем вычитания количества коэффициентов модели из количества записей: =Z1-Z2 У вас получится 980 степеней свободы. Теперь перейдем к F-статистике в ячейке Z4. Как отмечено выше, это просто отношение «понятной» части суммы квадратов к «непонятной» (Х3/Х1), умноженное на отношение количества степеней свободы к количеству зависимых переменных (Z3/(Z2–1)): =(X3/X1)*(Z3/(Z2–1)) Теперь эти значения можно подставить в распределение Z5 с помощью функции Excel FDIST/FРАСП. Назовите ячейку F Test P Value. Помещаем в FDIST/FРАСП F-статистику, количество зависимых переменных модели и степени свободы: =FDIST(Z4,Z2–1,Z3) =FРАСП(Z4,Z2–1,Z3) Как показано на рис. 6-13, вероятность получения такой подгонки, если принять нулевую гипотезу, почти везде равна нулю. Таким образом, нулевая гипотеза может быть отброшена, а произведенная подгонка — признана статистически значимой. 263
264 Много цифр Рис. 6-13. Результат проверки критерия Фишера Проверка коэффициента Стьюдента (Т-тест) — какие переменные являются значимыми? ОСТОРОЖНО: ВПЕРЕДИ ВЫСШАЯ МАТЕМАТИКА! Не в пример двум предыдущим проверкам, которые было несложно выполнить, проверка коэффициента Стьюдента для нескольких линейных регрессий потребует от вас перемножения и преобразования матриц. Если вы забыли, как делали это в старших классах школы или на первых курсах института, пролистайте учебник по линейной алгебре или вычислительной математике. Или хотя бы просто Википедию. Воспользуйтесь рабочими таблицами, приложенными к этой книге, чтобы быть уверенным в точности ваших вычислений. В Excel умножение матриц выполняется с помощью функции MMULT/МУМНОЖ, а преобразование — с помощью MINVERSE/МОБР. Так как матрица есть не что иное, как просто прямоугольный массив данных, эти формулы являются формулами массива (подробнее использование формул массива в Excel описано в главе 1).
6. Бабушка контролируемого искусственного интеллекта — регрессия Если критерий Фишера проверял, насколько значима вся наша регрессия целиком, то есть и способ проверить значимость отдельных переменных. Контролируя значимость каждой отдельной отличительной черты, вы поймете, откуда берутся результаты в вашей модели и от чего они зависят. Статистически незначительные переменные могут быть удалены. Если же вы интуитивно чувствуете, что незначимая переменная должна иметь смысл, то вам стоит проверить чистоту своего набора обучающих данных. Эта проверка коэффициентов модели называется критерием Стьюдента, или t-тестом. Во время его выполнения, точно так же как и во время проверки критерия Фишера, вы предполагаете, что данный коэффициент модели абсолютно бесполезен и должен быть равен 0. Приняв это предположение, t-тест рассчитывает вероятность получения коэффициента настолько далекого от 0, насколько вы видите в конкретной записи. Первое, что вы должны проверить при проведении t-теста зависимой переменной, — это среднеквадратичное отклонение прогноза. Это стандартное распределение выборки отклонения прогноза (более подробно про стандартное распределение рассказывается в главе 4), то есть мера вариабельности отклонений прогноза модели. Вы можете рассчитать среднеквадратичное отклонение прогноза в ячейке Х5 как квадратный корень из суммы квадрата отклонений (Х1), разделенный на количество степеней свободы (Z3): =SQRT(X1/Z3) =КОРЕНЬ(X1/Z3) Таким образом, мы получаем таблицу, изображенную на рис. 6-14. С помощью этой величины вы сможете рассчитать стандартное отклонение коэффициента. Подумайте о стандартном отклонении коэффициента как о стандартном распределении этого коэффициента, если вы рисуете каждую отличительную черту как набор данных о тысяче покупателей РитейлМарта, а затем подгоняете ее под отдельную линейную регрессию. Коэффициенты не будут каждый раз одинаковыми, они будут немного отличаться. А стандартное отклонение коэффициента определяет вариабельность, которую вы предполагаете увидеть. Для расчетов создайте новый лист в рабочей книге и назовите его ModelCoefficientStandardError. Сложным процесс вычисления стандартного отклонения делает необходимость понимать, как обучающие данные для коэффициентов варьируются и сами по себе, и взаимодействуя с другими переменными. Первый шаг в устранении этой неприятности — превращение обучающей последовательности в одну гигантскую матрицу (часто называемую матрицей плана) путем умножения ее на саму себя. 265
266 Много цифр Рис. 6-14. Стандартное отклонение прогноза для линейной регрессии Это произведение матрицы плана и ее же самой (В8:U1007) образует матрицу суммы квадратов и векторных произведений (СКВП). Чтобы увидеть, на что она похожа, вставьте строку заголовков обучающих данных в лист ModelCoefficientStdError в В1:U1 и, транспонированную, в А2:А21, вместе с заголовком Intercept. Чтобы умножить матрицу плана на саму себя, нужно обработать ее функцией Excel MMULT/МУМНОЖ, сначала транспонированную, затем правой стороной вверх: {=MMULT(TRANSPOSE(‘Linear Model’!B8:U1007),’Linear Model’! B8:U1007)} {=МУМНОЖ(ТРАНСП(‘Linear Model’!B8:U1007),’Linear Model’! B8:U1007)} Так как эта формула выдает результат в виде матрицы, переменную за переменной, вам нужно выделить весь промежуток В2:U21 на листе ModelCoefficientStdError и использовать формулу как формулу массива (о формулах массива более подробно говорится в главе 1). У вас получается таблица, изображенная на рис. 6-15. Обратите внимание на значения в матрице СКВП. По диагонали вы считаете совпадения каждой переменной с самой собой — то же, что и простое сложение единиц из каждого столбца матрицы плана. Свободный член получается равным 1000 в ячейке, к примеру, U21, потому что в исходных обучающих данных этот столбец состоит из 1000 ячеек.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-15. Матрица СКВП В ячейках, не входящих в диагональ, вас интересует число совпадений разных признаков. И если «мужчина» и «женщина» точно ни у кого не попадутся одновременно, то тест на беременность и противозачаточные появляются вместе в шести покупательских строках наших данных. Матрица СКВП дает нам представление о величине каждой переменной и то, насколько они пересекаются и соотносятся между собой. Вычисление стандартного отклонения коэффициента требует преобразования матрицы СКВП. Для его выполнения вставьте заголовки еще раз под саму матрицу в В24:U24 и А25:А44. Преобразование матрицы в В2:U21 рассчитывается выделением В25:U44 и применением функции MINVERSE/МОБР как формулы массива: {=MINVERSE(B2:U21)} {=МОБР(B2:U21)} Таким образом мы получаем таблицу, как на рис. 6-16. Значения, требуемые для вычисления стандартного отклонения коэффициента, находятся в диагонали преобразованной матрицы СКВП. Каждое из них рассчитывается как стандартное отклонение прогноза для целой модели (как до этого мы получили 0,37 в ячейке Х5 листа Linear Model), которое зависит от квадратного корня из соответствующего значения из диагонали СКВП. 267
268 Много цифр Например, стандартное отклонение коэффициента для параметра Male (мужчина) будет равным квадратному корню из значения совпадения его с самим собой в преобразованной матрице СКВП (корню из 0,0122), умноженному на стандартное отклонение прогноза. Чтобы рассчитать его для всех переменных, пронумеруйте каждую из них, начиная с 1 в В46 и заканчивая 20 в U46. Соответствующее каждому отличию диагональное значение затем можно найти с помощью формулы INDEX/ИНДЕКС. К примеру, INDEX(ModelCoefficientStdError!B25:B44,ModelCoefficientStd Error!B46)/ИНДЕКС(ModelCoefficientStdError!B25:B44,ModelCoefficient StdError!B46) выдает значение пересечения строки Male со столбцом Male (подробнее о формуле INDEX/ИНДЕКС прочитайте в главе 1). Рис. 6-16. Преобразование матрицы СКВП Извлекая из этого значения квадратный корень, а затем умножая его на стандартное отклонение прогноза, можно рассчитать стандартное отклонение коэффициента Male в ячейке В47: =’LinearModel’!$X5×SQRT(INDEX(ModelCoefficientStdError! B25:B44,ModelCoefficientStdError!B46)) =’LinearModel’!$X5×КОРЕНЬ(ИНДЕКС(ModelCoefficientStdError! B25:B44,ModelCoefficientStdError!B46))
6. Бабушка контролируемого искусственного интеллекта — регрессия Для модели, подогнанной в этой книге, результат равен 0,04. Растяните эту формулу до столбца U, чтобы получить стандартные отклонения всех коэффициентов, как показано на рис. 6-17. На листе Linear Model поместите в ячейку А3 заголовок Coefficient Standard Error. Скопируйте стандартные отклонения коэффициентов и вставьте их значения в строку 3 этого листа. Фух! С этого момента станет легче. До самого конца книги больше ни одного вычисления с матрицами. Клянусь! Рис. 6-17. Стандартное отклонение для каждого коэффициента модели Теперь у вас есть все, что нужно для подсчета статистики каждого коэффициента (такого же, как и расчет F-статистики в предыдущем разделе). Мы будем производить проверку по двустороннему критерию, то есть рассчитывать вероятности получения коэффициента, по меньшей мере, такой же величины, положительной или отрицательной, если на самом деле между отличием и зависимой переменной нет никакой связи. T-статистика для этой проверки может быть рассчитана в строке 4 как абсолютное значение коэффициента, нормализированного по его стандартному отклонению. Для признака Male это будет выглядеть так: =ABS(B2/B3) Раскопируйте эту формулу по всем ячейкам столбца U, относящимся к переменным. Проверку критерия Стьюдента теперь можно дополнить оценкой распределения Стьюдента (еще одного статистического распределения, вроде нормального распределения из главы 4) относительно значения t-статистики 269
270 Много цифр (статистики Стьюдента) для ваших значений степеней свободы. Озаглавьте строку 5 t Test p Value, а в В5 поместите формулу TDIST/СТЬЮДРАСП для расчета вероятности того, что коэффициент будет по меньшей мере таким, как при нулевой гипотезе: =TDIST(B4,$Z3,2) =СТЬЮДРАСП(B4,$Z3,2) Двойка в этой формуле обозначает двусторонний критерий. Копируя эту формулу на все переменные и применяя условное форматирование для ячеек, содержащих значения не меньше 0,05 (пятипроцентная вероятность), вы увидите, какие отличительные черты статистически не значимы. Ваши результаты могут отличаться из-за разницы в подгонке модели, а в таблице, показанной на рис. 6-18, столбцы Female, Home и Apt представлены как статистически не значимые. Рис. 6-18. Столбцы Female, Home и Apt статистически незначимы по условиям теста Для обучения модели в дальнейшем эти столбцы нужно будет удалить. Теперь, когда вы научились оценивать модель по статистическим критериям, сменим подход и обратимся к измерению качества модели, делая прогнозы на основании набора данных. Делаем прогнозы на основании новых данных и измеряем результат Последний раздел был целиком посвящен статистике — своего рода лабораторная работа. Это, конечно, не самое веселое, что вы делали в своей жизни, но умение проверять значимость и качество подгонки — важные навыки. А теперь пришло время устроить полевые испытания нашей модели и повеселиться!
6. Бабушка контролируемого искусственного интеллекта — регрессия Как вы узнаете, что ваша линейная модель хорошо справляется с прогнозированием реальных вещей? В конце концов, ваш обучающий набор данных не содержит все возможные записи о покупателях, а ваши коэффициенты были специально подогнаны под модель (хотя если вы сделали все правильно, обучающие данные довольно верно описывают картину мира). Чтобы лучше понять, как модель будет себя вести в реальном мире, нужно пропустить через нее несколько покупателей, которые не участвовали в предыдущем ее обучении. Этот отдельный набор примеров, используемый для тестирования модели, часто называется контрольной, или тестовой, выборкой, либо тестовой последовательностью. Чтобы обзавестись такой выборкой, нужно просто вернуться к базе данных РитейлМарта и выбрать других случайных покупателей (стараясь не наткнуться на тех, кто уже был выбран для обучения). Теперь, как отмечалось ранее, 6% покупателей РитейлМарта беременны, поэтому если вы выбрали 1000 случайных покупателей из базы, то примерно 60 из них окажутся беременными. Если для обучения модели вы делали выборку с запасом, то для тестирования стоит оставить отношение семей, ждущих ребенка, к остальным на уровне тех же 6%, чтобы измерения точности модели соответствовали тому, как модель будет себя вести в реальных условиях. В электронной таблице, соответствующей этой главе (доступна к загрузке на сайте книги), вы найдете вкладку под названием Training Set, заполненную тысячей строк с данными, подобно обучающему набору. Первые 60 покупателей беременны, а 940 остальных — нет (рис. 6-19). Рис. 6-19. Тестовый набор данных Точно так же, как во вкладке Linear Model, пропустите этот набор через модель, подставляя новые данные в линейную комбинацию данных покупателей и коэффициентов, и затем прибавляя свободный член. 271
272 Много цифр Помещая этот прогноз в столбец V, в строке 2 вы получаете следующую формулу для первого покупателя (так как в тестовом наборе нет столбца со свободным членом, следует добавить его отдельно): =SUMPRODUCT(‘LinearModel’!B$2:T$2,’TestSet’!A2:S2)+ ’LinearModel’!U$2 =СУММПРОИЗВ(‘LinearModel’!B$2:T$2,’TestSet’!A2:S2)+ ’LinearModel’!U$2 Скопируйте этот расчет для всех покупателей. Таблица, которая получается в итоге, изображена на рис. 6-20. Рис. 6-20. Прогнозы тестового набора На рис. 6-20 вы видите, что модель идентифицировала много семей, ожидающих прибавления, с прогнозами ближе к 1, чем к 0. Самые высокие значения прогноза получены для семей, которые покупали товары, четко относящиеся к беременности — фолиевую кислоту или витамины для беременных. С другой стороны, среди этих 60 «беременных» семей есть такие, которые не покупали ничего указывавшего на беременность. Конечно, они не покупали алкоголь или табак, но, как показывают их более низкие прогнозы, отсутствие покупки немного значит.
6. Бабушка контролируемого искусственного интеллекта — регрессия И наоборот, посмотрев на прогнозы «не-беременных» семей, вы увидите несколько упущений. К примеру, если вы следите за мной по таблице, то в строке 154 «не-беременный» покупатель заказывает одежду для беременных и перестает заказывать сигареты, а модель дает ему прогноз в 0,76. Таким образом, становится ясно, что если вы действительно собираетесь использовать эти прогнозы в собственном маркетинге, то вам придется установить некий порог для того, чтобы счесть покупателя беременным и начать отправлять ему соответствующие предложения. Возможно, нужно посылать рекламные материалы всем, у кого прогноз 0,8 и больше. Но, может быть, для вящей уверенности стоит поднять порог до 0,95. Перед тем как установить этот порог классификации, посмотрите на баланс плюсов и минусов в оценке качества работы модели. Измерения, больше всего влияющие на этот показатель, основаны на количествах и отношениях четырех величин, получаемых из нашей тестовой выборки: действительно положительные — отнесение беременного покупателя • к беременным; действительно отрицательные — отнесение «не-беременного» покупа• теля к не беременным; ложноположительные (также называемые ошибками I рода) — отнесе• ние «не очень беременного» покупателя к беременным. По моему опыту, конкретно это ложноположительное предположение очень обижает при личном контакте; ложноположительные (также называемые ошибками II рода) — неспо• собность определить беременного покупателя как такового. Это не так обидно, как подсказывает мой опыт. Несмотря на большое количество различных измерений качества работы модели, они все похожи на мексиканскую кухню — фактически являясь комбинацией одних и тех же четырех ингредиентов, перечисленных выше. Установка граничных значений Создайте новый лист и назовите его Performance. Самое меньшее значение, которое можно использовать в качестве граничного между беременными и не беременными, — это значение наименьшего прогноза в тестовой выборке. Назовите ячейку А1 Min Prediction, а в А2 поместите расчет: =MIN(‘TestSet’!V2:V1001) =МИН(‘Test Set’!V2:V1001) 273
274 Много цифр Аналогично, максимальной величиной может стать максимальное значение прогноза по тестовой выборке. Назовите А4 Max Prediction, а в А5 поместите формулу расчета: =MAX(‘Test Set’!V2:V1001) =МАКС(‘Test Set’!V2:V1001) Значения, описанные выше, составляют –0,35 и 1,25, соответственно. Не забывайте, что ваша линейная регрессия способна делать предположения и ниже 0, и выше 1, потому что на самом деле это не вероятности попадания в определенный класс (ими мы займемся позже в другой модели). Добавьте в столбец В заголовок Probability Cutoff for Pregnant Classification, а под ним определите промежуток его значений, начинающийся с –0,35. На листе, показанном на рис. 6-21, граничные значения меняются в большую сторону с шагом 0,05 до самого максимума 1,25 (просто введите первые три значения вручную, затем выделите их и растяните вниз, чтобы заполнить столбец до конца). Рис. 6-21. Граничные значения для классификации беременных
6. Бабушка контролируемого искусственного интеллекта — регрессия Особо дотошные могут считать граничным значение каждого прогноза в тестовой последовательности. Точность (положительная прогностическая ценность) А теперь давайте заполним некоторые параметры качества модели для каждого из этих граничных значений с помощью прогнозов по тестовой последовательности, начиная с точности, также известной как положительная прогностическая ценность полученного результата. Точность — это мера того, сколько семей в ожидании детей мы определили верно из всех семей, которые модель назвала «беременными». Говоря деловым языком, точность — это процент той рыбы в ваших сетях, которая является тунцом, а не дельфинами. Назовите столбец С Precision. Допустим, граничное значение находится в В2 и равно –0,35. Какова точность нашей модели, если беременным мы считаем каждого с прогнозом –0,35 и выше? Для расчета вернитесь к листу Test Set и сосчитайте количество случаев, когда «беременная» семья получала прогноз больше или равный –0,35, а затем разделите это количество на общее число строк с прогнозом –0,35 и выше. Используйте формулу COUNTIFS/СЧЁТЕСЛИМН для проверки действительно беременных и предполагаемых, которая в ячейке С2 будет выглядеть так: =COUNTIFS(‘TestSet’!$V$2:$V$1001,”>=”&B2,‘TestSet’!$U$2: $U$1001,”=1”)/COUNTIF(‘TestSet’!$V$2:$V$1001,”>=”&B2) =СЧЁТЕСЛИМН(‘TestSet’!$V$2:$V$1001,”>=”&B2,‘TestSet’!$U$2: $U$1001,”=1”)/СЧЁТЕСЛИ(‘TestSet’!$V$2:$V$1001,”>=”&B2) Первый оператор COUNTIFS/СЧЁТЕСЛИМН в формуле сравнивает и действительную беременность, и прогноз модели, в то время как COUNTIF/СЧЁТЕСЛИ в знаменателе считает только тех, чей прогноз выше –0,35, независимо от беременности. Вы можете растянуть эту формулу на все пороговые значения. Как показано на рис. 6-22, точность модели возрастает с увеличением граничного значения, а при границе, равной 1, модель становится идеально точной. Идеально точная модель считает беременными только беременных покупателей. Избирательность (доля действительно отрицательных результатов) Еще одна мера качества модели, которая растет вместе с пороговым значением, — это избирательность. Избирательность, также называемая долей действительно отрицательных результатов, выражается количеством покупателей, 275
276 Много цифр Рис. 6-22. Расчет точности на тестовой выборке которые были верно отнесены к таковым (действительно отрицательный результат), разделенным на общее количество «не-беременных» семей. Озаглавив столбец D Specificity/True Negative Rate, в D2 вы можете вычислить это значение с помощью формулы COUNTIFS/СЧЁТЕСЛИМН в числителе, чтобы узнать количество действительно «не-беременных», и COUNTIF/СЧЁТЕСЛИ в знаменателе, чтобы подсчитать всех «не-беременных» покупателей: =COUNTIFS(‘TestSet’!$V$2:$V$1001,”<”&B2,‘TestSet’!$U$2: $U$1001,”=0”)/COUNTIF(‘TestSet’!$U$2:$U$1001,”=0”) =СЧЁТЕСЛИМН(‘TestSet’!$V$2:$V$1001,”<”&B2,‘TestSet’!$U$2: $U$1001,”=0”)/СЧЁТЕСЛИ(‘TestSet’!$U$2:$U$1001,”=0”) Копируя эти вычисления на все строки с граничными значениями, можно увидеть, что значение его возрастает (рис. 6-23). По достижении граничного значения 0,85 правильно определяется 100% «не-беременных» покупателей.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-23. Расчет избирательности по тестовой последовательности Доля ложноположительных результатов Доля ложноположительных результатов — это стандартный параметр, по которому определяется качество модели. А так как у вас уже есть доля действительно отрицательных результатов, то он может быть быстро вычислен как разница между единицей и этой величиной. Назовите столбец Е False Positive Rate/(1 – Specificity) и заполните ячейки этой разницей между единицей и значением соответствующей ячейки столбца D. В Е2 это будет выглядеть так: =1-D2 Копируя эту формулу на весь список, вы можете увидеть, что по мере возрастания граничного значения, уменьшается количество ложноположительных результатов. Другими словами, вы совершаете меньше ошибок I рода (называя беременными покупателей, которые таковыми не являются). 277
278 Много цифр Доля действительно положительных результатов / память / чувствительность Последний параметр качества модели, который вы можете рассчитать, называется долей действительно положительных значений. И памятью. И чувствительностью. Ох, зачем придумывать столько названий для одного и того же! Доля действительно положительных значений — это количество правильно определенных беременных женщин, разделенное на общее количестве таковых в тестовом наборе. Назовите столбец F True Positive Rate/Recall/Sensitivity. В ячейке F2 теперь можно вычислить долю действительно положительных значений при граничной величине, равной –0,35: =COUNTIFS(‘TestSet’!$V$2:$V$1001,”>=”&B2,‘TestSet’!$U$2: $U$1001,”=1”)/COUNTIF(‘TestSet’!$U$2:$U$1001,”=1”) =СЧЁТЕСЛИМН(‘TestSet’!$V$2:$V$1001,”>=”&B2,‘TestSet’!$U$2: $U$1001,”=1”)/СЧЁТЕСЛИ(‘TestSet’!$U$2:$U$1001,”=1”) Возвращаясь к столбцу с действительно отрицательными результатами, отмечу, что вычисления здесь практически идентичны, за исключением того, что «<» превращается в «≥», а нули становятся единицами. Копируя эту формулу на весь столбец, вы можете убедиться, что с ростом граничного значения некоторые беременные женщины перестают определяться как таковые (ошибка II рода), а доля действительно положительных значений падает. На рис. 6-24 показаны доли действительных и ложноположительных значений в столбцах E и F. Оценка соотношения измерений и кривая ошибок При выборе порогового значения для бинарного классификатора важно выбрать наилучший баланс параметров качества его работы. Чем выше порог, тем выше точность модели, но ниже выборка. Одна из наиболее популярных ПРИ ЧЕМ ТУТ «РАБОЧАЯ ХАРАКТЕРИСТИКА ПРИЕМНИКА»? Причина, по которой такой простой график называется так сложно, проста: он был разработан радиотехниками во время Второй мировой войны, а не маркетологами на прошлой неделе для определения беременных покупателей. Эти ребята использовали сигналы для обнаружения врага и вражеской техники на поле боя и хотели визуально отобразить соотношение между верно и неверно определяемыми целями.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-24. Доли действительно положительных и ложноположительных значений визуализаций, которые используются для просмотра этой оценки, — это кривая ошибок (кривая соотношений правильного и ложного обнаружения сигналов, или рабочей характеристики приемника — Receiver Operating Characteristic, ROC). Кривая ошибок — это просто график зависимости действительно положительных значений от ложноположительных (столбцы E и F на листе Performance). Для того чтобы вставить график, выделите данные в столбцах E и F и выберите в меню диаграмм Excel «линейную диаграмму» (технология вставки графиков и диаграмм более подробно описана в главе 1). После небольшого форматирования (установки значений по осям от 0 до 1 и выбора удобного шрифта) кривая ошибок выглядит так, как показано на рис. 6-25. Эта кривая позволяет вам быстро увидеть долю ложноположительных значений, соотнесенную с долей действительно положительных, и лучше их понять. К примеру, на рис. 6-25 можно увидеть, что модель способна идентифицировать 40% беременных покупателей при пороговом значении 0,85 без единого «ложного срабатывания». Неплохо! 279
Много цифр Кривая ошибок 100% 90% Действительно положительные значения 80% 70% 60% 50% 40% 30% 20% 10% % 0% 10 % 90 % 80 % 70 % 60 % 50 % 40 % 30 % 20 0% 0% 10 280 Ложноположительные значения Рис. 6-25. Кривая ошибок линейной регрессии А если вас устраивает редкая отсылка семьям, не ожидающим детей, купонов, связанных с беременностью, модель может достичь доли действительно положительных значений в 75% при всего лишь 9 «ложных срабатываниях». То, какое значение вы установите в качестве порогового для определения «баллов беременности» покупателей — это бизнес-решение, а не чистая аналитика. Конечно, вместе с небольшим понижением порога определения беременности понизится и точность, но это весьма малая жертва, если принять во внимание существенное повышение доли действительно положительных значений. А при прогнозировании не беременности, а дефолта облигаций займа, вам наверняка захочется, чтобы специфичность и точность были немного повыше, не правда ли? И если бы модель, подобная этой, использовалась для подтверждения степени реальности военной угрозы, вы бы наверняка надеялись, что оператор модели пользовался очень высокой степенью точности перед тем, как вызвать беспилотники для атаки. СРАВНЕНИЕ ОДНОЙ МОДЕЛИ С ДРУГОЙ Как мы убедимся немного ниже, кривая ошибок также подходит для выбора между двумя прогностическими моделями. В идеале эта кривая подскакивает до 1 по оси у с максимально возможной скоростью и остается там до конца графика. Так что модель, график которой более похож на описанный выше (также стоит отметить, что она должна иметь наибольшую площадь под кривой), часто считается лучшей.
6. Бабушка контролируемого искусственного интеллекта — регрессия Так что о чем бы мы ни говорили — об отправке купонов, одобрении кредита или объявлении готовности № 1, — решение о выборе баланса между параметрами качества является стратегическим. Отлично! Мы опробовали модель на тестовых данных, сделали несколько прогнозов, рассчитали ее качественные показатели на тестовом наборе данных для различных граничных значений и отобразили эти показатели на кривой ошибок. Но чтобы с чем-то сравнить качество модели, нужна еще одна. Предсказание беременных покупателей РитейлМарта с помощью логистической регрессии Если взглянуть на предсказанные нашей линейной регрессией значения, становится ясно: модель полезна для классификации, но сами прогностические значения, конечно, не являются вероятностями класса. Вы не можете быть беременны со 125%-ной или 35%-ной вероятностью. Так существует ли модель, чьи прогнозы, и правда, были бы вероятностями класса? Мы можем создать такую модель, и называется она логистической регрессией. Первое, что нам нужно — это функция связи Подумайте о прогнозах, которые выдает ваша модель. Существует ли такая формула, через которую можно пропустить эти цифры, чтобы они оставались между 0 и 1? Оказывается, такая функция называется функцией связи, и есть отличный ее вариант, который делает очень простую операцию: exp(x)/(1+exp(x)) В этой формуле х — линейная комбинация значений из столбца W вкладки Linear Model и функции экспоненты, выраженной сокращенно exp. Экспонента exp(x), иначе называемая числом е, — просто математическая константа, равная 2,71828 — это что-то вроде «числа пи», только поменьше, в нашей формуле возведенная в степень х. Посмотрите на график этой функции, изображенный на рис. 6-26. Эта функция связи похожа на растянутую S. В нее можно подставить любое значение, полученное умножением коэффициентов модели на значение из строки данных покупателя, и на выходе получить число от 0 до 1. Но почему эта странная функция так выглядит? 281
Много цифр Функция связи «беременная/небеременная» 1 0,9 На выходе число от 0 до 1 282 0,8 0,7 0,6 0,5 0,4 0,3 0,2 0,1 0 –5 –4 –3 –2 –1 0 1 2 3 4 5 Любое значение Рис. 6-26. Функция связи А вы попробуйте быстренько округлить е до 2,7 и представьте ситуацию, когда вводные данные действительно велики, скажем х = 10. Тогда функция связи будет выглядеть следующим образом: exp(x)/(1+exp(x))=2,7^10/(1+2,7^10)=20589/20590 Это же практически 1, и с увеличением х эта единица в знаменателе значит все меньше и меньше. А как насчет отрицательного х? Посмотрите на –10: exp(x)/(1+exp(x))=2,7^-10/(1+2,7^-10)=0,00005/1,00005 По большому счету, это 0. Так что в данном случае 1 в знаменателе играет очень даже существенную роль, а небольшие величины так или иначе близки к 0. Полезно ли это? На деле эта функция связи оказалась настолько полезной, что кто-то дал ей собственное название. Это «логистическая» функция. Присоединение логистической функции и реоптимизация Пришло время снова скопировать лист, в этот раз — Linear Model, и назвать копию Logistic Link Model. Удалите все статистические тестовые данные, так как они относились к линейной регрессии. Отдельно выделите и удалите строки с 3 по 5, а также все значения вверху строк от W до Z, кроме названия Sum Squared Error. Также очистите столбец с квадратом отклонения и назовите его
6. Бабушка контролируемого искусственного интеллекта — регрессия Prediction (after Link Function). На рис. 6-27 показано, как должен выглядеть этот лист в итоге. Рис. 6-27. Лист, готовый к построению логистической модели Столбец Х вы будете использовать для получения результата из вашей логистической функции путем пропускания через нее линейной комбинации коэффициентов и данных из столбца W. К примеру, первая строка смоделированных данных покупателей будет обработана формулой в ячейке Х5: =EXP(W5)/(1+EXP(W5)) Если скопировать эту формулу на весь столбец, можно увидеть, что все новые значения находятся между 0 и 1 (рис. 6-28). Так или иначе, большая часть прогнозов оказывается близка к среднему, между 0,4 и 0,7. А все из-за того, что мы не оптимизировали коэффициенты на листе Linear Model для нашей новой модели. Так что оптимизацию придется повторить. Поэтому мы снова заполняем столбец с квадратом отклонения и далее столбцы до Y, но теперь в расчет отклонения включаем прогнозы линейной функции из столбца Х: =(V5-X5)^2 283
284 Много цифр Их мы снова складываем, точно так же, как в ячейке Х1 линейной модели: =SUM(Y5:Y1004) ЗАМЕТКА Ваши значения в столбцах W и X могут немного отличаться от моих, так как это — коэффициенты модели, которые мы искали с помощью эволюционного алгоритма на предыдущем листе. Рис. 6-28. Логистическая функция в действии Затем минимизируем сумму квадратов этой новой модели, пользуясь «Поиском решения», настроенным точно так же, как в прошлый раз (рис. 6-29), с единственным отличием: если вы экспериментируете с различными границами, то лучший вариант из возможных — это немного их расширить для логистической модели. На рис. 6-29 границы установлены таким образом, чтобы коэффициенты находились между –5 и 5. Закончив с реоптимизацией для новой функции связи, вы можете заметить, что теперь все ваши прогнозы по обучающим данным находятся между 0 и 1, причем многие из них с уверенностью можно отнести к 1 или 0. Как вы видите на рис. 6-30, эстетически такие прогнозы выглядят лучше, чем результаты линейной регрессии.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-29. Настройка «Поиска решения» для логистической модели идентична предыдущей Рис. 6-30. Подогнанная логистическая модель 285
286 Много цифр Создание настоящей логистической регрессии Правда состоит в том, что для создания настоящей логистической регрессии, дающей точные, беспристрастные свойства классов, вы не можете минимизировать сумму квадрата отклонения по причинам, находящимся за пределами охвата этой книги. Вместо этого подгонка модели заключается в нахождении коэффициентов, максимизирующих совместную вероятность (подробнее о ней можно прочитать в главе 3) извлечения этой обучающей выборки из базы данных РитейлМарта при том, что модель точно описывает реальность. Так какова же вероятность строки обучающих данных при известном наборе параметров логистической модели? Для данной строки в обучающем наборе пусть р выражает классовую вероятность, которую ваша логистическая модель выдает в столбце Х. А у пусть выражает значение действительной беременности, располагающееся в столбце V. Вероятность такой обучающей строки при данных параметрах модели будет равна py(1-p)(1–y) Для беременного покупателя (1 в столбце V) с прогнозом, равным 1 (1 в столбце Х), вычисление такой вероятности также дает 1. Но если прогноз у беременного покупателя был равен 0, то результатом этого вычисления будет уже 0 (подставьте значения и проверьте). Таким образом, вероятность каждой строки максимальна, когда предположение и реальность сходятся. Принимая независимость каждой строки данных (более подробно понятие независимости описано в главе 3), как в случае любой хорошей случайной выборки из базы данных, можно вычислить логарифм совместной вероятности данных, логарифмируя каждую из этих вероятностей и затем складывая их. Логарифм уравнения, приведенного выше, вычисленный с помощью тех же правил, что вы видели в разделе главы 3 о плавающей запятой, будет равен: Y*ln(p)+(1-y)*ln(1-p) Вероятность логарифма близка к 0, если результат предыдущей формулы был близок к 1 (то есть когда модель хорошо подогнана). Вместо того, чтобы минимизировать сумму квадрата отклонения, вы можете вычислить значение логарифмической функции правдоподобия для каждого прогноза, и затем сложить их. Те коэффициенты модели, которые максимизируют совместную вероятность, будут наилучшими. Для начала сделайте копию листа Logistic Link Model и назовите ее Logistic Regression. В столбце Y замените название Squared Error (квадрат отклонения)
6. Бабушка контролируемого искусственного интеллекта — регрессия на Log Likelihood (логарифмическое правдоподобие). В ячейке Y5 первое значение этой величины будет вычисляться по формуле: =IFERROR(V5*LN(X5)+(1-V5)*LN(1-X5),0) =ЕСЛИОШИБКА(V5*LN(X5)+(1-V5)*LN(1-X5),0) Полное вычисление логарифмического правдоподобия заключается в единственной формуле — IFERROR/ЕСЛИОШИБКА, ведь когда коэффициенты модели генерируют прогноз, очень-очень близкий к действительному значению класса 0/1, вы можете получить неустойчивость численного решения. В таком случае вполне справедливо установить значение логарифмического правдоподобия на 0 — идеальное сходство. СТАТИСТИЧЕСКИЕ ТЕСТЫ ЛОГИСТИЧЕСКОЙ РЕГРЕССИИ Статистические критерии, аналогичные r-квадрату и критериям Фишера, и Стьюдента, существуют и для логистической регрессии. Такие вычисления как псевдо-r-квадрат, отклонение модели и тест Вальда дают логистической регрессии практически ту же точность, что и у линейной регрессии. Более подробно об этом можно прочитать в книге «AppliedLogisticRegression», David W. Hosmer, Jr., Stanley Lemeshow, and Rodney X. Sturdivant (John Wiley & Sons, 2013). Скопируйте эту формулу на весь столбец Y, а в Х1 подсчитайте сумму значений логарифмического правдоподобия. Оптимизируя, вы получаете набор коэффициентов, очень похожий на найденный с помощью суммы квадратов отклонений, с небольшими расхождениями тут и там (рис. 6-31). При проверке сумма квадратов отклонений для полученной логистической регрессии должна оказаться практически оптимальной для такого параметра. Выбор модели: сравнение работы линейной и логистической регрессий Теперь, когда у вас есть вторая модель, можно приступить к сравнению ее работы с работой линейной регрессии с помощью тестовых данных. Логистическая регрессия делает свои предположения как и написано в столбцах W и Х листа Logistic Regression. В ячейке W2 листа Test Set вычислите значение линейной комбинации коэффициентов модели и тестовых данных следующим образом: =SUMPRODUCT(‘LogisticRegression’!B$2:T$2,’TestSet’!A2:S2)+ ‘LogisticRegression’!U$2 287
288 Много цифр =СУММПРОИЗВ(‘LogisticRegression’!B$2:T$2,’TestSet’!A2:S2)+ ‘LogisticRegression’!U$2 Рис. 6-31. Лист логистической регрессии В ячейке Х2 подставьте это значение в функцию связи, чтобы получить классовую вероятность: =EXP(W2)/(1+EXP(W2)) Скопировав эти формулы на оба столбца листа тестовых данных, вы получите лист, изображенный на рис. 6-32. Чтобы увидеть, как располагаются прогнозы, скопируйте лист Performance и назовите его Performance Logistic. После изменения формул максимального и минимального прогнозов таким образом, чтобы они обращались к столбцу Х, значения остаются в промежутке между 0 и 1, как вы и хотели, и модель, в отличие от линейной регрессии, теперь выдает текущие значения вероятностей принадлежности к классам. ЗАМЕТКА Результатом работы логистической регрессии являются вероятности принадлежности к классам (текущие значения прогнозов между 0 и 1). Эти вероятности основываются на соотношении беременных и «не-беременных» покупателей, равном 50/50 в нашей ребалансированной обучающей выборке. Это вполне приемлемо, так как все, что вам нужно — это бинарная классификация по какому-нибудь ограничительному признаку, а не настоящие вероятности.
6. Бабушка контролируемого искусственного интеллекта — регрессия Рис. 6-32. Логистическая регрессия: прогнозы на основе тестовых данных Выберите граничные значения от 0 до 1 с шагом в 0,05 (на самом деле стоило бы 1 поменять на 0,999 или около того, чтобы избавить формулу точности от деления на 0). Все строки ниже 22 можно очистить, а параметры качества работы нужно изменить только в том, чтобы они обращались к столбцу Х листа Test Set, вместо столбца V. Таким образом у нас получается лист, изображенный на рис. 6-33. Вы можете построить кривую ошибок в точности так же, как и раньше. Однако, чтобы сравнить логистическую регрессию с линейной, нужно добавить ее ряд данных для параметров каждой модели (клик правой клавишей мыши на графике и выбор опции «Выбрать данные»). На рис. 6-34 хорошо видно, что кривые ошибок обеих моделей буквально сливаются. При том что качество моделей практически идентично, вы можете склониться к использованию логистической регрессии разве что по причине практичности — ведь на выходе получаются текущие вероятности принадлежности к классам от 0 до 1. Это приятнее, при прочих равных. СЛОВО ОБ ОСТОРОЖНОСТИ В реальном мире вы наверняка слышали многое мнений о выборе модели. Кто-то спросит: «А почему вы не воспользовались методом опорных векторов, нейронными сетями или случайными лесами деревьев с добавленными градиентами?» Типов моделей ИИ множество, и у каждой есть сильные и слабые стороны. Неплохо было бы попробовать некоторые из них в своей работе. 289
290 Много цифр Но! Испытание различных моделей ИИ — не самая важная часть проекта моделирования ИИ. Это последний этап, вишенка на торте. И именно в этот момент сайты вроде Kaggle.com (сайт состязаний по моделированию ИИ) делают все не так. Вы получаете гораздо большую отдачу, когда тратите время на выбор хороших данных и отличительных признаков для вашей модели. К примеру, в задаче, приведенной в этой главе, вам бы лучше было обойтись тестированием возможных отличий вроде «покупатель перестал покупать мясо на ужин из-за боязни пастереллёза» и проверкой обучающих данных, чем тестированием нейронной сети на старом наборе для обучения. Почему? Да потому, что пословица «Что посеешь, то и пожнешь» ни к чему не подходит так хорошо, как к ИИ. Модель ИИ — не волшебный помощник, она не может «проглотить» ужасную выборку и чудесным образом указать, как использовать эти данные. Поэтому сделайте одолжение своей модели ИИ — проявите изобретательность и найдите самые лучшие отличительные черты, какие только возможно. Рис. 6-33. Лист Performance Logistic
6. Бабушка контролируемого искусственного интеллекта — регрессия 90% 80% Логистическая регрессия 70% Линейная регрессия 60% 50% 40% 30% 20% 10% % 0% 10 % 90 % 80 % 70 % 60 % 50 % 40 % 30 % 20 0% 0% 10 Действительно положительные значения Кривая ошибок 100% Ложноположительные значения Рис. 6-34. Кривые ошибок линейной и логистической регрессий Дополнительная информация Если вам очень понравился контролируемый ИИ и вы нашли в этой главе ответы на свои вопросы, то я, с вашего позволения, предложу вашему вниманию несколько книг: Data Mining with R, Luis Torgo (Chapman & Hall/CRC, 2010) прекрасно под• ходит для следующего шага. В этой книге дается описание машинного обучения на языке программирования R. R — любимый язык всех и каждого, кто работает со статистикой, и его несложно освоить в достаточном для моделирования ИИ объеме. R будет идеальной площадкой для обучения и запуска вашей производственной модели. The Elements of Statistical Learning, Trevor Hastie, Robert Tibshirani, Jerome • Friedman (Springer, 2009). Выражает академический взгляд на различные модели ИИ. Местами тяжеловатая для восприятия, эта книга может действительно поднять ваши интеллектуальные изыскания на новый уровень. На сайте Hastie’s Stanford есть бесплатная онлайн-версия. Для бесед с другими профи в области моделирования я обычно использую форум CrossValidated на StackExchange (stats.stackexchange.com). Частенько оказывается, что интересующий вас вопрос уже давно кто-то задал. С моей точки зрения, этот форум — отличная база знаний. 291
292 Много цифр Подытожим Поздравляю! Вы только что построили модель классификации в электронной таблице. Даже две. Может, даже две с половиной. А если вы еще и приняли мой вызов с медианной регрессией, то вы просто гигант! Давайте вспомним, чем же мы занимались в этой главе: выбор отличительных черт и сборка обучающих данных, включая созда• ние фиктивных переменных из категорийных данных; обучение модели линейной регрессии путем минимизации суммы ква• драта отклонений; вычисление R-квадрата, показывающего с помощью теста, что модель ста• тистически значима; определение качества работы модели на опорной выборке при различных • ограничениях с помощью вычисления точности, специфичности, доли ложноположительных результатов и памяти; отображение кривой ошибок; • добавление логистической функции связи к общей линейной модели и ре• оптимизация; максимизация вероятности в логистической регрессии; • сравнение моделей с помощью кривой ошибок. • Несмотря на то, что данные в этой главе — чистейшая выдумка, подобная логистическая модель — отнюдь не повод для шуток. Вы можете воспользоваться аналогичными инструментами для поддержки производственных решений или автоматизированной системы маркетинга вашего бизнеса. Если вам хочется продолжать работу с ИИ, то в следующей главе я покажу вам другой подход, который называется комбинированной моделью.
7 В Комплексные модели: огромная куча ужасной пиццы американской версии популярного сериала «Офис» начальник Майкл Скотт однажды купил для коллег пиццу. И все расстроились, когда узнали, что он случайно сделал покупку в «Пицце от Альфредо» вместо Alfredo's Pizza. Более дешевая, она оказалась просто ужасной. В ответ на жалобы Майкл задал подчиненным вопрос: что лучше — маленький кусочек хорошей пиццы или большой кусок ужасной? Многим людям, работающим с искусственным интеллектом, вполне возможно, больше понравится второй вариант. В предыдущей главе мы построили одну хорошую модель для определения беременных покупателей РитейлМарта. А что, если наоборот, стать немного демократичней? Что, если построить несколько заведомо неказистых моделей и затем устроить голосование по поводу беременности покупателя — а процент голосов использовать как единичный прогноз? Такой вид подхода называется комплексным моделированием, или ансамблем моделей (ensemble modeling). Как вы сможете убедиться, он обладает весьма ценным свойством — превращает обычные наблюдения в золото. Мы столкнемся с таким типом комплексной модели, как bagged decision stumps — бэггинговые одноуровневые деревья принятия решений (bagging — сокращенно от bootstrap aggregating — один из методов метаанализа), очень сильно напоминающим популярный в индустрии подход «случайный лес» (random forest). Нечто похожее я применяю каждый день в MailChomp.com, пытаясь предсказать, когда какой-нибудь пользователь собирается разослать спам. После бэггинга мы перейдем к еще одной отличной технике под названием бустинг (boosting). Обе эти техники находят замысловатые способы снова и снова использовать обучающие данные для обучения целого ансамбля классификаторов. Интуитивно они напоминают наивный Байес — глупость, в итоге оказывающаяся умной.
294 Много цифр Используем данные из главы 6 ЗАМЕТКА Электронная таблица Excel с вводными данными, используемая в этой главе, “Ensemble. xlsm”, доступна для скачивания на сайте книги www.wiley.com/go/datasmart. Или же вы можете просто следить за моими действиями по готовой заполненной таблице. Эта глава пролетит быстро, потому что мы возьмем базу данных РитейлМарта из главы 6. Используя те же самые данные, вы лучше поймете различия в применении двух моделей, которые я собираюсь вам предложить, и регрессионных моделей из предыдущей главы. Техники моделирования, которые мы будем использовать в этой главе, придуманы не так давно. Они более интуитивны и, вероятно, являются одними из самых мощных технологий ИИ, существующих на данный момент. Также мы построим кривые ошибок в точности, как в главе 6, так что я не буду тратить много времени на объяснение расчетов параметров качества работы модели. Загляните в главу 6, если вдруг захотите освежить в памяти понятия «точность» и «чувствительность». Итак, начнем. В таблице, которую вы, возможно, загрузили, есть лист TD, содержащий обучающие данные из главы 6 с уже настроенными фиктивными переменными (подробнее также в главе 6). Отличительные признаки пронумерованы от 0 до 18 в строке 2. Нумерация пригодится нам чуть позже для записей результатов (рис. 7-1). Также рабочая таблица содержит лист Test Set из главы 6. Рис. 7-1. Лист TD содержит данные из главы 6
7. Комплексные модели: огромная куча ужасной пиццы С этими данными вам предстоит сделать в точности то же, что вы делали в главе 6 — предсказать значения в столбце Pregnant с помощью данных слева от него, а затем проверить точность на тестовом наборе. ОЦЕНКА НЕДОСТАЮЩЕЙ ВЕЛИЧИНЫ В примере РитейлМарта, приведенном в главе 6 и продолженном здесь, вы работаете с набором данных, в котором нет пробелов. Для многих моделей, построенных на транзакционных данных бизнеса, это весьма актуально. Но и вы столкнетесь с ситуацией, когда в какой-нибудь строке данных не окажется элемента. К примеру, если вы строите рекомендательную бизнес-модель для сайта знакомств и включаете в анкету профиля пользователя вопрос, слушает ли он симфоническую хэви-метал группу Evanescence, то резонно ожидать, что часть пользователей оставит эту графу незаполненной. Как же обучать модель, если респондент оставил пустой графу с вопросом об Evanescence? На этот вопрос есть множество ответов. Я перечислю коротко несколько моментов, от которых можно оттолкнуться. • Просто выкиньте строки с недостающими значениями. Если эти значения более или менее случайны, потеря пары строк обучающей последовательности не будет критичной. Хотя как раз в примере с сайтом знакомств эти пропуски, скорее всего, будут носить намеренный, а не случайный характер, так что из-за потери строк набор данных может искаженно отображать реальность. • Если значения столбца — числовые, пропущенные значения можно заменить средними по параметру. Подстановка недостающих значений часто называется imputation (приписывание). Если столбец категорийный, используйте самое популярное значение категории. Опять же, в примере с пристыженными фанатами Evanescence, самым популярным ответом будет «Нет», следовательно, заполнение самым популярным значением — не лучший выход, если человек вдруг решит проверить свой профиль. • Вдобавок к предыдущей опции вы можете вставить рядом еще один столбец, заполненный нулями, пока не появится недостающее значение — в этом случае 0 становится 1. Таким образом вы заполняете пропущенные значения как можете, но рекомендуете модели не очень-то им доверять. • Вместо использования среднего можно обучить модель типа общей линейной модели из предыдущей главы «додумывать» недостающие значения, используя данные из других столбцов. Это, конечно, лишняя работа, но она того стоит, если у вас небольшой набор данных и вы не можете себе позволить потерю точности или целых строк. 295
296 Много цифр • К сожалению, последний подход (как и все остальные, упомянутые в этой заметке) отмечен отпечатком излишней самонадеянности. Он подразумевает отношение к приписанным данным как к гражданам высшего класса, если они предсказаны графиком регрессии. Чтобы обойти этот недостаток, те, кто работает со статистикой, часто используют статистические модели и создают несколько графиков регрессии. Пропуск в данных заполняется несколько раз с помощью этих моделей, каждая из которых, в свою очередь, создает свой набор данных. Дальше над вставленными наборами данных можно проводить любой анализ и комбинировать в итоге любые его результаты. Эта операция называется множественной подстановкой (multiple imputation). • Еще один неплохой подход называется подстановкой k ближайших соседей. Используя расстояния (глава 2) или матрицы смежности (глава 5), можно найти k ближайших соседей пропущенного значения. Вычислите среднее взвешенное расстояние (или самую распространенную величину, которая вам нравится) до значений соседей и вставьте его вместо пропуска в данных. Бэггинг: перемешать, обучить, повторить Бэггинг (метод случайных подвыборок) — это техника, которая используется для обучения нескольких классификаторов (ансамбля, с вашего позволения), но не на абсолютно одинаковых выборках. Дело в том, что если вы будете обучать классификаторы на одинаковых данных, они сами станут одинаковыми — но вам же нужно разнообразие моделей, а не пачка копий одной и той же модели! Бэггинг позволяет внести в набор классификаторов небольшое разнообразие. Одноуровневое дерево решений — неудачное название «неумного» определителя В строящейся нами модели бэггинга отдельные классификаторы будут одноуровневыми деревьями решений. Одноуровневое дерево решений — не более чем один вопрос, который вы обращаете к данным. В зависимости от ответа вы можете понять, ожидает ли семья ребенка или нет. Простые классификаторы вроде этого часто называют weak learner — слабообучаемыми. К примеру, если в обучающих данных вы сосчитаете, сколько раз «беременная» семья заказывала препараты фолиевой кислоты, выделив Н3:Н502, и сложите результаты в итоговой строке, то узнаете, что 104 «беременные» семьи
7. Комплексные модели: огромная куча ужасной пиццы сделали такой заказ до рождения ребенка. С другой стороны, только двое «небеременных» покупателей заказали фолиевую кислоту. Так что между заказом препаратов фолиевой кислоты и беременностью, бесспорно, существует связь. Можно использовать эту простую зависимость для сборки такого слабообучаемого классификатора: Покупали ли семьи фолиевую кислоту? Если да, то считать их «беременными». Если нет, то считать их «не-беременными». Такой прогностический классификатор изображен на рис. 7-2. Информация о покупателе Покупали ли вы фолиевую кислоту НЕТ ДА Не беременны Беременны Рис. 7-2. Фолиевое одноуровневое дерево А мне не кажется, что это глупо! Дерево решений на рис. 7-2 делит выборку обучающих записей на две подвыборки. Вы, наверное, думаете, что это дерево имеет глубокий смысл? Что ж, в известной степени вы правы. Хотя смысл этот все-таки не настолько глубок, как вам кажется. В конце концов, в вашей обучающей выборке имеется около 400 «беременных» семей, которые не покупали фолиевую кислоту и были неправильно классифицированы деревом решений. Все равно лучше, чем вовсе никакой модели, да? Несомненно. Но вопрос в том, насколько данное дерево лучше полного отсутствия модели. Один из способов оценить это — применить параметр под названием node impurity — загрязненность класса. Этим способом измеряется, как часто выбранная запись покупателя была неправильно классифицирована в качестве беременной или «не-беременной», 297
298 Много цифр если классификация производилась случайным образом, согласно распределению покупателей в своей подвыборке дерева решений. К примеру, можно начать с отнесения всей тысячи покупателей в одну подвыборку, что является, скажем прямо, стартом без модели. Вероятность того, что вы выберете беременного покупателя из кучи, равна 50%. Классифицировав его случайным образом, исходя из соотношения 50/50, вы получите 50%-ный шанс правильно угадать класс. Таким образом, получается 50% × 50% = 25% вероятность выбора беременного покупателя и правильного угадывания факта беременности. Аналогично равна 25% вероятность выбора «не-беременного» покупателя и угадывания того, что он не является беременным. Все, что не относится к этим двум случаям — просто версии неверных догадок. Значит, у нас есть 100% – 25% – 25% = 50% шанс неправильного отнесения покупателя к классу. Дерево решений по фолиевой кислоте делит этот набор из 1000 записей на две группы — 894 человека, не купивших фолиевые препараты, и 106 купивших. У каждой из этих подвыборок своя собственная загрязненность, так что, усреднив загрязненность обеих подвыборок (принимая во внимание разницу в их размере), вы сможете узнать, насколько одноуровневое дерево исправило ситуацию. Из 894 покупателей, попавших в «не-беременную» корзину, 44% беременны, а 56% — нет. Загрязненность можно рассчитать как 100% — 44%^2–56%^2 = 49%. Не такое уж большое улучшение. Что касается тех 106 покупателей, которых мы поместили в «беременную» категорию: 98% из них беременны, и только 2% — нет. Загрязненность будет равна 100% – 98^2 – 2^2 = 4%. Усреднив общее значение загрязненности, получаем 44%. Это получше, чем бросать монетку! Расчет загрязненности показан на рис. 7-3. ДЕЛИМ СВОЙСТВО НА БОЛЬШЕЕ КОЛИЧЕСТВО ЧАСТЕЙ В примере РитейлМарта все независимые переменные бинарны. Вам не нужно думать, как разделить обучающие данные для дерева принятия решений — единицы отправляются в одну сторону, нули — в другую. Но что, если у вас есть признак, имеющий все варианты значения? К примеру, один из прогнозов, который мы делаем в MailChimp.com, — это жив ли почтовый ящик и может ли он принимать почту. Один из используемых для этого параметров — количество дней, прошедших с момента отправления последнего письма на этот адрес. (Мы отправляем около 7 миллиардов писем в месяц, так что кое-какие данные у нас есть на каждого…)
7. Комплексные модели: огромная куча ужасной пиццы Этот признак совершенно не бинарен! И если мы обучаем дерево решений, которое его использует, то как определить, на сколько частей его делить, чтобы направить одну часть данных в одном направлении, а другую — в другом? На самом деле все очень просто. Существует ограниченное число групп, на которые вы можете поделить дерево. Максимум — это одна запись из вашей последовательности в каждой группе. И наверняка в вашем наборе есть такие адреса, у которых количество дней будет точно таким же, как прошло с последнего вашего письма им. Вам нужны только эти значения. Если у вас есть четыре уникальных значения, на которые вы можете поделить обучающую выборку (скажем, 10, 20, 30 и 40 дней), деление на 35 не сложнее деления на 30. Так что вы просто проверяете значения загрязненности для каждого выбранного вами деления, а затем выбираете количество групп с наименьшей загрязненностью. Готово! 500 беременных/500 нет Загрязненность = 100% – (50%2) – (50%2) = 50% Информация о покупателе НЕТ Не беременны Покупали ли Вы фолиевую кислоту? Средняя загрязненность: 0,89 * 0,49 + 0,11 * 0,04 = 44% 396 беременных/498 нет (89%) Загрязненность = 100% – (44%2) – (56%2) = 49% ДА Беременны 104 беременных/2 нет (11%) Загрязненность = 100% – (98%2) – (2%2) = 4% Рис. 7-3. Загрязненность классов для фолиевого дерева 299
300 Много цифр Нужно еще сильнее! Одноуровневого дерева решений недостаточно. Представьте, что у вас огромное количество деревьев, каждое из которых обучено на разной части данных и загрязненность результатов каждого — меньше 50%? В таком случае стоит разрешить им голосование. Основываясь на проценте деревьев, проголосовавших за беременность, вы можете принять решение отнести покупателя к беременным. Но вам нужно еще больше деревьев! Одно вы уже обучили на столбце с фолиевой кислотой. Почему бы не сделать то же самое со всеми остальными столбцами? У вас всего 19 признаков, и, честно говоря, некоторые из них, такие как адрес в виде дома или квартиры, несколько озадачивают. Так что вы имеете дело с 19 одноуровневыми деревьями сомнительного качества. Но с помощью метода случайных подвыборок (бэггинга, bagging) можно «изготовить» сколько хотите деревьев. Бэггинг действует примерно таким образом: 1. Для начала откусывает кусочек выборки. Стандартная практика — взять приблизительный квадратный корень из количества признаков (четыре случайных столбца в нашем примере) и случайным образом две трети строк. 2. Строит дерево решений для каждого из этих четырех выбранных вами признаков, с помощью случайно выбранных 2/3 данных. 3. Из этих четырех деревьев выбирает чистейшее. Сохраняет. Перемешивает все заново в большом котле и обучает новое дерево. 4. Когда у вас накопится куча деревьев, соберите их вместе, заставьте проголосовать и назовите их единой моделью. Обучим же ее! Из обучающих данных вам нужно взять случайный набор строк и столбцов. Простейший способ это сделать — перемешать столбцы как колоду карт, а затем выбрать необходимое из верхнего левого угла таблицы. Для начала скопируйте А2:U1002 из вкладки TD в верхнюю часть новой таблицы под названием TD_BAG (названия признаков вам не понадобятся — нужны только их порядковые номера из строки 2). Самый простой способ перемешать TD_BAG — это добавить еще один столбец и одну строку, заполненные случайными числами (с помощью оператора RAND/СЛЧИС). Сортировка по случайным значениям слева направо и сверху вниз, а затем выбор нужного количества из верхнего левого угла таблицы дает вам случайный набор строк и признаков.
7. Комплексные модели: огромная куча ужасной пиццы Получение случайного образца Вставьте пустую строку над номерами признаков и добавьте RAND/СЛЧИС в строку 1 (А1:S1) и в столбец V (V3:V1002). Таблица, получившаяся в результате, показана на рис. 7-4. Обратите внимание, что столбец V я назвал RANDOM. Рис. 7-4. Добавление случайных чисел в верхнюю и боковую часть данных Отсортируйте столбцы и строки случайным образом. Начните со столбцов, так как поперечная сортировка предпочтительнее. Чтобы перемешать столбцы, выделите их от А до S кроме столбца Pregnant, который является не признаком, а зависимой переменной. Откройте окно настраиваемой сортировки (более подробно она описана в главе 1). В окошке «Сортировка» (рис. 7-5) нажмите «Параметры» и выберите сортировку слева направо, чтобы ранжировать столбцы. Проверьте, что она проводится по строке 1, заполненной случайными числами. Также убедитесь, что напротив опции «Сортировать по существующему списку» не стоит галочка, так как у вас нет заголовков в горизонтальном направлении. Нажмите ОК. Вы увидите, как столбцы в таблице перемешиваются. Теперь то же самое нужно сделать со строками. В этот раз выберите промежуток А2:V1002, включая столбец Preganant, таким образом оставляя его привязанным к данным, за исключением строки случайных чисел вверху таблицы. Снова откройте окошко настраиваемой сортировки и под разделом «Параметры» на этот раз выберите «Отсортировать сверху вниз». Убедитесь, что отмечена опция «Сортировать по существующему списку», а затем выберите из выпадающего списка столбец Random. Окошко сортировки должно выглядеть, как показано на рис. 7-6. 301
302 Много цифр Рис. 7-5. Сортировка слева направо Рис. 7-6. Сортировка сверху вниз. Теперь, когда вы рассортировали ваши данные случайным образом, выберите прямоугольник, образованный первыми четырьмя столбцами и первыми 666 строками. Создайте новый лист и назовите его RandomSelection. Чтобы выбрать случайный образец, укажите в ячейке А1 следующее: =TD_BAG!A2 А затем скопируйте эту формулу до D667. Вы можете получить значения Preganant рядом с образцом, направляя их прямо в столбец Е. Е1 указывает на ячейку U2 предыдущего листа: =TD_BAG!U2 Кликните дважды на этой формуле, чтобы распространить ее на весь лист. Когда вы это сделаете, у вас не останется ничего, кроме случайных данных (рис. 7-7). Поскольку данные отсортированы случайным образом, в конце концов у вас остается четыре разных столбца с признаками.
7. Комплексные модели: огромная куча ужасной пиццы Самое приятное то, что если вы вернетесь на лист TD_BAG и отсортируете все заново, этот образец обновится автоматически! Рис. 7-7. Четыре случайных столбца и случайные две 2/3 строк Выращиваем одноуровневое дерево из образца Глядя на любой из этих четырех признаков, можно понять: есть только четыре вещи, которые могут произойти между одним признаком и зависимой переменной Preganant: признак может иметь значение 0, а Preganant — 1; • признак может иметь значение 0, а Preganant — 0; • признак может иметь значение 1, а Preganant — 1; • признак может иметь значение 1, а Preganant — 0. • Вам нужно сосчитать количество обучающих строк, попадающих в каждый из этих случаев, чтобы построить дерево по признаку, аналогичное тому, что изображено на рис. 7-2. Для этого пронумеруйте четыре обозначенные комбинации нулей и единиц в G2:H5. Настройте I1:L1 так, чтобы в нем были порядковые номера из А1:D1. Теперь таблица выглядит, как на рис. 7-8. После настройки этой небольшой таблицы вам нужно заполнить ее количествами обучающих строк, значения которых совпадают с комбинацией прогноза и значением в столбце Preganant. Для верхнего левого угла таблицы (первый признак в моем случайном наборе оказался с номером 15) вы можете сосчитать 303
304 Много цифр Рис. 7-8. Четыре возможных варианта обучающих данных количество обучающих строк, в которых признак 15 имеет значение 0, а столбец Preganant — значение 1, с помощью следующей формулы: =COUNTIFS(A$2:A$667,$G2,$E$2:$E$667,$H2) =СЧЁТЕСЛИМН(A$2:A$667,$G2,$E$2:$E$667,$H2) Формула COUNTIFS/СЧЁТЕСЛИМН позволяет вам сосчитать строки, удовлетворяющие нескольким критериям (спасибо S//МН в конце названия!). Первый критерий смотрит на промежуток признака номер 15 (А2:А667) и проверяет его на строки, идентичные значению ячейки G2 (0), в то время как второй критерий проверяет отрезок Preganant (Е2:Е667) на строки, идентичные значению ячейки Н2 (1). Скопируйте эту формулу во все остальные ячейки таблицы, чтобы получить количества для каждого случая (рис. 7-9). Рис. 7-9. Пары признак/ответ для каждого признака в случайном образце Если бы каждый из этих признаков был деревом решений, то какое значение признака являлось бы индикатором беременности? Несомненно, значение с самой высокой концентрацией беременных покупателей в образце.
7. Комплексные модели: огромная куча ужасной пиццы В строке 6 под значениями количества вы можете сравнить эти отношения. Поместите в I1 формулу: =IF(I2/(I2+I3)>I4/(I4+I5),0,1) =ЕСЛИ(I2/(I2+I3)>I4/(I4+I5),0,1) Если отношение беременных покупателей, ассоциированное с нулевым значением признака (I2/(I2+I3)), больше, чем ассоциированное с единицей (I4/ (I4+I5)), то 0 — показатель беременности в этом дереве. Если все наоборот, то 1. Скопируйте эту формулу вправо до столбца L. Таким образом получится лист, изображенный на рис. 7-10. Рис. 7-10. Вычисление значения признака, ассоциированного с беременностью Используя значения в строках с 2 по 5, вы можете рассчитать значения загрязненности для групп каждого дерева решений, которое вы выбрали для разделения по признаку. Вставим расчет загрязненности в строку 8 под подсчетом случаев. Так же, как и на рис. 7-3, вам нужно вычислить значение загрязненности для обучающих случаев, имеющих значение признака 0, и усреднить их с теми, у которых 1. Если вы используете первый признак (номер 15 для меня), 299 беременных и 330 «не-беременных» оказались в группе 0, так что загрязненность равна 100% — (299/629)^2 – (330/629)^2, что можно ввести в таблицу следующим образом: =1–(I2/(I2+I3))^2-(I3/(I2+I3))^2 Точно так же загрязненность для группы 1 может быть записана так: =1-(I4/(I4+I5))^2-(I5/(I4+I5))^2 305
306 Много цифр Вместе они составляют взвешенное среднее: каждая загрязненность умножается на количество обучающих случаев в группе, затем результаты складываются и делятся на общее количество случаев, то есть 666: =(I8*(I2+I3)+I9*(I4+I5))/666 Теперь вы можете растянуть этот расчет загрязненности на все признаки, получая комбинированные значения для каждого из возможных деревьев решений, как показано на рис. 7-11. Рис. 7-11. Комбинированная загрязненность для четырех деревьев решений Ваши значения загрязненностей наверняка будут отличаться от моих — ведь мы пользовались генератором случайных чисел. В моем случае победителем явно является номер 8 (заглянув в лист TD, можно найти название признака, это — витамины для беременных) со значением 0,450. Записываем победителя Итак, витамины в моем варианте победили. У вас результат наверняка оказался другим, и теперь следует его где-то записать. Назовите ячейки N1 и N2 Winner и Pregnant Is. Вы сохраняете выигравшие деревья в столбце О. Начните с сохранения номера выигравшего столбца в ячейке О1. Это будет значение из промежутка I1:L1 с минимальной загрязненностью (в моем случае это 8). Вы также можете скомбинировать формулы MATCH/ПОИСКПОЗ и INDEX/ИНДЕКС, чтобы они нашли его за вас (более подробно о них рассказано в главе 1):
7. Комплексные модели: огромная куча ужасной пиццы =INDEX(I1:L1,0,MATCH(MIN(I10:L10),I10:L10,0)) =ИНДЕКС(I1:L1,0,ПОИСКПОЗ(МИН(I10:L10),I10:L10,0)) MATCH(MIN(I10:L10),I10:L10,0))/ПОИСКПОЗ(МИН(I10:L10),I10:L10,0)) находит столбец с минимальной загрязненностью в строке 10 и передает информацию функции INDEX/ИНДЕКС. Эта функция определяет положение названия соответствующего признака. Аналогично в О2 можно определить, 0 или 1 ассоциируется с беременностью — найти значение в строке 6 в столбце с минимальной загрязненностью: =INDEX(I6:L6,0,MATCH(MIN(I10:L10),I10:L10,0)) =ИНДЕКС(I6:L6,0,ПОИСКПОЗ(МИН(I10:L10),I10:L10,0)) Выигравшее дерево решений и его ассоциированная с беременностью группа затем выписываются, как показано на рис. 7-12. Рис. 7-12. Победитель по версии четырех деревьев Встряхни меня, Джуди! Фух! Я знаю, что это была целая куча маленьких шажков и всего одно дерево. Но сейчас, когда все формулы уже на месте, следующая пара сотен будет сущим пустяком. Второе дерево можно сделать очень быстро. Перед этим не забудьте сохранить только что построенное! Для этого просто скопируйте и вставьте значения из О1:О2 в Р1:Р2. Чтобы создать новое дерево, переключитесь на лист TD_BAG и снова перемешайте столбцы и строки. 307
308 Много цифр Вернитесь на лист RandomSelection. Вуаля! Победитель изменился. В моем случае это фолиевая кислота, и значение, соответствующее беременности, — 1 (рис. 7-13). Предыдущее дерево сохранилось справа. Рис. 7-13. При перемешивании данных появляется новое дерево Чтобы сохранить второе дерево, кликните правой кнопкой на столбец Р и выберите «Вставить», чтобы сместить первое дерево вправо. Ансамбль теперь выглядит так, как показано на рис. 7-14. Рис. 7-14. И теперь их два Как видите, с этим вторым дело пошло гораздо быстрее, чем с первым. Так что продолжайте…
7. Комплексные модели: огромная куча ужасной пиццы Скажем, вы хотите ансамбль из 200 моделей. Все, что вам нужно сделать, — это повторить эти шаги еще 198 раз. Ничего невозможного, просто надоедает. Почему бы вам просто не записать это действие в макрос и затем проигрывать его? Оказывается, перемешивание очень подходит для макроса. Для тех, кто никогда не записывал макрос: это не что иное, как запись серии повторяющихся нажатий на клавиши, чтобы потом можно было ее проиграть вместо того, чтобы самому зарабатывать туннельный синдром. Так что ищем на панели меню Вид Макрос (в MacOs Инструменты Макрос) и выбираем «Начать запись». Нажатие кнопки «Запись» откроет окно, в котором вы сможете дать своему макросу название, например GetBaggedStump. Удобства ради проассоциируем вызов макроса с комбинацией клавиш. У меня MacOS, так что все мои комбинации начинаются с Option + Cmd, к которым я хочу добавить Z, потому что сегодня у меня такое настроение (рис. 7-15). Рис. 7-15. Готов к записи макроса Нажмите ОК, чтобы начать запись. Вот шаги, которые нужны для создания одноуровневого дерева решений: 1. 2. 3. 4. 5. 6. 7. Нажать на лист TD_BAG. Выделить столбцы от А до S. Вручную рассортировать столбцы. Выделить строки от 2 до 1002. Вручную рассортировать строки. Переключиться на лист RandomSelection. Кликнуть правой клавишей мышки на столбце Р и вставить новый пустой столбец. 309
310 Много цифр 8. Выделить и скопировать выигрышное дерево из О1:О2. 9. Вставить «Специальной вставкой» значения в Р1:Р2. Перейдите в меню Вид Макрос Остановить запись (Инструменты Макрос Остановить запись в Excel 2011 для MacOs), чтобы закончить запись. Теперь вы можете создавать новые деревья решений простым нажатием комбинации клавиш, активирующей макрос. Подождите, пока я понажимаю на клавиши раз так 19 800… Оценка бэггинговой модели Вот это бэггинг! Все, что нужно сделать — это перемешать данные, взять подвыборку, обучить простой классификатор — и все по новой! Накопив в своем ансамбле пачку классификаторов, вы будете готовы делать прогнозы. Когда вы запустите макрос дерева решения пару сотен раз, лист RandomSelection будет выглядеть примерно так, как показано на рис. 7-16 (ваши деревья могут отличаться от моих). Рис. 7-16. 200 деревьев решений Прогнозирование на тестовой выборке Теперь, когда у вас есть деревья, пришло время опробовать модель на тестовых данных. Создайте копию листа TestSet и назовите ее TestBag. Переместитесь на лист TestBag и вставьте две пустые строчки в самый верх листа — это будет место для новых деревьев. Вставьте значения деревьев из листа RandomSelection (Р1:HG2, если у вас их 200) в лист TestBag, начиная со столбца W. Таким образом получается лист, изображенный на рис. 7-17. Вы можете запускать по одной строке тестовых данных в каждое дерево. Начните с первой строки данных (строка 4) и первого дерева в столбце W. Можете использовать формулу OFFSET/СМЕЩ, чтобы найти значение из столбца с деревом, записанное в W1. Если это значение равняется значению в W2, то дерево
7. Комплексные модели: огромная куча ужасной пиццы Рис. 7-17. Деревья, добавленные в лист TestBag прогнозирует беременность покупателя. В противном случае прогноз дерева — покупатель не является беременным. Формула выглядит так: =IF(OFFSET($A4,0,W$1)=W$2,1,0) =IF(СМЕЩ($A4,0,W$1)=W$2,1,0) Ее можно скопировать во все деревья на всем листе (обратите внимание на абсолютные ссылки). Таким образом получается лист, изображенный на рис. 7-18. Рис. 7-18. Деревья, оцененные с помощью тестового набора 311
312 Много цифр В столбце V вычислите среднее значение строк слева, чтобы получить классовую вероятность для беременности. К примеру, для V4, если у вас 200 деревьев, формула будет такова: =AVERAGE(W4:HN4) =СРЗНАЧ(W4:HN4) Скопируйте ее на весь столбец V, чтобы получить прогнозы для каждого столбца тестового набора, как показано на рис. 7-19. Рис. 7-19. Прогнозы для каждой строки Качество работы Вы можете оценить эти прогнозы, используя те же параметры оценки работы и расчеты, что и в главе 6. Сначала создайте новый лист под названием PerformanceBag. В первом столбце найдите максимальный и минимальный прогнозы. Для моих 200 деревьев эти значения получились равными 0,02 и 0,75. Поместите в столбец В серию граничных значений от минимума до максимума (в своем случае я сделал шаг равным 0,02). Точность, специфичность, доля положительных результатов и чувствительность вычисляются так же, как и в главе 6. Таким образом получается лист, изображенный на рис. 7-20. Обратите внимание на граничное значение прогноза 0,5 — при половине деревьев, проголосовавших за беременность, вы можете идентифицировать 33 беременных покупателя с одним лишь процентом ложноположительных результатов (напоминаю, что в вашем варианте это может быть совсем другое граничное значение — ведь мы используем случайные числа). Весьма неплохо для нескольких простых деревьев!
7. Комплексные модели: огромная куча ужасной пиццы Также вы можете вставить кривую ошибок, пользуясь долей ложноположительных и ложноотрицательных результатов (столбцы Е и F), опять же как в главе 6. График для моих 200 деревьев изображен на рис. 7-21. Рис. 7-20. Параметры качества работы модели бэггинга 90% 80% 70% 60% 50% 40% 30% 20% 10% % 90 % 10 0% % 80 % 70 % 60 % % 50 40 % 30 % 20 0% 0% 10 Действительно положительные значения Кривая ошибок 100% Ложноположительные значения Рис. 7-21. Кривая ошибок бэггинга 313
314 Много цифр Еще кое-что о работе модели Так как бэггинговая модель с одноуровневыми деревьями поддерживается промышленными пакетами программ, такими, к примеру, как пакет randomForest для R, я хотел бы особо выделить два отличия между этой и типовыми моделями. Обычные случайные леса выбирают образцы с заменой, в том смысле, что • одна и та же строка обучающих данных может быть отобрана в образцы больше одного раза. Вы можете выбрать то же количество записей, что и в вашем обучающем наборе, не ограничиваясь двумя третями. У выбора с заменой выше статистические характеристики, но если вы работаете с достаточно большим объемом данных, то особой разницы между этими двумя методами нет. Случайные леса по умолчанию выращены из деревьев полной классифи• кации, а не из одноуровневых. Полное дерево таково, что, разделив данные на два класса, вы выбираете все новые признаки для деления, пока, наконец, не столкнетесь с ограничительным критерием. Деревья полной классификации лучше, чем одноуровневые, если между признаками есть какая-либо связь, которую можно смоделировать. Переходя к точности модели, привожу несколько преимуществ бэггингового подхода: бэггинг устойчив к выбросам и не пытается слишком сильно подгонять дан• ные. Слишком сильная подгонка приводит к тому, что модель отражает не только ваши данные, но и статистический шум; процесс обучения можно проводить параллельно, потому что обучение • одного слабообучаемого не зависит от обучения предыдущего слабообучаемого; этот тип модели способен обрабатывать тонны переменных решения. • Модели, используемые нами в MailChimp.com для предсказания спама и домогательств, — это модели случайного леса, которые мы обучаем параллельно с помощью примерно 10 миллиардов строк необработанных данных. Такое нельзя проделать в Excel, и я абсолютно уверен, что не стал бы пользоваться для этого макросом. Я использую язык программирования R с пакетом randomForest, о котором я рекомендую узнать поподробнее, если вы собираетесь использовать какуюнибудь из этих моделей в своей организации. С помощью randomForest можно построить и модель, рассматриваемую в этой главе, — надо всего лишь отключить выбор с заменой и установить максимальное количество групп в деревьях принятия решений на 2 (подробнее в главе 10).
7. Комплексные модели: огромная куча ужасной пиццы Бустинг: если сразу не получилось, бустингуйте и пробуйте снова Давайте вспомним, зачем мы занимались бэггингом. Если вы обучаете пачку деревьев поиска решений на полном наборе данных несколько раз, снова и снова, то они будут идентичны. Выбирая образцы из базы данных случайным образом, вы вносите немного разнообразия в ваши деревья и, в конце концов, находите такие нюансы в обучающих данных, которые одно дерево ни за что бы не обнаружило. Бэггинг делает со случайным выбором то же самое, что бустинг делает с весами. Бустинг не выбирает случайные порции из набора данных — он использует весь набор данных в каждой итерации обучения. Он фокусируется на обучении дерева решений, которое исправляет некоторые грехи, совершенные предыдущими деревьями. Алгоритм таков: Сначала все строки обучающих данных считаются одинаковыми. Все они • имеют одинаковый вес. В вашем случае есть 100 строк, и все они начинают с весом 0,001. То есть в сумме все веса составляют единицу. Оцените каждый признак на фоне остальных, чтобы выбрать лучшее дерево • решений. Кроме того, если мы применяем бустинг, а не бэггинг, то победит дерево с минимальным взвешенным отклонением (погрешностью). Каждое ложное предположение для возможного дерева считается штрафом, равным весу строки. Сумма этих штрафов и есть взвешенная погрешность. Выберите дерево с минимальной взвешенной погрешностью. Веса регулируются. Если выбранное дерево решений правильно предска• зывает строку, то ее вес уменьшается. Если выбранное дерево решений ошибается со строкой, то вес строки растет. Новые деревья обучаются с помощью этих новых весов. Таким образом, • по ходу выполнения, алгоритм больше концентрируется на строках с обучающими данными, которые предыдущие деревья обработали плохо. Деревья обучаются, пока взвешенное отклонение не достигнет порога. Что-то из этого может показаться немного непонятным, но процесс сделает все абсолютно ясным в таблице. Вперед, к данным! Обучаем модель: каждому признаку — шанс В бустинге каждый признак — это возможное дерево в каждой итерации. В этот раз вам не придется выбирать по четыре. 315
316 Много цифр Для начала создайте лист под названием BoostStumps. Вставьте в него возможные комбинации признака/результата из промежутка G1:H5 листа RandomSelection. Рядом с этими значениями в строку 1 вставьте номера признаков (0–18). В итоге получается лист, изображенный на рис. 7-22. Рис. 7-22. Лист BoostStumps в исходном положении Под каждым номером, как и в бэггинге, нужно сложить количество строк обучающего набора, которые попадают в каждую из четырех комбинаций значения признака и независимой переменной, данных в столбцах А и В. Начните в ячейке С2 (номер признака 0) со сложения количества обучающих строк, имеющих 0 в графе данного признака и являющихся беременными. Это можно вычислить с помощью формулы COUNTIFS/СЧЁТЕСЛИМН: =COUNTIFS(TD!A$3:A$1002,$A2,TD!$U$3:$U$1002,$B2) =СЧЁТЕСЛИМН(TD!A$3:A$1002,$A2,TD!$U$3:$U$1002,$B2) Использование абсолютных ссылок позволяет вам раскопировать эту формулу до U5. Так получается лист, изображенный на рис. 7-23. Рис. 7-23. Подсчет делений обучающих данных по каждому признаку
7. Комплексные модели: огромная куча ужасной пиццы Так же, как и в бэггинге, в С6 вы можете найти значение, ассоциированное с беременностью для признака номер 0, глядя на соотношение беременных, ассоциированных со значениями признака, равными 0 и 1: =IF(C2/(C2+C3)>C4/(C4+C5),0,1) =ЕСЛИ(C2/(C2+C3)>C4/(C4+C5),0,1) Эту формулу можно раскопировать до столбца U. Теперь запишите в столбец В веса для каждого значения данных. Начните с В9 — назовите ячейку Current Weights, а под ней, до самой В1009, введите по 0,001 для каждой из тысячи обучающих строк. В строку 9 вставьте названия признаков из листа TD, чтобы было легче за ними следить. Так получается лист, который показан на рис. 7-24. Для каждого из этих возможных деревьев решений нужно вычислить взвешенную погрешность. Это делается путем определения положения обучающих строк, отнесенных к неправильному классу, и выписывания штрафа в размере их весов. К примеру, в ячейке С10 можно оглянуться на данные из первой обучающей строки для признака номер 0 (А3 на листе TD). Если они совпадают с индикатором беременности в С6, то вы получаете штраф (вес в ячейке В10), если строка (конечно, имеется в виду покупатель из строки) «не-беременна». Если же значение признака не совпадает с С6, то вы получаете штраф в случае беременности покупателя в строке. Получается такая формула с двумя операторами IF/ЕСЛИ: =IF(AND(TD!A3=C$6,TD!$U3=0),$B10,0)+ IF(AND(TD!A3<>C$6,TD!$U3=1),$B10,0) =ЕСЛИ(И(TD!A3=C$6,TD!$U3=0),$B10,0)+ ЕСЛИ(И(TD!A3<>C$6,TD!$U3=1),$B10,0) Абсолютные ссылки позволяют раскопировать формулу до U1009. Взвешенная погрешность для каждого возможного дерева решений затем может быть рассчитана в строке 7. Для ячейки С7 расчет взвешенной погрешности таков: =SUM(C10:C1009) =СУММА(C10:C1009) Скопируйте это в строку 7, чтобы получить взвешенную погрешность для каждого дерева решений (рис. 7-25). 317
318 Много цифр Рис. 7-24. Веса каждой строки обучающих данных Рис. 7-25. Расчет взвешенной погрешности для каждого дерева решений
7. Комплексные модели: огромная куча ужасной пиццы Выбираем победителя Поместите в ячейку W1 название Winning Error, а в Х1 найдите минимальное значение взвешенной погрешности: =MIN(C7:U7) =МИН(C7:U7) Как и в разделе про бэггинг, в Х2 нужно скомбинировать формулы INDEX/ ИНДЕКС и MATCH/ПОИСКПОЗ, чтобы найти выигрышное дерево: INDEX(C1:U1,0,MATCH(X1,C7:U7,0)) ИНДЕКС(C1:U1,0,ПОИСКПОЗ(X1,C7:U7,0)) А с помощью INDEX/ИНДЕКС и MATCH/ПОИСКПОЗ в Х3 можно узнать значение, ассоциирующееся с беременностью для этого дерева: =INDEX(C6:U6,0,MATCH(X1,C7:U7,0)) =ИНДЕКС(C6:U6,0,ПОИСКПОЗ(X1,C7:U7,0)) Так получается лист, изображенный на рис. 7-26. Начиная с одинаковых весов для каждой строки, признак номер 5 с индикатором беременности 0 выбран лучшим деревом. Вернувшись на лист TD, видим, что этот признак — противозачаточные. Рис. 7-26. Первое победившее бустинговое дерево Расчет альфа-значения для дерева Бустинг работает, назначая веса обучающим строкам, которые были неправильно классифицированы предыдущими деревьями. Деревья в начале процесса бустинга в целом более эффективны, в то время как деревья в конце обучающего 319
320 Много цифр процесса — более специализированные, так как веса меняются для концентрации на нескольких неприятных точках обучающих данных. Эти деревья со специализированными весами помогают в подгонке модели к странным точкам набора данных. Однако при этом их взвешенная погрешность будет больше, чем у деревьев в начале бустинга. Так как их взвешенная погрешность растет, общее улучшение, которое они вносят в модель, падает. В бустинге это соотношение выражается с помощью величины, которая называется альфа: альфа = 0,5 × ln((1 – общая взвешенная погрешность дерева) / общая взвешенная погрешность дерева) Так как общая взвешенная погрешность дерева растет, выражение под знаком натурального логарифма уменьшается и приближается к 1. А так как натуральный логарифм 1 равен 0, значение параметра альфа все уменьшается и уменьшается. Посмотрим на это в таблице. Назовите ячейку W4 Alpha, а в Х4 поместите взвешенную погрешность из Х1, подставленную в расчет параметра альфа: =0,5*LN((1-X1)/X1) Для этого первого дерева значение альфа в итоге получается равным 0,207 (рис. 7-27). Рис. 7-27. Значение параметра альфа для первой итерации бустинга Как именно используются эти значения параметра альфа? В бэггинге каждое дерево имело голос 0/1 для прогнозирования. При прогнозировании для бустингованных деревьев каждый классификатор вместо этого выдает значение
7. Комплексные модели: огромная куча ужасной пиццы альфа, если считает, что покупатель беременный, и –альфа, если нет. Так что это первое дерево во время голосования в тестовых данных будет давать 0,207 каждому покупателю, не купившему противозачаточные и –0,207 каждому купившему. Итоговый прогноз ансамбля моделей — это сумма всех этих положительных и отрицательных значений параметра альфа. Как вы увидите позже, чтобы определить общий прогноз беременности, выданный моделью, нужно установить границу на сумму баллов конкретного дерева. Поскольку в качестве своего вклада в прогноз каждое дерево выдает либо положительное, либо отрицательное значение альфа, в качестве классификационного порога принято использовать 0, однако вы можете менять его, дабы достичь большей точности. Повторное взвешивание Теперь, когда вы закончили с одним деревом, пришло время заново взвесить обучающие данные. Для этого нужно узнать, какие строки данных это дерево обрабатывает правильно, а какие — нет. Поэтому в столбце V озаглавьте ячейку V9 Wrong. В V10 можно использовать формулу OFFSET/СМЕЩ вместе с номером столбца выигравшего дерева (ячейка Х2), чтобы найти взвешенную погрешность обучающей строки. Если погрешность не нулевая, то значит, дерево неправильно обработало строку и в столбец Wrong записывается единица: =IF(OFFSET($C10,0,$X$2)>0,1,0) =ЕСЛИ(СМЕЩ($C10,0,$X$2)>0,1,0) Эту формулу можно раскопировать во все обучающие строки (обратите внимание на абсолютные ссылки!). Теперь исходные веса для этого дерева находятся в столбце В. Чтобы отрегулировать их согласно тому, какие строки получили 1 в столбце Wrong, бустинг умножает исходный вес на exp(альфа*Wrong) (где eхp— экспоненциальная функция, с помощью которой вы делали логистическую регрессию в главе 6). Если значение в столбце Wrong равно 0, то exp(альфа*Wrong) становится 1, и вес остается прежним. Если в столбце Wrong единица, то exp(альфа*Wrong) имеет значение больше 1, поэтому общий вес увеличивается. Назовите столбец W Scale by Alpha. В W10 можно будет рассчитать этот новый вес следующим образом: =$B10*EXP($V10*$X$4) Раскопируйте эту формулу на всю последовательность. 321
322 Много цифр К сожалению, эти новые веса уже не образуют в сумме 1, как исходные. Их нужно нормализовать (отрегулировать так, чтобы в сумме они все же давали 1). Поэтому назовите ячейку Х9 Normalize, а в Х10 разделите новый вес на сумму всех новых весов: =W10/SUM(W$10:W$1009) =W10/СУММА(W$10:W$1009) Теперь можно быть уверенным, что сумма новых весов — 1. Раскопируйте формулу. В итоге получается лист, изображенный на рис. 7-28. Рис. 7-28. Расчет нового веса И еще разок. И еще… Теперь вы готовы построить второе дерево. Сначала скопируйте данные выигравшего дерева из предыдущей итерации от X1:X4 до Y1:Y4. Теперь скопируйте новые значения весов из столбца Х в столбец В. Весь лист обновится, чтобы выбрать лучшее дерево для нового набора весов. Как показано на рис. 7-29, второе выигравшее дерево имеет номер 7 (фолиевая кислота), и 1 в нем обозначает беременность. Вы можете обучить эти 200 деревьев примерно таким же способом, как мы это делали в бэггинге. Просто запишите макрос, который вставляет новый столбец Y, копирует значения из Х1:Х4 в Y1:Y4 и переносит веса из столбца Х в столбец В.
7. Комплексные модели: огромная куча ужасной пиццы После 200 итераций ваша взвешенная погрешность возрастет почти до 0,5, в то время как значение альфа упадет до 0,005 (рис. 7-30). Вспомните, что ваше первое дерево имело значение альфа, равное 0,2. Это означает, что деревья в конце процесса в 40 раз слабее в голосовании, чем самое первое дерево в начале. Рис. 7-29. Второе дерево Рис. 7-30. Двухсотое дерево 323
324 Много цифр Оценка модели бустинга Ну вот! Вы обучили целую бустинговую модель деревьев принятия решений. Вы можете сравнить ее с моделью бэггинга, взглянув на ее параметры качества. Для этого сначала сделайте прогнозы с помощью модели на тестовых данных. Прогнозы на тестовой выборке Заготовьте копию тестовой выборки и назовите ее TestBoost, а затем вставьте четыре пустые строки в верхнюю часть листа, чтобы потом записать туда ваши победившие деревья. Начиная со столбца W на листе TestBoost вставьте ваши деревья (в моем случае 200) в верх листа. Так получается лист, изображенный на рис. 7-31. Рис. 7-31. Деревья решений, вставленные в лист TestBoost В ячейке W6 вы можете оценить первое дерево на первой строке тестовых данных с помощью OFFSET/СМЕЩ точно так же, как в модели бэггинга. За исключением того, что в этот раз прогноз беременности выдает значение альфа данного дерева (ячейка W4), а прогноз ее отсутствия — минус альфа. =IF(OFFSET($A6,0,W$2)=W$3,W$4,-W$4) =ЕСЛИ(СМЕЩ($A6,0,W$2)=W$3,W$4,-W$4) Скопируйте эту формулу на все деревья и на все строки тестовых данных (рис. 7-23). Чтобы сделать прогноз для строки, сложите эти значения по всем прогнозам ее дерева. Назовите V5 Score (баллы). Количество баллов в V6 — это просто сумма прогнозов, данных справа:
7. Комплексные модели: огромная куча ужасной пиццы Рис. 7-32. Прогнозы для каждой строки тестовых данных от каждого дерева =SUM(W6:HN6) =СУММА(W6:HN6) Скопируйте эту сумму на весь столбец. У вас получится лист вроде изображенного на рис. 7-33. Баллы в столбце V больше нуля означают, что больше альфа-взвешенных прогнозов ушло в положительном направлении, чем в отрицательном (рис. 7-33). Рис. 7-33. Итоговые прогнозы бустинговой модели 325
326 Много цифр Рассчитываем качество работы Чтобы измерить качество работы модели бустинга на тестовой выборке, создайте копию листа PerformanceBag и назовите ее PerformanceBoost. Укажите на столбец V листа TestBoost и установите граничные значения на возрастание от минимума баллов бустинговой модели до максимума. В моем случае я делаю это с шагом в 0,25 между минимальным значением прогноза в –8 и максимальным 4,5. Так получается лист качества работы, изображенный на рис. 7-34. Рис. 7-34. Параметры качества бустинговых деревьев На этой модели мы видим, что граничное значение баллов, равное 0, дает 85% положительных результатов и только 27% ложноположительных. Неплохо для 200 тупых деревьев! Добавьте кривую ошибок модели бустинга к кривой ошибок бэггинговой модели, чтобы сравнить их, как мы сравнивали модели в главе 6. Как явствует из рис. 7-35, бустинговая модель опережает бэггинговую во многих точках. Кое-что кроме качества В целом, чтобы сделать хорошую бустинговую модель требуется меньше деревьев, чем для модели бэггинга. Этот метод не так популярен, как бэггинг, потому
7. Комплексные модели: огромная куча ужасной пиццы 100% 90% Бустинговая Бэггинговая 80% 70% 60% 50% 40% 30% 20% 10% 0% 0% 10 % 20 % 30 % 40 % 50 % 60 % 70 % 80 % 90 % 10 0% Действительно положительные значения Кривая ошибок Ложноположительные значения Рис. 7-35. Кривые ошибок бустинговой и бэггинговой модели что риск переподгонки данных немного выше. Так как каждое переписывание обучающих данных основано на неверно классифицированных в предыдущей итерации точках, в итоге можно оказаться в ситуации, когда обученные вами классификаторы становятся чрезвычайно чувствительными к выбросам. К тому же итеративное повторное взвешивание данных означает, что бустинг, в отличие от бэггинга, не может быть запараллелен на несколько компьютеров или ядер процессора. Таким образом, в гонке между хорошо подогнанными бустинговой и бэггинговой моделями последней победа оказалась не по зубам. Подытожим Только что на ваших глазах пачка простых моделей была скомбинирована бэггингом или бустингом в ансамбль моделей. Эти методы, не известные аж до середины девяностых, сегодня являются двумя самыми популярными техниками моделирования, используемыми в бизнесе. Вы можете подвергнуть бустингу или бэггингу любую модель, которую хотите использовать как слабообучаемую. Эти модели совсем не обязательно состоят из одноуровневых или любых других деревьев принятия решений. К примеру, последнее время широко обсуждается бустинг моделей наивного Байеса, вроде того, с которым мы работали в главе 3. 327
328 Много цифр В главе 10 вы примените некоторые знания, полученные в этой главе, но уже на примере языка программирования R. Тем же, кто хочет узнать об этих алгоритмах побольше, я бы рекомендовал книгу The Elements of Statistical Learning Trevor Hastie, Robert Tibshirani, Jerome Friedman (Springer, 2009).
8 К Прогнозирование: дышите ровно, выиграть невозможно ак вы уже наверняка отметили при знакомстве с главами 3, 6 и 7, контролируемое машинное обучение заключается в предсказании значения либо классификации наблюдений с помощью модели, обученной на данных из прошлого. Прогнозирование занимается ровно тем же. Конечно, если вы астролог, то можете «прозревать грядущее» и без данных, но в количественном прогнозировании для предсказания событий в будущем всегда используются данные из прошлого. Некоторые техники, например, множественная регрессия (упомянутая в главе 6), применяются в обоих случаях. А вот где они действительно различаются — так это в вопросе канонических задач. Типичные задачи прогнозирования построены на изменении неких данных во времени (продаж, спроса, поставок, ВВП, выбросов углерода или численности населения, к примеру) и проецировании этих изменений на будущее. А с учетом трендов, циклов и периодических вмешательств божьей воли данные в будущем могут существенно отличаться от произошедшего в обозримом прошлом. В этом и состоит проблема прогнозирования: в отличие от глав 6 и 7, где беременные женщины более или менее стабильно продолжают покупать одни и те же товары, прогнозирование частенько используется в таких областях, где будущее совершенно не похоже на прошлое. Едва вы приходите к выводу, что у вас отличный прогноз спроса на жилье, пузырь недвижимости лопается и ваш прогноз отправляется в унитаз. Наш MailChimp.com может продолжать расти, как на дрожжах, а может улететь во внезапно разверзшуюся под Атлантой дыру. Тем не менее ни одно бизнеспланирование не обходится без прогноза. Мы делаем попытку спрогнозировать рост наилучшим образом, чтобы иметь возможность спланировать инфраструктуру и кадровое обеспечение. Не собираетесь же вы все время играть в догонялки!
330 Много цифр Как вы убедитесь на примере этой главы, можно не только попытаться предсказать будущее, но и выразить численно неопределенность всего, что связано с прогнозом. Численное выражение неопределенности с помощью создания интервалов прогнозирования поистине неоценимо, но часто игнорируется в прогностическом мире. Как сказал один гуру по прогнозированию, «хороший специалист не умнее остальных, просто его невежество лучше организовано». Так что давайте без лишних вступлений «организуем немного невежества»! Торговля мечами начата На минутку представьте себя ярым фанатом «Властелина Колец». Несколько лет назад, когда на основе трилогии вышел самый первый фильм, вы надели пару искусственных хоббичьих ножек и пошли стоять в очереди на первый полуночный показ. Затем вы стали посещать фестивали и бурно обсуждать на форумах, мог ли Фродо просто взять да полететь на орле к Роковой Горе. В какой-то момент вы решаете внести свой вклад в «хоббитовую реальность». Вы проходите в местном колледже курс металлообработки и начинаете ковать мечи. Ваш самый любимый меч из романа — Андурил, Пламя Запада. Вы становитесь экспертом в выковывании этих здоровенных палашей в самодельной кузнице и организуете их продажу на Amazon, eBay и Etsy. Ваши высказывания приобретают популярность у искушенных ботанов, бизнес идет в гору семимильными шагами. Раньше вам приходилось выискивать заказчиков с собственным материалом, поэтому вы решили спрогнозировать свой будущий спрос и вставить данные о предыдущих заказах в таблицу. Только откуда же взять данные о прошлых продажах, чтобы построить такой прогноз? В данной главе рассматривается набор прогностических техник под названием экспоненциальное сглаживание. На сегодняшний день это одни из простейших техник, имеющие широчайшее применение в бизнесе. Разумеется, я могу с ходу назвать несколько компаний из Fortune 500, которые строят свои прогнозы с помощью этих техник, потому что они известны точностью своих данных. Эта точность частично проистекает из простоты метода — переподгонке зачастую рассеянных данных из прошлого. Более того, с помощью этих методов значительно проще вычислить интервалы прогнозирования вокруг экспоненциально сглаженных прогнозов, что вам неизбежно придется делать.
8. Прогнозирование: дышите ровно, выиграть невозможно Знакомство с временной последовательностью данных ЗАМЕТКА Электронная таблица Excel, используемая в этой главе, — SwordForecasting.xlsm доступна для скачивания вместе с книгой на сайте www.wiley.com/go/datasmart. Эта таблица содержит все вводные данные на случай, если вы захотите с ними поработать — или можете просто следить за мной по заполненной таблице. Электронная таблица для этой главы содержит данные о торговле мечами за последние 36 месяцев, начиная с января. Данные записаны на листе Timeseries (рис. 8-1). Как уже отмечалось выше, данные типа этих — регулярные наблюдения с фиксированными временными интервалами — называются временными рядами данных. Временной ряд может быть любым в зависимости от конкретной задачи — идет ли речь об изменении численности населения за год или ежедневной динамике цен на газ. Рис. 8-1. Временной ряд данных 331
332 Много цифр В нашем случае мы имеем ежемесячный спрос на мечи, и первое, что вам нужно сделать, — это отобразить его графически, как показано на рис. 8-2. Чтобы вставить график, выделите столбцы А и В в Excel и выберите «Точечную диаграмму» из меню диаграмм Excel (вкладка «Диаграммы» в MacOS и «Вставить диаграмму» в Windows). Длину осей можно настроить, кликнув на них правой клавишей мышки и выбрав «Форматирование». Что же вы видите на рис. 8-2? Данные варьируются от 140 три года назад до 304 в прошлом месяце. За три года спрос удвоился — может быть, это тренд роста? Мы вернемся к этой мысли чуть позже. Рис. 8-2. Диаграмма временного ряда данных На графике есть несколько пиков и спадов, что может быть признаком некоторой сезонности. В частности, пики спроса приходятся на месяцы с номерами
8. Прогнозирование: дышите ровно, выиграть невозможно 12, 24 и 36, которые оказываются декабрями. Но может быть это лишь случайность или особенность тренда? Давайте выясним. Медленный старт с простым экспоненциальным сглаживанием Методы экспоненциального сглаживания основываются на прогнозировании будущего по данным из прошлого, где более новые наблюдения весят больше, чем старые. Такое взвешивание возможно благодаря константам сглаживания. Первый метод экспоненциального сглаживания, который мы опробуем, называется простым экспоненциальным сглаживанием (ПЭС, simple exponential smoothing, SES). Он использует лишь одну константу сглаживания. При простом экспоненциальном сглаживании предполагается, что ваш временной ряд данных состоит из двух компонентов: уровня (или среднего) и некоей погрешности вокруг этого значения. Нет никакого тренда или сезонных колебаний — есть просто уровень, вокруг которого «висит» спрос, тут и там окруженный небольшими погрешностями. Отдавая предпочтение более новым наблюдениям, ПЭС может явиться причиной сдвигов этого уровня. Говоря языком формул, Спрос в момент времени t = уровень + случайная погрешность около уровня в момент времени t Самое последнее приближение уровня служит прогнозом на будущие периоды времени. Если вы обсчитываете месяц 36, каким будет хорошее приближение на период 38? Самое последнее приблизительное значение уровня. А на 40? Уровень. Все просто — ведь это простое экспоненциальное сглаживание. Так как же найти приблизительное значение уровня? Если принять все временные значения как имеющие одинаковую ценность, то следует просто вычислить их среднее значение. Это среднее задаст вам уровень, и вы будете предсказывать будущее, говоря себе: «Будущий спрос — это средний спрос прошлого». Некоторые компании поступают именно так. Я видел ежемесячные прогнозы, в которых будущий спрос равнялся среднему за прошедшие месяцы последних нескольких лет. Плюс «поправочный коэффициент» смеха ради. Да-да, прогнозирование зачастую делается настолько криворуко, что даже крупные публичные компании до сих пор используют архаизмы вроде «поправочного коэффициента». Фу! Но когда уровень изменяется во времени, то нет нужды одинаково оценивать каждую точку прошлого, как при использовании среднего. Должны ли все 333
334 Много цифр данные с 2008 по 2013 год весить одинаково, чтобы спрогнозировать 2014-й? Возможно, но для большей части компаний, вероятно, это не так. Так что нам нужно приблизительное значение уровня, которое дает больший вес недавним наблюдениям спроса. Давайте вместо этого подумаем о расчете уровня, пройдясь по точкам данных по порядку и обновляя его по мере продвижения. Для начала решим, что исходное значение уровня — это среднее от нескольких последних точек данных. В этом случае выберите значения первого года. Назовите их исходным уровнем, уровень0: уровень0= среднее значение спроса за первый год (месяцы 1–12) Для спроса на мечи он равен 163. Теперь о том, как работает экспоненциальное сглаживание. Даже при том, что вы знаете спрос за месяцы с 1 по 36, вам нужно взять компоненты вашего самого последнего прогноза и использовать их для предсказания на месяц вперед с помощью полного ряда данных. Мы используем уровень0 (163) как прогноз спроса на месяц 1. Предсказав период 1, вы шагаете вперед во времени от периода 0 к периоду 1. Текущий спрос равен 165, то есть он вырос на 2 меча. Стоит обновить приближение исходного уровня. Уравнение простого экспоненциального сглаживаня выглядит так: уровень1 = уровень0 + несколько процентов × (спрос1 – уровень0) Обратите внимание, что (спрос1 – уровень0) — ошибка, которую вы получаете, когда предсказываете период 1 с использованием первоначального уровня. Шаг вперед: уровень2 = уровень1 + несколько процентов × (спрос2 – уровень1) И еще один: уровень3 = уровень2 + несколько процентов × (спрос3 – уровень2) Теперь выясним, сколько процентов погрешности вы готовы заложить в уровень — это будет константа сглаживания, и для уровня ее название — альфа (так исторически сложилось). Это может быть любое число от 0 до 100% (от 0 до 1). Если вы сделаете альфу равной 1, то получится, что погрешностью является все, означающее, что уровень текущего периода равен спросу на текущий период.
8. Прогнозирование: дышите ровно, выиграть невозможно Если сделать альфу равной 0, то в первом прогнозе уровня не останется совсем никакой коррекции погрешности. Наверное, нам нужно что-то между этими двумя крайностями, но выбирать лучшее значение альфы вы научитесь позже. Пока же проведите это вычисление для разных моментов времени: уровеньтекущий период = уровеньпредыдущий период + альфа × × (спростекущий период — уровень предыдущий период) В итоге вы имеете финальное приближение уровня — значение уровень36, где последние наблюдения спроса весят больше, потому что их поправки на погрешность не умножались с каждым следующим значением альфа: уровень36 = уровень35 + альфа × (спрос36 — уровень35) Это итоговое приближение уровня — то, что вы будете использовать как прогноз на будущие месяцы. Спрос за месяц 37? Ну, это просто уровень36. А как насчет месяца 40? Уровень36. Месяц 45? Уровень36. У вас есть картинка. Итоговое приближение уровня — просто лучшее из тех, что у вас есть на будущее, так что его вы и используете. Давайте взглянем на него в таблице. Настраиваем прогноз простого экспоненциального сглаживания Первое, что нужно сделать, — это создать новый лист в документе под названием SES. Вставьте временной ряд данных в столбцы А и В, начиная со строки 4, чтобы оставить немного места наверху для значений альфа. Вы можете ввести количество месяцев, которое у вас есть (36) в ячейку А2, а исходное значение альфа — в С2. Я начну с 0,5, потому что это число между 0 и 1 и оно мне нравится. Поместите расчет уровня в столбец С. Нужно вставить новую строку 5 во временной ряд данных вверху таблицы для исходного приближения уровня в момент времени 0. В С5 используйте следующий расчет: =AVERAGE(B6:B17) =СРЗНАЧ(B6:B17) Эти средние значения данных за первый год дают исходный уровень. Таблица с ними выглядит так, как показано на рис. 8-3. 335
336 Много цифр Рис. 8-3. Приблизительное значение исходного уровня для простого экспоненциального сглаживания Добавление одношагового прогноза и погрешности Теперь, когда вы добавили в последовательность значения первого уровня, можно идти вперед во времени с помощью формулы ПЭС, описанной в предыдущем разделе. Для этого добавьте еще два столбца: столбец одношагового прогноза (D) и погрешности прогноза (Е). Одношаговый прогноз за период времени 1 — это уровень0 (ячейка С5), а расчет погрешности — это разница текущего спроса и прогноза: =B6-D6 Приблизительное значение уровня за период 1 — это предыдущий уровень, с поправкой на альфу, умноженное на погрешность, то есть: =C5+C$2*E6 Обратите внимание, что у меня перед альфой стоит значок $, поэтому при распространении формулы на всю таблицу абсолютные ссылки на строку
8. Прогнозирование: дышите ровно, выиграть невозможно позволяют альфе оставаться собой. Таким образом получается лист, изображенный на рис. 8-4. Рис. 8-4. Генерация одношагового прогноза, погрешности и расчета уровня на период 1 Рястяните Вы будете смеяться, но сделано уже практически все. Просто растяните С6:Е6 вниз на все 36 месяцев и — вуаля! — у вас есть уровень. Добавим месяцы 37–48 в столбец А. Прогноз на следующие 12 месяцев — это просто уровень36. Так что в В42 можно добавить только =C$41 в качестве прогноза и оттянуть его на весь следующий год. Таким образом получается прогноз, равный 272, как показано на рис. 8-5. Но неужели нельзя сделать что-то получше? Сейчас наш способ оптимизации прогноза — установка значений альфы: чем альфа больше, тем меньше нам важны старые данные о спросе. Оптимизация одношаговой погрешности Точно так же, как вы оптимизировали сумму квадратов отклонений во время подгонки регрессии в главе 6, можно найти лучшую константу сглаживания для прогноза путем минимизации суммы квадратов отклонений (погрешностей) для прогнозирования предстоящего периода. 337
338 Много цифр Рис. 8-5. Прогноз простого экспоненциального сглаживания с альфой, равной 0,5 Добавим расчет квадрата отклонения в столбец F — это просто значение из столбца Е, возведенное в квадрат, — и растянем этот расчет на все 36 месяцев, а затем сложим их все в ячейке Е 2, чтобы получить сумму квадратов отклонений (СКО). Таким образом у нас получается лист, изображенный на рис. 8-6. Также в нашу таблицу нужно добавить само стандартное отклонение— в ячейку F2. Стандартное отклонение — это квадратный корень из СКО, разделенный на 35 (36 месяцев за вычетом количества сглаживающих параметров модели, которое для простого экспоненциального сглаживания равно 1). Стандартное отклонение — это приблизительное значение стандартного распределения для одношаговой погрешности (отклонения). Вы уже встречались с ним в главе 4. Это просто оценка распределения погрешности. Если ваша прогностическая модель отлично подогнана, то среднее значение погрешности будет 0. Это, скажем так, непредвзятый прогноз. Он настолько же преувеличивает спрос, насколько и преуменьшает. Стандартное отклонение численно выражает распределение вокруг 0, если прогноз непредвзятый.
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-6. Сумма квадратов отклонений для простого экспоненциального сглаживания В ячейке F2 стандартное отклонение вычисляется как: =SQRT(E2/(36–1) =КОРЕНЬ(E2/(36–1) Для альфы, равной 0,5, оно получается равным 20,94 (рис. 8-7). Вспомнив правило 68–95–99,7 из обсуждения нормального распределения в главе 4, вы поймете, что 68% погрешностей одношагового прогноза должны оказаться меньше 20,94 и больше –20,94. Теперь ваша задача — сжать это распределение насколько возможно, найдя подходящее значение альфы. Попробуйте несколько разных значений, используя «Поиск решения» в который раз в этой книге. Настройка «Поиска решения» для этой операции чрезвычайно проста. Откройте опцию, установите целевую функцию — стандартное отклонение в ячейке F2, и переменную решения — альфа в С2, добавьте ограничение, что С2 должна быть меньше 1, и поставьте галочку в поле, указывающем, что решение должно быть неотрицательным. Рекурсивные расчеты уровня, входящие в каждый расчет погрешности прогноза, очень нелинейны, поэтому для оптимизации альфы нам придется воспользоваться эволюционным алгоритмом. 339
340 Много цифр Рис. 8-7. Расчет стандартного отклонения Настройка «Поиска решения» должна выглядеть так, как показано на рис. 8-8. Нажав «Выполнить» вы получаете значение альфы, равное 0,73, что дает нам новое стандартное отклонение 20,39. Не такое уж кардинальное улучшение! Рис. 8-8. Настройка «Поиска решения» для оптимизации альфы
8. Прогнозирование: дышите ровно, выиграть невозможно А теперь графика! Лучший способ проверить наш прогноз — это нарисовать его диаграмму рядом с графиком данных о спросе в прошлом и посмотреть, как спрогнозированный спрос отличается от реального. Мне нравится вид простой диаграммы Excel. Для начала выберите А6:В41, где расположены наши исторические данные, и простую линейную диаграмму из вариантов, предложенных Excel. Добавив график, кликните на нем правой кнопкой мыши, выберите «Выбрать данные» и вставьте туда новую серию свежепредсказанных значений А42:В53. Если хотите, добавьте также названия осей, после чего у вас получится что-то похожее на рис. 8-9. Рис. 8-9. Диаграмма итогового прогноза простого экспоненциального сглаживания Возможно, у вас есть тренд Достаточно беглого взгляда на этот график, чтобы понять несколько вещей. Вопервых, простое экспоненциальное сглаживание — это прямая линия, уровень. Но если посмотреть на данные о спросе за прошедшие 36 месяцев, то окажется, что он поднялся. Похоже на восходящий тренд, особенно в конце. Наши глаза, определенно, не врут, но все же как это доказать? Для доказательства достаточно подогнать линейную регрессию под данные спроса и выполнить тест на соответствие критерию Стьюдента на подъеме этой линии тренда, в точности как в главе 6. 341
342 Много цифр Если уклон линии ненулевой и статистически значимый (в проверке по критерию Стьюдента величина р менее 0,05), то можете быть уверены: у данных есть тренд. Если в последнем предложении вы не видите никакого смысла, загляните в раздел главы 6 о статистических тестах. Переключитесь во вкладку Timeseries вашей электронной таблицы для выполнения проверки тренда. В главе 6 я испытывал ваш характер, заставляя выполнять проверки критериев Стьюдента и Фишера вручную. Но я не зверь, чтобы подвергать вас этому испытанию вторично. В этой главе для подгонки линейной регрессии, а также для проверки уклона, расчета стандартного отклонения коэффициента уклона и количества степеней свободы (если не понимаете эти термины — загляните в главу 6) мы будем использовать функцию LINEST/ЛИНЕЙН, встроенную в Excel. Затем можно будет рассчитать статистику Стьюдента и пропустить ее через функцию TDIST/ СТЬЮДРАСП, как описано в главе 6. Если вы никогда раньше не пользовались функцией LINEST/ЛИНЕЙН, ознакомьтесь со справочным материалом Excel по этой функции. Вы задаете LINEST/ ЛИНЕЙН данные зависимых переменных (спроса в столбце В) и независимых (у вас только одна независимая переменная, и это — время в столбце А). Отметив «Истина», вы даете функции понять, что свободный член надо подгонять как часть линии регрессии, и еще раз — чтобы получить детализированный отчет по стандартному отклонению и R-квадрату. После этого линейную регрессию на листе Timeseries можно запустить следующим образом: =LINEST(B2:B37,A2:A37,TRUE,TRUE) =ЛИНЕЙН(B2:B37,A2:A37,ИСТИНА,ИСТИНА) Эта формула вернет уклон линии регрессии, потому что LINEST/ЛИНЕЙН — формула массива. LINEST/ЛИНЕЙН возвращает всю статистику регрессии в массиве, чтобы вытряхнуть все содержимое в выбранную область таблицы. Вы также можете воспользоваться формулой INDEX/ИНДЕКС для LINEST/ЛИНЕЙН, чтобы вытащить только интересующие вас значения одно за другим. Например, первые компоненты линии регрессии, которые выдает LINEST/ЛИНЕЙН, — это коэффициенты регрессии, так что можно рассчитать уклон регрессии в ячейке В39 таблицы Timeseries, пропуская LINEST/ЛИНЕЙН через INDEX/ ИНДЕКС: =INDEX(LINEST(B2:B37,A2:A37,TRUE,TRUE),1,1) =ИНДЕКС(ЛИНЕЙН(B2:B37,A2:A37,ИСТИНА,ИСТИНА),1,1)
8. Прогнозирование: дышите ровно, выиграть невозможно Получается уклон, равный 2,54, что означает тренд линии регрессии к повышению спроса на 2,54 дополнительных меча в месяц. То есть уклон действительно есть. Но значим ли он статистически? Чтобы проверить уклон критерием Стьюдента, нужно узнать стандартное отклонение уклона и количество степеней свободы регрессии. LINEST/ЛИНЕЙН помещает значения стандартного отклонения в строку 2, столбец 1 массива результатов. К примеру, в В40 вы можете это написать как: =INDEX(LINEST(B2:B37,A2:A37,TRUE,TRUE),2,1) =ИНДЕКС(ЛИНЕЙН(B2:B37,A2:A37,ИСТИНА,ИСТИНА),2,1) Единственное отличие от вычисления уклона заключается в том, что вместо ряда 1 столбца 1 мы задаем формуле INDEX/ИНДЕКС строку 2 столбец 1 и находим стандартное отклонение. Стандартное отклонение уклона получается равным 0,34. Таблица на этом этапе показана на рис. 8-10. Рис. 8-10. Уклон и стандартное отклонение линии регрессии, подогнанное под исторический спрос Точно так же функция LINEST/ЛИНЕЙН знает, что степени свободы регрессии помещены в строку 4 столбца 2 итогового массива. Поэтому в В41 их можно вычислить следующим образом: =INDEX(LINEST(B2:B37,A2:A37,TRUE,TRUE),4,2) =ИНДЕКС(ЛИНЕЙН(B2:B37,A2:A37,ИСТИНА,ИСТИНА),4,2) У вас должно получиться 34 степени свободы (как отмечено в главе 6, они рассчитываются как 36 точек данных минус 2 коэффициента линейной регрессии). 343
344 Много цифр Теперь известны все три значения для проверки критерием Стьюдента статистической значимости вашего подогнанного тренда. Так же, как и в 6 главе, вы можете вычислить статистику этого критерия как абсолютную величину уклона, разделенную на стандартное отклонение уклона. Рассчитайте величину р для этой статистики из распределения Стьюдента с 34 степенями свободы, воспользовавшись функцией TDIST/СТЬЮДРАСП в В42: =TDIST(ABS(B39/B40),B41,2) =СТЬЮДРАСП(ABS(B39/B40),B41,2) Функция выдает значение р, близкое к 0, намекая на то, что если бы тренд был не существующим в реальности (уклон 0), то ни при каких условиях мы бы не получили настолько отличающийся от регрессии уклон. Это показано на рис. 8-11. Рис. 8-11. Ваш тренд существует! Поздравляю! У вас есть тренд. Осталось включить его в прогноз. Экспоненциальное сглаживание Холта с корректировкой тренда Экспоненциальное сглаживание Холта с корректировкой тренда распространяет простое экспоненциальное сглаживание на создание прогноза из данных, имеющих линейный тренд. Часто оно называется двойным экспоненциальным сглаживанием, потому что в отличие от простого ЭС, имеющего один параметр
8. Прогнозирование: дышите ровно, выиграть невозможно сглаживания — альфа, и один компонент, не являющийся отклонением, двойное экспоненциальное сглаживание имеет их два. Если у временной последовательности линейный тренд, то его можно записать так: спрос за время t = уровень+ t × тренд + случайное отклонение уровня в момент времени t Самое последнее приближение уровня и тренда (умноженные на количество периодов) служит прогнозом на грядущие периоды времени. Если сейчас месяц 36, то каким будет хорошее приближение спроса на период 38? Приближение последнего периода времени плюс два месяца тренда. Не настолько просто, как ПЭС, но близко. Теперь, как и в простом экспоненциальном сглаживании, вам нужно получить несколько исходных приближений значений уровня и тренда, которые мы обозначим уровень0 и тренд0. Один из простейших способов их найти — это просто изобразить на графике первую половину ваших данных о спросе и определить линию тренда (как мы делали в главе 6 в примере с аллергией на кошек). Уклон этой линии — тренд0, а у-начальный отрезок (свободный член) — уровень0. Экспоненциальное сглаживание Холта с корректировкой тренда имеет два новых уравнения, одно — для уровня по мере его продвижения во времени, а другое — собственно тренд. Уравнение уровня также содержит сглаживающий параметр под названием альфа, а в уравнении тренда используется параметр, часто называемый гамма. Они абсолютно одинаковые — просто значения от 0 до 1, регулирующие вмешательство погрешности одношагового прогноза в дальнейшие расчеты приближений. Вот как выглядит новое уравнение уровня: уровень1 = уровень0 + тренд0 + альфа × (спрос1 – (уровень0 + тренд0)) Обратите внимание, что уровень0 + тренд0— это просто одношаговый прогноз от исходных значений к месяцу 1, поэтому (спрос1 – (уровень0 + тренд0)) — это одношаговое отклонение. Это уравнение очень похоже на уравнение уровня из ПЭС, за исключением того, что считается значение тренда за один период, когда бы вы ни рассчитывали следующий шаг. Таким образом, основное уравнение приближения уровня будет следующим: уровень текущий период= уровень предыдущий период + тренд предыдущий период + альфа × × (спрос текущий период – (уровень предыдущий период + трендпредыдущий период)) 345
346 Много цифр Для этой новой техники сглаживания нам понадобится новое уравнение обновления тренда. Для первого шага оно будет таким: тренд1= тренд0 + гамма × альфа × (спрос1 – (уровень0 + тренд0)) То есть уравнение тренда очень похоже на уравнение обновления уровня. Берется предыдущее приближение тренда и изменяется на гамму, умноженную на размер отклонения, заложенного в соответствующее обновление уровня (которое имеет интуитивный смысл, потому что только некоторые из отклонений, используемых для изменения уровня, можно отнести к небольшим или скачкообразным приближениям тренда). Таким образом основное уравнение приближения тренда такое: трендтекущий период = трендпредыдущий период + гамма × альфа × × (спрос текущий период – (уровень предыдущий период + трендпредыдущий период)) Настройка холтовского сглаживания с коррекцией тренда в электронной таблице Для начала создайте новый лист под названием Holt’s Trend-Corrected. Затем, как и в случае с таблицей простого экспоненциального сглаживания, скопируйте в строку 4 временной ряд данных и вставьте пустую строку 5 для исходных приближений. Столбец С снова будет содержать приближения уровня, а столбец D — приближения тренда. Наверху в этих столбцах находятся значения альфы и гаммы. Вы оптимизируете их «Поиском решения» за секунду, но сейчас пусть они будут около 0,5. Так получается таблица, изображенная на рис. 8-12. А для исходных значений уровня и тренда в С5 и D5 мы построим график за первые 18 месяцев и добавим в него линию тренда с уравнением (если вы не знаете, как добавить на график линию тренда, обратитесь к главе 6). Так мы получаем исходное значение тренда 0,8369 и исходный уровень (свободный член линии тренда), равный 155,88. Добавив данные в D5 и С5 соответственно, получаем лист, изображенный на рис. 8-13. Теперь добавьте в столбцы E и F столбцы прогноза и погрешности прогноза на один шаг вперед. Если посмотреть на строку 6, одношаговый прогноз получается примерно равным предыдущему уровню, к которому прибавлен тренд за один месяц с помощью предыдущего приближения — это С5+D5. Погрешность прогноза вычисляется так же, как и в случае простого экспоненциального сглаживания: F6 — это просто текущий спрос, из которого вычтен одношаговый прогноз — В6–Е6.
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-12. Начинаем с параметрами сглаживания 0,5 Рис. 8-13. Исходные значения уровня и тренда 347
348 Много цифр Теперь вы можете обновить значение уровня в ячейке С6 — оно будет равно предыдущему значению, к которому прибавлен предыдущий тренд и альфа, умноженная на погрешность: =C5+D5+C$2*F6 Тренд в D6 обновляется точно так же, только нужно еще прибавить гамму, умноженную на альфу, умноженную на погрешность: =D5+D$2*C$2*F6 Обратите внимание на следующую деталь: необходимо использовать абсолютные ссылки на альфу и гамму, чтобы была возможность растянуть формулу на целые столбцы. Сделайте это прямо сейчас — растяните С6:F6 вниз до месяца 36. Операция показана на рис. 8-14. Рис. 8-14. Растягивание расчетов уровня, тренда, прогноза и погрешности Прогнозируем будущее Чтобы прогнозировать дальше, чем на 36 месяцев, добавьте итоговый уровень (который для альфы и гаммы, равных 0,5, будет равняться 281) к количеству месяцев после 36-го, на которые вы хотите рассчитать прогноз, умноженному на итоговое приближение тренда. Вы можете подсчитать количество месяцев от 36 до нужного вам, вычтя один месяц в столбце А из другого.
8. Прогнозирование: дышите ровно, выиграть невозможно К примеру, для прогноза месяца 37 в ячейке В42 вы будете пользоваться такой формулой: =C$41+(A42-A$41)*D$41 С помощью абсолютных ссылок на месяц 36, итоговый тренд и итоговый уровень, прогноз можно растянуть вниз до месяца 48, что показано на рис. 8-15. Рис. 8-15. Прогнозы на будущие месяцы, сделанные методом экспоненциального сглаживания Холта с коррекцией тренда Как и в таблице простого экспоненциального сглаживания, здесь можно построить график исторического спроса и прогноза как двух серий данных на одной простой координатной плоскости, как показано на рис. 8-16. При альфе и гамме, равных 0,5, прогноз, конечно, выглядит немного странно. Начиная с конца последнего месяца он внезапно возрастает, гораздо быстрее, чем ранее. Похоже, стоит оптимизировать параметры сглаживания. 349
350 Много цифр Рис. 8-16. График прогноза со значениями альфа и гамма по умолчанию Оптимизация одношаговой погрешности Точно так же, как и в случае с простым экспоненциальным сглаживанием, здесь нужно добавить квадрат погрешности прогноза в столбец G. В F2 и G2 можно рассчитать сумму квадратов погрешностей (отклонений) и стандартное отклонение для одношагового прогноза, в точности как и раньше. За исключением того, что в этот раз у модели два параметра сглаживания, так что придется разделить эту сумму на 36–2 перед извлечением из нее корня: =SQRT(F2/(36–2)) =КОРЕНЬ(F2/(36–2)) Так получается лист, изображенный на рис. 8-17. Настройки оптимизации идентичны таковым в простом экспоненциальном сглаживании. Единственное отличие — в этот раз вы оптимизируете оба параметра, альфу и гамму, вместе, как показано на рис. 8-18. После запуска «Поиска решения» вы получите оптимальное значение альфы, равное 0,66, и гаммы, равное 0,05. Оптимальный прогноз показан на графике на рис. 8-19.
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-17. Расчет суммы квадрата погрешности и стандартного отклонения Рис. 8-18. Настройки оптимизации для экспоненциального сглаживания Холта с корректировкой тренда 351
352 Много цифр Рис. 8-19. График оптимального холтовского прогноза Тренд, который вытекает из вашего прогноза, — это пять дополнительных мечей, проданных за месяц. Этот тренд дублирует уже найденный вами ранее в предыдущей таблице, потому что сглаживание с корректировкой тренда ценит более поздние данные выше, и в этом случае спрос за недавнее время оказывается более «трендовым». Обратите внимание, что этот прогноз начинается очень близко к прогнозу ПЭС для месяца 37–290 против 292. Но довольно быстро прогноз с корректировкой тренда начинает расти вместе с трендом, как вы и предполагали. Так мы закончили? Взгляд на автокорелляции Все ли возможное мы сделали? Все ли учли? Есть один способ испытать вашу прогностическую модель на прочность — проверить погрешности одного шага вперед. Если эти отклонения случайны, то вы хорошо поработали. Но если найдется спрятанная в них закономерность — что-то вроде повторяющегося поведения на регулярных интервалах — возможно, в данных о спросе есть сезонный фактор, который мы не учли. Под закономерностью я понимаю следующее: если взять погрешность и поместить ее рядом с ней же, но взятой за следующий месяц, или через два месяца, или даже 12 — будет ли она меняться синхронно? Эта концепция погрешности, коррелирующей с собственной версией за другой период, называется автокорреляцией («авто-» по-гречески означает «само-». Отличная, кстати, приставка для слива лишних гласных в «Эрудите»).
8. Прогнозирование: дышите ровно, выиграть невозможно Так что начнем с создания нового листа под названием Holt’s Autocorrelation. Вставьте туда месяцы с 1 по 36 вместе с их одношаговыми погрешностями из холтовского прогноза — в столбцы А и В. Под погрешностями в В38 рассчитайте среднюю погрешность. Получившийся лист показан на рис. 8-20. Рис. 8-20. Месяцы и ассоциированные с ними одношаговые погрешности В столбце С рассчитайте отклонения каждой погрешности в столбце В от среднего в В38. Эти отклонения одношаговых погрешностей от средней — то «пространство», где закономерности могут поднимать свои страшненькие головы. К примеру, возможно, что каждый декабрь погрешность прогноза значительно больше средней — и такая сезонная закономерность обнаружится в этих цифрах. Итак, в С2 рассчитаем отклонение погрешности в В2 от средней: =B2-B$38 Затем можно растянуть эту формулу вниз, чтобы получить все отклонения. В ячейке С38 рассчитаем сумму квадратов отклонений: =SUMPRODUCT($C2:$C37,C2:C37) =СУММПРОИЗВ($C2:$C37,C2:C37) Так получается таблица, изображенная на рис. 8-21. 353
354 Много цифр Рис. 8-21. Сумма квадратов отклонений от средней погрешности холтовского прогноза Теперь поместим в столбец D отклонения погрешностей со сдвигом на месяц. Назовите столбец D «1». Ячейку D2 можете оставить пустой, а в D3 поместить =С2 А теперь просто растяните эту формулу до D37, оказавшегося равным С36. Таким образом получается таблица, изображенная на рис. 8-22. Рис. 8-22. Отклонения погрешностей со сдвигом на 1 месяц
8. Прогнозирование: дышите ровно, выиграть невозможно Чтобы сдвинуть отклонения на 2 месяца, просто выделите D1:D37 и перетяните в столбец Е. Точно так же можно сдвинуть погрешности на 12 месяцев — просто протащить выделенную область до столбца О. Элементарно! У вас получилась каскадная матрица сдвинутых отклонений погрешности, как показано на рис. 8-23. Теперь, имея эти сдвиги, подумайте о том, что может значить для одного из этих столбцов «синхронное движение» со столбцом С. Возьмем, к примеру, сдвиг на 1 месяц в столбце D. Если эти два столбца синхронны, то число, отрицательное в одном из них, должно быть отрицательно и в другом. Собственно, и положительное должно быть таковым в обоих столбцах. Это означает, что произведение двух столбцов в результате будет иметь много положительных значений (отрицательное значение, умноженное на отрицательное, дает положительное, как и положительное, умноженное на положительное). Рис. 8-23. Прекрасно подогнанная каскадная матрица сдвинутых отклонений погрешности 355
356 Много цифр Сложите эти произведения. Чем ближе окажется сумма (SUMPRODUCT/СУММПРОИЗВ) столбца со сдвигом исходных отклонений к сумме квадратов отклонений в С38, тем более синхронны, более коррелированы сдвинутые погрешности будут к исходным. Также вы можете получить негативную автокорелляцию, в которой сдвинутые отклонения становятся отрицательными, независимо от того, положительны исходные значения или отрицательны. SUMPRODUCT/СУММПРОИЗВ в этом случае будет довольно большим отрицательным числом. Начнем с растягивания формулы SUMPRODUCT($C2:$C37,C2:C37)/ СУММПРОИЗВ($C2:$C37,C2:C37) в ячейке С38 вправо до столбца О. Обратите внимание на то, как абсолютная ссылка на столбец С сохраняет его на месте. У вас появляется SUMPRODUCT/СУММПРОИЗВ каждого столбца со сдвигом и исходного столбца, как показано на рис. 8-24. Рис. 8-24. SUMPRODUCT/СУММПРОИЗВ сдвинутых отклонений и исходных значений Теперь рассчитайте автокорреляцию данных со сдвигом на месяц: SUMPRODUCT/СУММПРОИЗВ отклонений сдвига, разделенная на сумму квадра- тов отклонений в С38. Для примера можно рассчитать автокорреляцию сдвига на один месяц в ячейке С40: =D38/$C38 Растянув ее по горизонтали, можно получить автокорреляцию для каждого сдвига.
8. Прогнозирование: дышите ровно, выиграть невозможно Теперь выделите D40:О40 и вставьте столбчатую диаграмму, как показано на рис. 8-25 (кликните правой клавишей мышки на серии данных и отформатируйте их, чтобы столбики диаграммы стали прозрачнее и номера месяцев лучше читались под осью). Эта столбчатая диаграмма называется коррелограммой, (круто, да?). Она показывает автокорреляции для каждого сдвига на месяц до самого конца года. Рис. 8-25. Это моя коррелограмма. Все коррелограммы похожи, но это моя Какие автокорреляции нам важны? Как правило, все автокорреляции, большие, чем 2/корень из количества точек данных, что в нашем случае будет 2/√36 = 0,333. Также нас интересуют отрицательные автокорреляции меньше –0,333. Посмотрите на эту диаграмму автокорреляций, находящихся выше и ниже критических значений. В прогнозировании на коррелограмме принято изображать критические значения пунктирной линией. Из любви к красивым картинкам я, так и быть, покажу, как это сделать здесь. В ячейку D42 добавьте =2/SQRT(36)/=2/КОРЕНЬ(36) и растяните вправо до столбца О. В D43 сделайте то же самое, только с отрицательным значением: 357
358 Много цифр =–2/SQRT(36)/=–2/КОРЕНЬ(36) и тоже растяните вправо до О. Так получаются критические точки автокорреляций, показанные на рис. 8-26. Рис. 8-26. Критические точки автокорреляций Кликните правой клавишей мышки на столбчатой диаграмме и выберите «Выбрать данные». В выплывшем окошке нажмите кнопку «Добавить», чтобы создать новые серии данных. Для первой из них выберите промежуток D42:О42 для оси у. А для второй — D43:О43. Это добавит новые столбцы на диаграмму. Правый щелчок на каждой из этих новых серий столбцов даст возможность изменить тип отображения данных на линейную диаграмму. Затем кликните правой кнопкой мыши на эти линии и выберите «Формат данных». Переключитесь на линию (тип линии в некоторых версиях Excel) в выплывшем окне. Здесь вы можете сделать свою линию пунктирной, как показано на рис. 8-27. Таким образом получается коррелограмма с пунктирными критическими значениями. Она изображена на рис. 8-28. И что же мы видим? Совершенно точно есть одна автокорреляция выше критического значения, и это 12 месяцев. Погрешность, сдвинутая на год, коррелирует сама с собой. Это означает 12-месячный сезонный цикл. И это неудивительно. Если вы посмотрите на график спроса во вкладке Timeseries, то окажется, что есть пики спроса на каждое Рождество и провалы в апреле-мае. Вам нужна такая техника прогнозирования, которая способна учитывать сезонность. Кроме того, существует аналогичная техника экспоненциального сглаживания.
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-27. Изменение отображения критических значений со столбцов на пунктир Рис. 8-28. Коррелограмма с критическими значениями 359
360 Много цифр Мультипликативное экспоненциальное сглаживание Холта–Винтерса Мультипликативное экспоненциальное сглаживание Холта–Винтерса является логическим продолжением сглаживания Холта с корректировкой тренда. Оно учитывает уровень, тренд и необходимость подгонки спроса вверх или вниз на регулярной основе «в угоду» сезонным флуктуациям. Сезонные колебания не обязательно имеют годовой цикл, как в нашем примере. В случае MailChimp мы имеем периодические колебания спроса каждый четверг (похоже, четверг считается отличным днем для отправки маркетинговых писем). С помощью Холта–Винтерса мы можем учесть этот недельный цикл. В большинстве случаев вы не можете просто взять и прибавить или отнять от спроса какую-либо фиксированную сезонную величину ради подгонки прогноза. Если ваш бизнес растет от продаж в 200 мечей до 2000 каждый месяц, добавление 20 штук в модель в качестве подгонки под рождественский всплеск спроса — не очень хорошая идея. Нет, сезонные изменения обычно должны быть результатом умножения. Вместо прибавления 20 мечей, возможно, стоило бы умножить прогноз на 120%. Вот почему метод называется мультипликативным (от multiplicate — умножать). Вот как этот прогноз представляет себе спрос: Спрос в момент t = (уровень + t × тренд) × сезонная поправка для момента t × все оставшиеся нерегулярные поправки, которые мы не можем учесть Таким образом, теперь у вас есть структура тренда и уровня, идентичная той, что была в холтовском сглаживании с корректировкой тренда. А поскольку мы не в силах учесть нерегулярные колебания спроса, такие как божья воля, то не станем и пытаться. Сглаживание Холта–Винтерса также называют тройным экспоненциальным сглаживанием, потому что, как вы, наверно, сами догадались, у него три сглаживающих параметра. Здесь, кроме, знакомых нам альфы и гаммы, также присутствует сезонный фактор с обновленным уравнением. Он называется дельта. Три уравнения корректировки погрешности немного сложнее, чем то, с чем вы ранее имели дело, но есть и много общего. Перед тем, как начать, я хочу прояснить одну вещь. Вы использовали уровни и тренды предыдущего периода, чтобы предсказать и скорректировать следующий, — но при сезонных корректировках можно на него и не оглядываться. Нас больше интересует приближение фактора корректировки для конкретной точки цикла. В нашем случае это на 12 периодов раньше.
8. Прогнозирование: дышите ровно, выиграть невозможно Это значит, что если сейчас месяц 36 и вы прогнозируете на 3 следующих месяца, до 39, то прогноз будет выглядеть так: Прогноз на месяц 39 = (уровень36 + 3 × тренд36) × сезонность27 Да-да, все верно, там написано сезонность27. Это самое последнее приближение сезонной корректировки для марта. Нельзя использовать сезонность36, потому что это — декабрь. Покопаемся в обновлениях уравнений, начиная с этого уровня. Теоретически вам нужен только исходный уровень0 и тренд0, но на самом деле потребуется двенадцать исходных сезонных факторов, от сезонности–11 до сезонности0. К примеру, обновленное уравнение для уровня1 основано на исходном сезонном приближении для января: уровень1= уровень0 + тренд0+ альфа × (спрос1 –(уровень0 + тренд0) × × сезонность–11) /сезонность–11 В этом расчете уровня многие компоненты вам знакомы. Текущий уровень — это предыдущий уровень плюс предыдущий тренд (точно так же, как и в двойном экспоненциальном сглаживании) плюс альфа, умноженная на одношаговую погрешность (спрос1 – (уровень0 + тренд0) × сезонность–11), где погрешность получает сезонную корректировку, будучи разделенной на сезонность–11. Таким образом мы продвигаемся вперед во времени, и следующий месяц будет выглядеть так: уровень2= уровень1 + тренд1+ альфа × (спрос2 – (уровень1 + тренд1) × × сезонность–10)/сезонность–10 Общий уровень будет иметь такую формулу для расчета: уровеньтекущий период = уровеньпредыдущий период + трендпредыдущий период + альфа × × (спростекущий период – (уровеньпредыдущий период + трендпредыдущий период) × × сезонностьпоследний релевантный период ) / сезонностьпоследний релевантный период Тренд обновляется соответственно уровню в точности так же, как и при двойном экспоненциальном сглаживании: трендтекущий период = трендпредыдущий период + гамма + альфа × × (спростекущий период – (уровеньпредыдущий период + трендпредыдущий период ) × × сезонностьпоследний релевантный период ) / сезонностьпоследний релевантный период 361
362 Много цифр Как и при двойном экспоненциальном сглаживании, текущий тренд — это предыдущий тренд плюс гамма, умноженная на погрешности, включенные в уравнение обновления уровня. А теперь — уравнение обновления сезонного фактора. Оно не похоже на уравнение обновления тренда, разве что корректирует последний релевантный сезонный фактор с помощью дельты, умноженной на погрешность, которую обновления уровня и тренда игнорировали: сезонностьтекущий период = сезонностьпоследний релевантный период + + дельта × (1 – альфа) × (спростекущий период – (уровеньпредыдущий период + + трендпредыдущий период ) × сезонностьпоследний релевантный период) / (уровеньпредыдущий период + + тренд предыдущий период) В этом случае вы не только обновляете корректировку сезонности соответствующим фактором за 12 предшествующих месяцев, но также и вкладываете в нее дельту, умноженную на все неучтенные погрешности, валяющиеся обрезками на полу мастерской после обновления уровня. Обратите внимание: вместо того, чтобы сезонно корректировать погрешность, вы делите на значения предыдущего уровня и тренда. С помощью «корректировки уровня и тренда» одношаговой погрешности вы помещаете погрешность в ту же шкалу множителей, что и сезонные факторы. Установка исходных значений уровня, тренда и сезонности Установка исходных значений для ПЭС и двойного экспоненциального сглаживания происходила проще простого. Но теперь вам нужно выяснить, что в серии данных является трендом, а что — сезонностью. Установка исходных значений для этого прогноза (одного уровня, одного тренда и 12 сезонных корректирующих факторов) в этот раз немного труднее. Существуют простые (и неверные!) способы провести ее. Я покажу вам правильный метод инициализации Холта–Винтерса, при том что ваши исторические данные имеют как минимум объем в два сезонных цикла. В нашем случае есть объем данных в три цикла. Вот что нужно сделать: Сгладить исторические данные методом скользящего среднего 2 × 12. • Сравнить сглаженную версию временного ряда данных с оригиналом, чтобы • получить приблизительную оценку сезонности. С помощью исходных приближений сезонности десезонировать истори• ческие данные.
8. Прогнозирование: дышите ровно, выиграть невозможно Найти приближения уровня и тренда с помощью линии тренда десезони• рованных данных. Для начала создайте новый лист и назовите его HoltWintersInitial. Затем вставьте в первые два столбца временную серию данных. Теперь нужно сгладить некоторые из этих данных с помощью скользящего среднего. Так как сезонность рассчитывается у нас в 12-месячных циклах, имеет смысл использовать среднее за 12 месяцев. Что значит скользящее среднее за 12 месяцев? Для расчета вы берете спрос за конкретный месяц и спрос за периоды до и после, и вычисляете среднее значение. Так утрамбовываются все странные всплески в серии. Но со скользящим средним за 12 месяцев есть проблема. 12 — четное число. Если вы сглаживаете спрос за месяц 7, стоит ли считать его средним спросом с 1-го по 12-й месяц или со 2-го по 13-й? Иначе говоря, месяц 7 не совсем в середине. Середины нет! Чтобы справиться с этим затруднением, нужно сгладить спрос с помощью «скользящего среднего 2 × 12», что является средним значением обоих вариантов — месяцев с 1 по 12 и со 2 по 13. (То же самое относится к любому четному числу временных периодов цикла. Если в вашем цикле нечетное количество периодов, часть «2×» скользящего среднего вам не нужна и вы можете вычислить простое скользящее среднее.) А теперь обратите внимание: для первых шести месяцев данных и для шести последних такие вычисления вообще не представляются возможными. У вас нет данных за 6 месяцев ни с какой стороны. Все, что вы можете — это сгладить месяцы из середины последовательности данных (в нашем случае месяцы 7–30). Именно поэтому вам нужна последовательность данных длиной как минимум два года — чтобы в итоге сглаживать данные за год. Таким образом, можно использовать эту формулу начиная с месяца 7: =(AVERAGE(B3:B14)+AVERAGE(B2:B13))/2 =(СРЗНАЧ(B3:B14)+СРЗНАЧ(B2:B13))/2 Это среднее значение месяца 7 с 12 месяцами до и после него, за исключением того, что месяцы 1 и 13 учитываются как половина остальных месяцев. Такой учет имеет определенный смысл: так как эти месяцы, 1 и 13, приходятся на один и тот же календарный месяц, то, если бы мы считали каждый из них как один, в вашем среднем оказалось бы слишком много данных за январь. Растягивая эту формулу вниз до месяца 30 и помещая на простую линейную диаграмму и сглаженные данные, и оригинал, вы получаете лист, изображенный 363
364 Много цифр на рис. 8-29. На своей диаграмме я назвал их сглаженными (smoothed) и несглаженными (unsmoothed). После взгляда на сглаженную линию становится очевидным, что любые сезонные изменения, имеющиеся в данных, сглажены. Теперь в столбце D разделите оригинальную величину на сглаженную и получите приблизительное значение сезонной поправки. В8/С8 Полученную комбинацию растяните вниз до месяца 30. Обратите внимание на всплески в 20% выше нормального спроса в месяцах 12 и 24 (декабрь), в то время как весной наблюдаются провалы. Рис. 8-29. Сглаженные данные спроса Эта техника сглаживания дала вам две (для каждого фактора сезонности) точечные оценки. Давайте узнаем среднее значение этих двух факторов в столбце Е, что будет исходным сезонным фактором для Холта–Винтерса.
8. Прогнозирование: дышите ровно, выиграть невозможно Например, в Е2, где находятся данные за январь, нужно взять среднее от двух значений спроса за январь из столбца D, ячеек D8 и D26. Так как сглаженные данные в столбце D начинаются от середины года, то растянуть формулу среднего нельзя. В Е8, где находятся данные за июль, нужно брать среднее от D8 и D20, к примеру. Когда все эти 12 корректировок будут у вас в столбце Е, можно вычесть единицу из каждого из них в столбце F и отформатировать ячейки в проценты (выделить их и правым щелчком мыши вызвать меню, в котором выбрать «Формат ячеек»), чтобы увидеть, как эти факторы двигают спрос вверх или вниз каждый месяц. Вы можете даже вставить столбчатую диаграмму этих значений в таблицу, как показано на рис. 8-30. Рис. 8-30. Столбчатая диаграмма приблизительных сезонных колебаний Теперь, когда у вас есть эти исходные сезонные корректировки, можно использовать их для десезонализации временной последовательности данных. 365
366 Много цифр Когда вся серия будет десезонализирована, можно провести через нее линию тренда, а затем использовать уклон и свободный член в качестве начального отрезка и тренда. Для начала вставьте соответствующие значения сезонных корректировок за каждый месяц от G2 до G37. Фактически вы вставляете Е2:Е13 три раза подряд в столбец G (убедитесь, что вы вставляете только значения). В столбце Н разделите исходную серию данных из столбца В на сезонные факторы из столбца G, чтобы удалить приблизительный сезонный фактор из данных. Эта таблица показана на рис. 8-31. Теперь, как и на предыдущих листах, вам нужно вставить диаграмму столбца Н и провести на ней линию тренда. Отобразив уравнение этой линии на графике, вы получите исходное приближение тренда, равное 2,29 дополнительных проданных мечей в месяц, и исходное приближение уровня, равное 144,42 (рис. 8-32). Рис. 8-31. Десезонированная серия данных
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-32. Исходные приближения уровня и тренда относительно линии тренда в десезонированной серии Приступим к прогнозу Теперь, когда у вас есть исходные значения всех параметров, настало время создать новый лист под названием HoltWintersSeasonal, в строку 4 которого для начала нужно вставить серию данных, точно так же, как и в двух рассмотренных выше методах прогнозирования. В столбцах C, D и E рядом с этой серией расположатся уровень, тренд и сезонные значения соответственно. Но на этот раз, в отличие от двух предыдущих, где нам нужно было вставить только одну пустую строку 5, мы вставляем пустые строки с 5 по 16 и нумеруем их по месяцам относительно текущего — от –11 до 0 в столбце А. Затем исходные значения из предыдущего листа можно вставить в соответствующие ячейки, как показано на рис. 8-33. В столбце F вы делаете одношаговый прогноз. Для периода 1 он равен предыдущему уровню в С16, сложенному с предыдущим трендом в D16. Но они оба скорректированы соответствующими приближениями сезонности 12-ю строками выше в Е5. Таким образом, в F17 записано следующее: =(C16+D16)*E5 Погрешность прогноза в G17 может быть рассчитана как =B17-F17 367
368 Много цифр Рис. 8-33. Все исходные значения Холта–Винтерса в одном месте Теперь вы готовы рассчитывать уровень, тренд и сезонность, шагая вперед. Таким образом в ячейках С2:Е2 располагаются значения альфа, гамма и дельта (как обычно, я начну с 0,5). Эта таблица показана на рис. 8-34. Первое, что вы будете рассчитывать, двигаясь вперед во времени, — это новое приближение уровня для текущего периода: для периода 1 в ячейке С17 расчет будет таким: =C16+D16+C$2*G17/E5 Как вы узнали из предыдущего раздела, новый уровень равен предыдущему, сложенному с предыдущим трендом и альфой, умноженным на десезонированную погрешность прогноза. Обновленный тренд в D17 рассчитывается практически так же: =D16+D$2*C$2*G17/E5 Он, по сути, представляет собой предыдущий тренд плюс гамма, умноженные на величину десезонированной погрешности, встроенной в обновление уровня.
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-34. Рабочий лист со сглаживающими параметрами и первым одношаговым прогнозом с погрешностью Обновленный сезонный фактор для января будет выглядеть следующим образом: =E5+E$2*(1-C$2)*G17/(C16+D16) Это фактор предыдущего января, скорректированный дельтой, умноженный на погрешность, проигнорированную при коррекции уровня, нормированный подобно сезонным факторам — с помощью последовательного деления на предыдущий уровень и тренд. Обратите внимание, что все три формулы — альфа, гамма и дельта — имеют абсолютные ссылки, так что при перемещении расчета ничего не изменится. Растягивая С17:G17 вниз до месяца 36, получаем таблицу, изображенную на рис. 8-35. Теперь, когда у вас есть итоговый уровень, тренд и сезонные приближения, вы можете спрогнозировать спрос на следующий год. Начиная с месяца 37 в ячейке В53 получаем: 369
370 Много цифр =(C$52+(A53-A$52)*D$52)*E41 Рис. 8-35. Уравнения обновлений до месяца 36 Как и в холтовском сглаживании с коррекцией тренда, берется последнее приближение уровня, к которому затем прибавляется тренд, умноженный на количество месяцев, прошедших с самого последнего приближения тренда. Единственная разница заключается в том, что весь прогноз нормируется по самому свежему сезонному множителю для января, который находится в ячейке Е41. А так как в уровне C$52 и тренде D$52 использованы абсолютные ссылки и они не изменяются при растягивании прогноза вниз, сезонная ссылка в Е41 должна двигаться вниз вместе с растягиванием прогноза на следующие 11 месяцев. Таким образом, растянув расчет вниз, вы получаете прогноз, показанный на рис. 8-36. Вы можете создать график этого прогноза с помощью простой линейной диаграммы, как и в предыдущих двух методах (рис. 8-37).
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-36. Прогноз Холта–Винтерса на следующие месяцы Рис. 8-37: График прогноза Холта–Винтерса 371
372 Много цифр И наконец… оптимизация! Вы думали, что уже все сделали? Увы! Пора установить параметры сглаживания. Как и в предыдущих двух техниках, поместите сумму квадратов отклонений в ячейку G2, а стандартное отклонение — в Н2. Операция отличается только тем, что параметров сглаживания три, поэтому стандартное отклонение рассчитывается как =SQRT(G2/(36–3)) =КОРЕНЬ(G2/(36–3)) Так получается лист, изображенный на рис. 8-38. Что касается настройки «Поиска решения» (показанного на рис. 8-39), в этот раз мы оптимизируем Н2, варьируя три параметра сглаживания. Для вычисления стандартного отклонения подходит почти половина упомянутых техник. График прогноза (рис. 8-40) выглядит довольно симпатично, не правда ли? Вы следите за трендом и сезонными колебаниями. Рис. 8-38. Добавление суммы квадратов отклонений и стандартного отклонения
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-39. Настройка «Поиска решения» для Холта–Винтерса Рис. 8-40. Оптимизированный прогноз по Холту–Винтерсу Пожалуйста, скажите, что это все!!! Теперь в сделанном прогнозе нужно проверить автокорреляции. Они у вас уже настроены — так что просто скопируйте их и вставьте новые значения погрешностей. 373
374 Много цифр Создайте копию листа Holt Autocorrelation и назовите ее HW Autocorrelation. Затем вставьте специальной вставкой значения из столбца с погрешностями G в столбец В листа автокорреляции. Так получается коррелограмма, изображенная на рис. 8-41. Рис. 8-41. Коррелограмма модели Холта–Винтерса Бах! Так как выше критической точки 0,33 нет автокорреляций, вы понимаете, что модель неплохо поработала над пониманием структуры значений спроса. Создаем интервал прогнозирования вокруг прогноза Итак, у нас есть вполне рабочий прогноз. Как установить верхние и нижние границы, которые можно использовать для построения реалистичных предположений вместе с начальником? В этом вам поможет симуляция Монте-Карло, с которой вы уже встречались в главе 4. Смысл заключается в том, чтобы сгенерировать будущие сценарии поведения спроса и определить группу, в которую попадают 95% из них. С чего же начать? На самом деле процесс довольно прост. Создайте копию листа HoltWintersSeasonal и назовите ее PredictionIntervals. Удалите оттуда все графики — они вам не нужны — и более того, сотрите прогноз из ячеек В53:В64. Вы запишете туда «реальный» (но симулированный) спрос. Как я и предупреждал в начале главы, прогноз всегда неверен. В нем всегда есть отклонения. Но вы знаете, как они распределяются. У вас реалистичный прогноз, который, как вы предполагаете, имеет среднее одношаговое отклонение,
8. Прогнозирование: дышите ровно, выиграть невозможно равное 0 (непредвзято) со стандартным распределением, равным 10,37, как рассчитано в предыдущей вкладке. Аналогично рассмотренному в главе 4, вы можете сгенерировать симуляцию отклонения с помощью функции NORMINV/НОРМОБР. Для будущих месяцев вам достаточно снабдить ее средним (0), стандартным распределением (10,37 в ячейке Н$2) и случайным числом от 0 до 1, а она выдаст отклонение из колоколообразной кривой. (Функция интегрального распределения рассматривается также в главе 4.) Теперь поместим симуляцию одношаговой погрешности в ячейку G53: =NORMINV(RAND(),0,H$2) =НОРМОБР(СЛЧИС(),0,H$2) Растянув эту формулу вниз до G64, вы получите симуляции погрешностей для 12 месяцев одношагового прогноза. Так возникает лист, изображенный на рис. 8-42 (ваши значения симуляций будут отличаться от моих). С погрешностью прогноза у вас есть все, что нужно для обновления приближений уровня, тренда и сезонности, которые следуют за одношаговым прогнозом. Так что выделите ячейки C52:F52 и растяните их до строки 64. В результате у вас имеются симулированная погрешность прогноза и сам прогноз на шаг вперед. Вставив погрешность в столбец G а прогноз — в столбец F, можно фактически отказаться от симуляции спроса за этот период. Таким образом, в В53 окажется просто: =F53+G53 Растяните эту формулу до В64, чтобы получить величины спроса на все 12 месяцев (рис. 8-43). Выполнив этот сценарий и обновив страницу, вы получаете новые значения спроса. Можно генерировать различные сценарии будущего спроса, просто копируя и вставляя один сценарий куда угодно, а затем наблюдая за меняющимися значениями. Начните с называния ячейки А69 Simulated Demand, а ячеек А70:L70 — по месяцам, с 37 по 48. Это можно сделать простым копированием А53:А64 и специальной вставкой транспонированных значений в А70:L70. Точно так же вставьте специальной вставкой транспонированные значения первого сценария спроса в А71:L71. Чтобы вставить второй сценарий, кликните правой клавишей мышки на строке 71 и выберите «Вставить» — так появится пустая строка 71. Теперь воспользуйтесь специальной вставкой и заполните ее другими симулированными значениями спроса (они должны были обновиться, когда вы вставляли предыдущую последовательность). 375
376 Много цифр Рис. 8-42. Симулированные одношаговые погрешности Можете продолжать выполнять эту операцию, пока у вас не будет столько сценариев будущего спроса, сколько вам хочется. Процесс, безусловно, утомляет? Тогда быстренько запишите макрос. Как и в главе 7, проделайте следующие шаги: Вставка пустой строки 71. • Копирование В53:В64. • Специальная вставка транспонированных значений в строку 71. • Нажатие кнопки остановки записи. • Записав эти нажатия клавиш, вы можете нажимать на ссылки макросов, которые вам нравятся (см. главу 7) снова и снова, пока у вас не окажется тонна сценариев. Можете даже подержать одну кнопку нажатой — такая тысяча сценариев вас тоже вполне устроит. (Если перспектива держания кнопки вам претит, погуглите и выясните, как зациклить код вашего макроса с помощью Visual Basic for Applicators.)
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-43. Симулированный будущий спрос В завершенном виде ваша таблица должна быть похожей на рис. 8-44. Теперь у вас есть сценарии на каждый месяц и вы можете использовать функцию PERCENTILE/ПЕРСЕНТИЛЬ, чтобы получить верхние и нижние границы в середине 95% сценариев и создать интервал прогнозирования. В качестве примера над месяцем 37 в А66 поместите формулу: =PERCENTILE(A71:A1070,0.975) =ПЕРСЕНТИЛЬ(A71:A1070,0.975) Это даст вам 97,5-й персентиль спроса на данный месяц. В моей таблице он получается около 264. А в А67 можно получить 2,5-й персентиль: =PERCENTILE(A71:A1070,0.025) =ПЕРСЕНТИЛЬ(A71:A1070,0.025) Обратите внимание: я использую интервал А71:А1070 из-за того, что у меня 1000 симулированных сценариев. Вы можете более или менее надеяться 377
378 Много цифр Рис. 8-44. У меня 1000 сценариев спроса на проворство вашего указательного пальца. Если спросите меня, я скажу, что нижняя граница проходит примерно на 224. Это значит, что, хотя прогноз на месяц 37 равен 245, 95%-ный прогностический интервал — от 224 до 264. Растянув эти уравнения персентилей до месяца 48 в столбце L, вы получите полный интервал (рис. 8-45). Теперь есть что передать начальнику: скромный отчет и, если хотите, прогноз! Смело заменяйте 0,025 и 0,975 на 0,05 и 0,95 для 90%-ного интервала или 0,1 и 0,9 для 80%-ного, и т. д. И диаграмма с областями для пущего эффекта Этот последний шаг не обязателен, но обычно прогнозы с прогностическим интервалом изображаются в виде неких диаграмм с областями. Такую можно сделать и в Excel. Создайте новый лист и назовите его Fan Chart. Вставьте в первую его строку месяцы с 37 по 48, а во вторую — значения верхней границы прогностического интервала из строки 66 вкладки PredictionsIntervals. В третью специальной вставкой поместите транспонированные значения текущего прогноза из вкладки
8. Прогнозирование: дышите ровно, выиграть невозможно Рис. 8-45. Прогностический интервал по Холту–Винтерсу HoltWintersSeasonal. В четвертую — значения нижней границы прогностического интервала из строки 67 таблицы с интервалами. Итак, у нас есть месяцы, верхняя граница интервала, прогноз и нижняя граница интервала, все в ряд (рис. 8-46). Рис. 8-46. Прогноз между двух прогностических интервалов Выделив А2:L4 и выбрав «Диаграмму с областями» из меню диаграмм Excel, вы получаете три сплошные области, лежащие на графике друг над другом. 379
380 Много цифр Кликните правой кнопкой мыши на одной из последовательностей и нажмите «Выбрать данные». Измените название оси Х на одно из серии А1:L1, чтобы на графике отображались правильные месяцы. Теперь кликните правой кнопкой мыши на серию нижних границ и отформатируйте их, чтобы цвет ячеек был белым. Уберите линии разметки графика, целостности ради. Не стесняйтесь добавлять названия осей и подписи. Так получается диаграмма с областями, изображенная на рис. 8-47. Рис. 8-47. Прекрасная диаграмма с областями Самое замечательное в этой диаграмме то, что она передает и прогноз, и интервалы на одной простой картинке. Эх, можно было наложить и 80%-ный интервал, было бы больше оттенков серого! На графике есть два интересных момента: Погрешность со временем становится шире. В этом есть смысл. Неуверен• ность накапливается с каждым месяцем. Точно так же погрешность растет и в частях, приходящихся на периоды • сезонного повышения спроса. С последующим его падением погрешность сжимается.
8. Прогнозирование: дышите ровно, выиграть невозможно Подытожим Эта глава оказалась чрезвычайно богатой на новые техники и приемы: простое экспоненциальное сглаживание; • выполнение проверки критерия Стьюдента на линейной регрессии, чтобы • удостовериться в линейном тренде последовательности данных; холтовское экспоненциальное сглаживание с корректировкой тренда; • расчет автокорреляций и построение коррелограммы с критическими зна• чениями; выполнение мультипликативного экспоненциального сглаживания Холта– • Винтерса с помощью скользящего среднего 2 × 12; прогнозирование сглаживанием Холта–Винтерса; • создание прогностических интервалов вокруг прогноза с помощью симу• ляции Монте-Карло; отображение прогностических интервалов на диаграмме с областями. • Если вам удалось дойти до конца главы вместе со мной — браво! Кроме шуток, слишком много прогнозирования для одной главы. Тем, кто хочет дополнительно позаниматься прогнозированием, рекомендую несколько прекрасных учебников. Я очень люблю Forecasting, Time Series, and Regression, Bowerman et al. (Cengage Learning, 2004). Отличный бесплатный онлайновый учебник есть у Хайндмана http://otexts.com/fpp/, а его блог с чудесным названием Hyndsight очень интересно почитать. Если появляются вопросы, их можно задавать в этом сообществе: http://stats.stackexchange.com/. Что касается производственного прогнозирования, то эта область содержит бесконечное множество объектов прогнозирования. Для тех, что попроще, достаточно и Excel. Если же у вас тысячи объектов или единиц складского учета, то в этом случае лучше, конечно, использовать немного кода. Прекрасные пакеты для прогнозирования есть в SAS и R. В R они написаны самим Хайндманом (см. главу 10), который подвел статистический фундамент под определение прогностических интервалов в методах экспоненциального сглаживания. Ну, вот и все! Надеюсь, теперь вы чувствуете в себе необходимую дозу уверенности, чтобы идти дальше и «организовывать свое невежество»! 381

9 В Определение выбросов: выделяющиеся не значит важные ыбросы — точки, сильно выбивающиеся из последовательности, не вписывающиеся в модель по какой-либо причине. Вы можете помнить их из школьного курса математики — это экстремумы, величины, слишком большие или слишком маленькие, чтобы быть результатом одного и того же процесса, что и остальные наблюдения из ряда данных. Единственная причина, по которой люди озаботились выбросами — это желание избавиться от них. Эти выбросы «достали» тем, что оттягивают на себя средние значения и сдвигают распределение данных. Статистики, работавшие сто лет назад, имели много общего с Боргом : по их мнению, точка в последовательности должна была ассимилироваться или умереть. Хороший пример удаления выбросов — гимнастика, где наибольшие и наименьшие оценки судей всегда удаляются перед вычислением среднего балла. Выбросы проявляют себя во всей красе в запутывании моделей машинного обучения. К примеру, в главах 6 и 7 вы наблюдали процессы выявления беременных покупателей на основании данных об их покупках. А что, если бы в магазине перепутали ценники и система регистрировала бы покупаемые поливитамины как фолиевую кислоту? Покупатели с такими ошибочными векторами покупок — это выбросы, которые сдвигают отношение беременных к «не-беременным» в данных о покупке фолиевой кислоты и мешают модели понять поведение покупателей. Однажды, когда я консультировал правительственные структуры, моя компания обнаружила в Дубае водохранилище, принадлежащее США, которое оценивалось в несколько миллиардов долларов. Стоимость его была выбросом, оттягивающим результаты нашего анализа, но оказалось, что кто-то вбил его в базу с кучей лишних нулей. Поэтому первая причина обращать внимание на выбросы — это обеспечение чистоты анализа данных и моделирования. Но есть и другая. Они интересны сами по себе!
384 Много цифр Выбросы тоже (плохие?) люди! Представьте момент, когда после подозрительной транзакции вам звонит компания, выпустившая вашу кредитную карту. Что именно она делает? Она определяет эту транзакцию как выброс, основываясь на вашем поведении в прошлом. И вместо игнорирования транзакции как выброса, она помечает ее как потенциально мошенническую и начинает действовать соответственно. В MailChimp, при определении спамеров еще до отправки спама, мы предсказываем выбросы. Эти спамеры — небольшая группа людей, чье поведение лежит за пределами того, что мы как компания считаем нормальным. Мы используем контролируемые модели вроде той, что рассматривалась в главах 6 и 7, чтобы предсказать, основываясь на последних событиях, когда новый пользователь собирается отправить спам. Поэтому в случае MailChimp выброс — это не более чем маленький, но оформленный класс данных в общем наборе, который можно предсказать с помощью обучающей последовательности. Но как быть, когда вы сами не знаете, что искать — как в случае с ценниками на поливитамины? Мошенники часто меняют линию поведения; единственное, чего вы можете ожидать от них — это неожиданности. Но если этого раньше никогда не происходило, как найти подобные «выбивающиеся» точки в первый раз? Такой способ определения выбросов является примером неконтролируемого обучения и добычи данных. Это интуитивная изнанка анализа, который мы выполняли в главах 2 и 5, когда определяли кластеры данных. В кластерном анализе вас интересуют группы друзей по точкам данных и анализ этих групп. При определении выбросов вам важны точки, которые отличаются от групповых. Они выделяются, являясь в некотором роде исключениями. Эта глава начнется с простого, стандартного расчета выбросов в нормальных одномерных данных. Затем мы перейдем к графу k ближайших соседей, чтобы определить выбросы в многомерных данных, как мы это делали на графах r-окрестности для создания кластеров в главе 5. Захватывающее дело Хадлум против Хадлум ЗАМЕТКА Электронная таблица “Pregnancy Duration.xlsx”, используемая в этой главе, доступна для скачивания вместе с книгой на сайте издательства www.wiley.com/go/datasmart. Ниже мы перейдем к таблице побольше, “SupportCenter.xlsx”, доступной по тому же адресу.
9. Определение выбросов: выделяющиеся не значит важные Когда-то давно, в 1940-х годах, один британец по имени мистер Хадлум ушел на войну. Энное количество дней спустя (349, если быть точным) его жена, миссис Хадлум, родила. В среднем беременность длится 266 дней. Таким образом получается, что миссис Хадлум носила ребенка лишних 12 недель. Исключительно долгая беременность, не правда ли? Именно так и утверждала миссис Хадлум. Но мистер Хадлум тоже был не лыком шит и настаивал, что в деле замешан другой мужчина, с которым миссис Хадлум встречалась в его отсутствие: 349-дневная беременность — аномалия, которую трудно оправдать статистическим распределением продолжительности. При наличии подобных данных наверняка можно быстренько определить, стоит ли считать выбросом интересный случай миссис Хадлум? Исследования показали, что продолжительность беременности — величина с более-менее нормальным распределением со средним значением в 266 дней после оплодотворения и стандартным отклонением около 9. Так что можно вычислить значение функции нормального интегрального распределения, упоминавшегося в главе 4, и получить вероятность, меньшую требуемых 349. В Excel это легко сделать с помощью функции NORMDIST/НОРМРАСП: =NORMDIST(349,266,9,TRUE) =НОРМРАСП(349,266,9,ИСТИНА) Эта функция требует выбора интересующего вас случая, его среднего, стандартного распределения и отметки TRUE/ИСТИНА, которая заставит функцию выдать интегральное значение. Формула все время выдает 1,000, сколько бы знаков после запятой Excel я ни рассчитал. Это значит, что почти все дети, рожденные от настоящего момента до бесконечности, будут рождены на 349-й день или раньше. Вычитаем это значение из 1: =1-NORMDIST(349,266,9,TRUE) =1-НОРМРАСП(349,266,9,ИСТИНА) И получаем, конечно же, 0,000000 насколько хватает глаз. Другими словами, человеческого детеныша практически невозможно вынашивать так долго. Мы никогда точно не узнаем ответа, но я бы поставил неплохие деньги на то, что миссис Хадлум имела интрижку на стороне. Самое смешное, что суд решил дело в ее пользу, постановив, что такая долгая беременность, хотя и очень маловероятна, но все же возможна. 385
386 Много цифр Границы Тьюки Концепция того, что выбросы — это маловероятные точки на колоколообразной кривой, методом проб и ошибок привела к границам Тьюки. Их легко проверить и легко программировать. Они используются в статистических пакетах по всему миру для идентификации и удаления сомнительных точек данных из любого ряда, соответствующего нормальной колоколообразной кривой. Метод Тьюки заключается в следующем: Рассчитать 25-й и 75-й персентиль любого ряда данных, в котором вы хо• тите найти выбросы. Эти значения также называются первым и третьим квартилями. Excel вычисляет их значения с помощью функции PERCENTILE/ ПЕРСЕНТИЛЬ. Вычесть первый квартиль из третьего — получится мера распределе• ния данных, называемая межквартильным размахом (МР). МР прекрасен своей относительной устойчивостью к экстремальным значениям меры распределения (то есть робустный), в отличие от обычного расчета стандартного распределения, которым вы пользовались в предыдущих главах этой книги. Вычесть 1,5 × МР из первого квартиля и получить нижнюю внутреннюю • границу. Прибавить 1,5 × МР к третьему квартилю и получить верхнюю внутреннюю границу. Точно так же вычесть 3 × МР из первого квартиля, чтобы получить нижнюю • внешнюю границу. Прибавить 3 × МР к третьему квартилю, чтобы получить верхнюю внешнюю границу. Любое значение, меньшее нижней границы или выше верхней, экстре• мально. В данных с нормальным распределением вы увидите одну точку на 100 снаружи внутренней границы, и только одну на 500 000 точек за пределами внешней границы. Применение границ Тьюки в таблице Я включил таблицу под названием PregnancyDuration.xlsx в файлы, доступные для загрузки на сайте книги, так что вы можете применить этот метод к реальным данным. Открыв ее, вы увидите лист Pregnancies с 1000 наблюдений в столбце А. Срок беременности миссис Хадлум в 349 дней находится в ячейке А2. В столбец D поместите всю итоговую статистику и границы. Начните с медианы (среднего значения), которая более устойчива как статистика центрированности, чем среднее значение (на которое могут влиять выбросы).
9. Определение выбросов: выделяющиеся не значит важные Озаглавьте С1 как Median, а в D1 рассчитайте значение медианы следующим образом: =PERCENTILE(A2:A1001,0.5) =ПЕРСЕНТИЛЬ(A2:A1001,0.5) Это будет 50-й персентиль. Под медианой вычислите первый и третий квартили: =PERCENTILE(A2:A1001,0.25) =PERCENTILE(A2:A1001,0.75) =ПЕРСЕНТИЛЬ(A2:A1001,0.25) =PERCENTILE(A2:A1001,0.75) А межквартильный размах — это разница: =D3-D2 «Приклеивая» 1,5 и 3, умноженные на МР к первому и третьему квартилю соответственно, можно затем вычислить все границы: =D2–1.5*D4 =D3+1.5*D4 =D2–3*D4 =D3+3*D4 Если вставить названия всех величин, получится таблица, показанная на рис. 9-1. Рис. 9-1. Границы Тьюки для продолжительности беременности 387
388 Много цифр Применив к таблице условное форматирование, можно посмотреть, кто же выпадает за образованные границы. Чтобы выделить экстремальные значения, выберите «Условное форматирование» из домашней вкладки меню, затем нажмите «Правила выделения ячеек» и «Меньше, чем», как показано на рис. 9-2. Рис. 9-2. Добавление условного форматирования выбросов Определяя нижнюю внутреннюю границу, не стесняйтесь выбирать яркий цвет, который вам по душе (я выбрал желтую заливку для внутренних границ и красную для внешних, потому что люблю светофоры). Таким же образом отформатируйте три остальные границы (если у вас Excel 2011 для MacOS, используйте правило «Форматировать только значения, которые находятся выше или ниже заданных», чтобы добавить 2 правила вместо 4). Как показано на рис. 9-3, миссис Хадлум «краснеет», следовательно, ее беременность была совершенно точно экстремальна. Прокрутив данные до конца, вы увидите, что красных ячеек больше нет, но есть девять желтых. Это очень похоже на примерно одну точку из 100, что и предполагалось в нормальных данных согласно правилу. Ограничения этого нехитрого метода Границы Тьюки работают только при выполнении всех трех условий: 1. Данные, в общем, распределены нормально. Распределение может не быть идеальным, но кривая должна быть колоколообразной и обнадеживающе симметричной, без разных длинных хвостов, вылезающих с одной стороны.
9. Определение выбросов: выделяющиеся не значит важные Рис. 9-3. Так-так, миссис Хадлум. Что вы скажете об этом условном форматировании? 2. Выброс «отмечен» как экстремальное значение на внешней стороне распределения. 3. Данные одномерны. Рассмотрим пример выброса, который не удовлетворяет первым двум условиям. В «Братстве Кольца», объединившись, наконец, в одну компанию (братство, в честь которого и названа книга), герои встают небольшой группой и слушают лидера эльфов, произносящего речь о том, кто они есть и какова их цель. В этой группе есть четверо высоких ребят — Гэндальф, Арагорн, Леголас и Боромир — и четверо приземистых. Это хоббиты: Фродо, Мерри, Пиппин и Сэм. Среди них есть один гном — Гимли. Гимли ниже первых на две головы, но выше вторых примерно настолько же (рис. 9-4). В фильме, когда мы впервые видим эту группу, Гимли явно выделяется по росту. Он не принадлежит ни к одной из групп. Но является ли он выбросом? Его рост не ниже всех и не выше. На самом деле, его рост ближе всего к среднему в группе. Понимаете, это распределение роста ничем не похоже на нормальное. Можете называть его «мультимодальным», если хотите (распределение с несколькими пиками). И Гимли является выбросом не из-за выдающегося роста, а всего лишь оттого, что находится между двумя пиками. А если данные многомерны, то такие точки в них найти еще сложнее. Такой вид выбросов довольно часто обнаруживается в случаях мошенничества. Кто-то слишком обычный, чтобы быть обычным. Берни Мейдофф — отличный пример такого выброса. Если в большей части схем Понци предлагался 389
390 Много цифр А я — выброс! Хоббиты Гимли Верзилы Рис. 9-4. Гимли, сын Глойна, «гномий» выброс размер выплат более 20% сверху, больше похожий на выброс, то Мейдофф стал предлагать скромные надежные выплаты, смешивающиеся с шумом каждый год — он не перепрыгивал никаких границ Тьюки. Но постепенно эти выплаты из-за своей надежности превратились в многомерный выброс. Так как же находить выбросы в случае многомодельности, многомерности данных (это все можно назвать простыми словами «данные из реального мира»)? Один чудесный способ решения этого вопроса — отнестись к данным как к графу (см. поиск кластеров данных в главе 5). Задумайтесь над этим. Что определяет Гимли как выброс относительно остальных точек данных — это расстояние от него до них относительно расстояния между ними самими. Все эти расстояния, от одной точки до другой, определяют ребра графа. С его помощью можно «выманить» изолированные точки. Для этого нужно начать с создания графа k ближайших соседей и плясать от него. Ни в чем не ужасен, плох во всем В этом разделе вам придется представить себя в роли управляющего большим центром поддержки клиентов. Каждый звонок, электронное письмо или сообщение в чате от покупателя создает жетон. Один работник службы поддержки должен обрабатывать не меньше 140 жетонов в день. В конце каждого диалога клиенту дается возможность оценить работника по пятибалльной шкале. Сотрудники должны поддерживать свой рейтинг не ниже 2, иначе их уволят. Высокие стандарты! Компания также следит за множеством других показателей своих работников. Сколько раз они опоздали в этом году? Сколько у них было ночных смен и смен, приходящихся на выходные? Сколько они брали больничных и какое количество из них приходилось на пятницу? Компания знает, сколько часов сотрудник тратит на внутренние обучающие курсы (она оплачивает до 40 часов)
9. Определение выбросов: выделяющиеся не значит важные и сколько раз он оставлял запрос на замену смен или был добрым самаритянином и шел навстречу просьбам коллег. Все эти данные на каждого из 400 сотрудников службы поддержки содержатся у вас в таблице. Вопрос в том, кто из них является выбросом и какие выводы о его работе можно сделать? Есть ли плохиши, проскользнувшие между теми, кто не подходит по требованиям жетона, и минимальным клиентским рейтингом? Возможно, выбросы подскажут, как сформулировать новые, более эффективные инструкции. Открыв электронную таблицу для этого раздела главы (SupportCenter.xlsx можно скачать на сайте книги www.wiley.com/go/datasmart), вы найдете все эти данные слежки за служащими во вкладке SupportPersonnel (рис. 9-5). Рис. 9-5. Различные показатели сотрудников Подготовка данных к отображению на графе С этими данными есть одна проблема. Нельзя измерить расстояние между сотрудниками, чтобы выяснить, кто находится «за пределами», потому что каждый столбец имеет свои единицы измерения. Что значит разница, равная 5, между двумя работниками в их среднем количестве жетонов относительно разницы в 0,2 в клиентском рейтинге? Нужно стандартизировать каждый столбец, чтобы значения были ближе к единому центру и распределению. Способ стандартизации столбцов данных таков: вычесть среднее значение столбца из каждого наблюдения; • разделить каждое наблюдение на стандартное отклонение столбца. • 391
392 Много цифр Для нормально распределенных данных центром является 0 (что дает нулевое среднее), а стандартное отклонение равно 1. Нормальное распределение с центром в 0 и стандартным отклонением в 1 называется стандартным нормальным распределением. СТАНДАРТИЗАЦИЯ УСТОЙЧИВЫМИ ПАРАМЕТРАМИ ЦЕНТРИРОВАННОСТИ И ШКАЛЫ Начнем с того, что не все данные, которые вам хочется нормализовать, распределены нормально. Вычитание среднего и деление последовательно на стандартное отклонение в любом случае срабатывают. Но выбросы могут испортить среднее значение и расчет стандартного отклонения, поэтому иногда специалисты предпочитают стандартизировать вычитанием более устойчивой статистики центрированности («середины» данных) и последовательным делением на более устойчивые параметры шкалы / статистического распределения (разброс данных). Вот несколько способов рассчитать центрированность, определяющих одномерные выбросы лучше, чем среднее: • медиана — просто 50-й персентиль; • межквантильное среднее — среднее между 25-м и 75-м персентилями; • тройное среднее — среднее между медианой и межквантильным средним. Оно мне нравится за умное название; • усеченное среднее — среднее, из которого выкинули N верхних и нижних процентов точек. Такое часто можно встретить на спортивных соревнованиях (например, по гимнастике, где отбрасываются высшие и низшие баллы). Если отбросить по 25% сверху и снизу и взять среднее от 50% данных в середине, то получится величина, имеющая свое название — межквартильное среднее (МКС); • винсоризированное среднее — похоже на усеченное, но вместо отбрасывания слишком большие и слишком маленькие значения заменяются на граничные. Что касается робустных параметров шкалы, то вот некоторые полезные замены среднеквадратичному отклонению: • межквартильный размах, с которым вы уже встречались ранее в этой главе. Это просто 75-й персентиль минус 25-й. Можно пользоваться и другими –илями. К примеру, если вычесть 101-й персентиль из 90-го, то получится междецильный размах; • медиана абсолютного отклонения (МОА). Вычислите медиану данных. Теперь возьмите абсолютное значение разницы каждой точки и медианы. Медианой этих отклонений и будет МОА. Что-то вроде ответа медианы среднеквадратичному отклонению.
9. Определение выбросов: выделяющиеся не значит важные Итак, приступим. Вычислите среднее значение и стандартное отклонение каждого столбца внизу листа SupportPersonnel. Первым значением здесь будет среднее количество жетонов за день в ячейке В402, которое можно записать как: =AVERAGE(B2:B401) =СРЗНАЧ(B2:B401) А под ним рассчитайте стандартное отклонение столбца: =STDEV(B2:B401) =СТАНДОТКЛОН(B2:B401) Копируя эти две формулы в столбец К, получаем лист, изображенный на рис. 9-6. Рис. 9-6. Среднее значение и стандартное отклонение для каждого столбца Создайте новый лист, назовите его Standardized. Скопируйте туда названия столбцов из строки 1 и персональные номера работников из столбца А. Нормализацию значений можно начать с ячейки В2 и формулы STANDARDIZE/НОРМАЛИЗАЦИЯ. Эта формула берет исходное значение, центр и величину рассеяния и выдает значения с вычтенным центром, разделенным на рассеяние. Таким образом, в В2 получается: =STANDARDIZE(SupportPersonnel!B2,SupportPersonnel!B$402, SupportPersonnel!B$403) =НОРМАЛИЗАЦИЯ(SupportPersonnel!B2,SupportPersonnel!B$402, SupportPersonnel!B$403) 393
394 Много цифр Обратите внимание: абсолютные ссылки стоят только на строки со средним и стандартным отклонением, таким образом они остаются на месте при копировании формулы вниз. Однако ее горизонтальные столбцы при копировании будут меняться. Скопируйте и вставьте В2 слева направо до К2, выделите и кликните правой клавишей, чтобы распространить вычисления до К401. Получается нормализованный набор данных, показанный на рис. 9-7. Рис. 9-7. Нормализованный набор данных о работе персонала Создаем граф Граф есть не что иное как ребра и вершины. В нашем случае каждый работник является вершиной, и для начала можно просто провести ребра между ними всеми. Длина ребра — это евклидово расстояние между двумя работниками в их нормализованных данных. Как вы помните из главы 2, евклидово расстояние (оно же расстояние птичьего полета) между двух точек — это квадратный корень из суммы квадратов разниц каждого столбца для каждого из них. В новой вкладке Distances создайте матрицу расстояний между сотрудниками точно так же, как в главе 2 — с помощью формулы OFFSET/СМЕЩ. Пронумеруйте сотрудников от 0 до 399 начиная с А3 вниз и от С1 вправо. (Подсказка: начните печатать 0, 1 и 2 в первых трех ячейках, а затем выделите их и растяните в нужном направлении. Excel заполнит их за вас — он вполне способен с этим справиться.) Рядом с этими числами вставьте персональные номера сотрудников (специальной вставкой с транспонированием столбцов). Так получается пустая матрица, изображенная на рис. 9-8.
9. Определение выбросов: выделяющиеся не значит важные Рис. 9-8. Пустая матрица расстояний между сотрудниками Заполнение матрицы начнем с первой ячейки расстояний, С3. В ней находится расстояние между сотрудником 144624 и им самим. Для всех расчетов расстояний мы будем пользоваться формулой OFFSET/ СМЕЩ, привязанной к первой строке стандартизированных данных сотрудников: OFFSET(Standardized!$B$2:$K$2, некоторое количество строк, 0 столбцов) СМЕЩ(Standardized!$B$2:$K$2, некоторое количество строк, 0 столбцов) Для ячейки С3 Standardized!$B$2:$K$2 — текущая строка работника 144624, так что можно вычислить разницу между этим работником и им самим с помощью формулы смещения: OFFSET(Standardized!$B$2:$K$2,Distances!$A3,0)-OFFSET (Standardized!$B$2:$K$2,Distances!C$1,0) СМЕЩ(Standardized!$B$2:$K$2,Distances!$A3,0)-СМЕЩ (Standardized!$B$2:$K$2,Distances!C$1,0) В первой формуле смещения вы двигаете строки с помощью значения в $А3, а во второй — в С$1, чтобы передвинуть OFFSET//СМЕЩ к другому сотруднику. Абсолютные ссылки в этих формулах используются в необходимых местах, поэтому при копировании формулы на весь лист она продолжает считывать значения из столбца А и строки 1. 395
396 Много цифр Этот расчет разности нужно возвести в квадрат, сложить и извлечь квадратный корень, получая таким образом полное евклидово расстояние: {=SQRT(SUM((OFFSET(Standardized!$B$2:$K$2,Distances!$A3,0)OFFSET(Standardized!$B$2:$K$2,Distances!C$1,0))^2))} {=КОРЕНЬ(СУММ((СМЕЩ(Standardized!$B$2:$K$2,Distances!$A3,0)СМЕЩ(Standardized!$B$2:$K$2,Distances!C$1,0))^2))} Заметьте, что этот расчет основан на формуле массива из-за отличия строк друг от друга. Поэтому нажмите Ctrl+Shift+Enter (Command+Return в MacOS), и все заработает. Евклидово расстояние работника 144624 до самого себя действительно равно 0. Раскопируйте эту формулу до OL2, а потом выделите этот промежуток и кликните дважды в нижнем углу, размножив таким образом вычисление до самой OL402. Так получится таблица, показанная на рис. 9-9. Вот и все! У вас есть граф сотрудников. Можете экспортировать его в Gephi как в главе 5, и взглянуть на то, что получится, но так как у него 16 000 ребер и только 400 вершин, это наверняка жуткая картина. Подобно тому, как в главе 5 вы конструировали граф r-окрестности из матрицы расстояний, в данной главе мы сфокусируемся лишь на k ближайших соседей каждого сотрудника, чтобы найти выбросы. Первый шаг — ранжирование, то есть расположение работников согласно расстояниям относительно друг друга. Это приводит нас к первому и основному методу выделения выбросов на графе. Рис. 9-9. Матрица расстояний сотрудников
9. Определение выбросов: выделяющиеся не значит важные Вычисляем k ближайших соседей Создайте новый лист под названием Rank. Вставьте персональные номера от А1 вниз и от В1 вправо, чтобы получилась основа для матрицы, как в предыдущей части. Теперь нужно ранжировать каждого работника в верхней строке в соответствии с его расстоянием до работников в столбце А. Начните с 0 таким образом, чтобы 1 оказывались у действительно других работников, а 0 образовали диагональ графа (так как расстояния до самих себя всегда самые короткие). Начиная с В2 ранг сотрудника номер 144624 относительно него самого записывается с помощью формулы RANK//РАНГ: =RANK(Distances!C3,Distances!$C3:$OL3,1)-1 =РАНГ(Distances!C3,Distances!$C3:$OL3,1)-1 Эта –1 в конце и дает нам расстояние до самого себя, равное 0, а не 1. Обратите внимание, что столбцы с С по OL вкладки Distances имеют абсолютные ссылки, что позволяет вам копировать формулу вправо. Копируя ее таким образом в первую правую ячейку, С2, вы ранжируете работника 142619 относительно его расстояния до работника 144624: =RANK(Distances!D3,Distances!$C3:$OL3,1)-1 =РАНГ(Distances!D3,Distances!$C3:$OL3,1)-1 В результате получаем ранг 194 из 400, то есть этих двоих ребят нельзя назвать хорошими друзьями (рис. 9-10). Рис. 9-10. Сотрудник 142619, ранжированный относительно 144624-го Раскопируйте эту формулу на всю таблицу. У вас получится полная матрица рангов, изображенная на рис. 9-11. 397
398 Много цифр Рис. 9-11. Каждый сотрудник в столбце ранжирован относительно каждой строки Определение выбросов на графе, метод 1: полустепень захода Если вы хотите построить граф k ближайших соседей, используя таблицы Distances и Rank, то все, что вам нужно сделать — это удалить все ребра из вкладки Distances (сделать все ячейки пустыми), чей ранг окажется больше, чем k. Для k = 5 вы отбросите все расстояния с рангом 6 и больше. Что значит выброс в этом контексте? Думаю, он нечасто будет оказываться в числе «ближайших соседей», верно? Скажем, вы построили граф 5 ближайших соседей, оставив лишь ребра с рангом 5 и меньше. Если просмотреть весь столбец, к примеру столбец В для сотрудника 144624, сколько можно найти его попаданий в первую пятерку всех остальных сотрудников? То есть сколько человек выбирают его одним из 5 ближайших соседей? Немного. На самом деле, я не вижу ни одного такого, кроме него самого с рангом 0 на диагонали, что можно игнорировать. Как насчет 10 ближайших соседей? Ну, в таком случае сотрудник 139071 в строке 23, оказывается, считает его девятым ближайшим соседом! Это значит, что в графе 5 ближайших соседей работник 144624 имел полустепень захода, равную 0, но в графе 10 ближайших соседей она уже равна 1. Полустепень захода — это количество ребер, входящих в любую вершину графа. Чем ниже полустепень захода, тем больше вы похожи на выброс, потому что никто не хочет быть вашим соседом. Внизу столбца В листа Rank вычислите полустепень захода для работника 144624 на графе 5, 10 и 20 ближайших соседей. Сделать это можно с помощью простой формулы COUNTIF/СЧЁТЕСЛИ (вычитая из 1 в случае дистанции до самих
9. Определение выбросов: выделяющиеся не значит важные себя на диагонали, что игнорируется). Таким образом, чтобы подсчитать, например, полустепень захода для сотрудника 144624 на графе 5 ближайших соседей, нужно в ячейке В402 написать следующее: =COUNTIF(B2:B401,”<=5”)–1 =СЧЁТЕСЛИ(B2:B401,”<=5”)–1 Точно так же ниже можно рассчитать полустепень захода для сотрудника на графе 10 ближайших соседей: =COUNTIF(B2:B401,”<=10”)-1 =СЧЁТЕСЛИ(B2:B401,”<=10”)-1 И для 20: =COUNTIF(B2:B401,”<=20”)-1 =СЧЁТЕСЛИ(B2:B401,”<=20”)-1 Конечно, вы можете выбрать любое k от 1 до числа служащих. Но на этот раз вполне достаточно 5, 10 и 20. Используя меню условного форматирования, выделите ячейки, чье значение равно 0 (что значит отсутствие входящих ребер для этой вершины на графе такого размера). Этот расчет для работника 144624 показан на рис. 9-12. Выделяя В402:В404, перенесите расчеты вправо до самого столбца ОК. При просмотре результатов видно, что некоторых сотрудников можно считать выбросами на графе 5 ближайших соседей, но они не обязательно окажутся таковыми на графе 10 (если вы определяете выброс как работника с полустепенью 0, при желании можете выбрать другое значение). Рис. 9-12. Полустепени захода трех разных графов ближайших соседей 399
400 Много цифр В итоге существуют всего двое сотрудников, у которых даже на графе 20 ближайших соседей нет ни одного входящего ребра. Никто не считает их соседями, даже 20 ближайших. Это довольно далеко! Персональные номера этих двоих ребят — 137155 и 143406. Переключившись обратно во вкладку SupportPersonnel, можно изучить их получше. Сотрудник 137155 расположен в строке 300 (рис. 9-13). У него большое среднее количество жетонов, высокий клиентский рейтинг и он кажется добрым самаритянином. Он брал много смен в выходные, ночных и семь раз заменял тех, кто просил его об этом. Мило! Вот кто во всех измерениях достаточно исключителен, чтобы не попасть даже в 20 ближайших расстояний до любого другого сотрудника. Удивительно! Наверное, такие работники заслуживают пиццы или чего-то подобного. Рис. 9-13. Данные о работе сотрудника 137155 А что насчет второго сотрудника — 143406? Он находится в строке 375 и явно контрастирует с предыдущим служащим (рис. 9-14). Никакие параметры сами по себе не являются достаточными условиями для увольнения, но количество его жетонов на два стандартных отклонения ниже среднего, клиентский рейтинг тоже примерно на пару отклонений ниже распределения. Число опозданий выше среднего и пять из шести больничных приходятся на пятницу. Хммм… Этот сотрудник посетил массу курсов для персонала, что, конечно, хорошо. Но, возможно, любознательность продиктована тем, что ему просто нравилось отлынивать от обработки жетонов. Быть может, руководству стоило бы дифференцировать занятия для персонала? А еще он просил заменить себя 4 раза, но ни разу не откликнулся на просьбы коллег. Такие сотрудники остаются на местах благодаря системе. Удовлетворяя минимальным требованиям трудоустройства (заметьте, что здесь тоже никто
9. Определение выбросов: выделяющиеся не значит важные не переходит границ Тьюки), они плавно скатываются к краям любого распределения. Рис. 9-14. Данные о работе сотрудника 143406 Определение выбросов на графе, метод 2: нюансы k-расстояния Одним из недостатков метода, описанного выше, является то, что на конкретном графе k ближайших соседей ты либо получаешь входящее ребро, либо нет. И это означает большие промежутки между теми, кто характеризуется как выброс, и остальными, в зависимости от выбранного k. В этом примере мы пробовали 5, 10 и 20, пока не остались лишь с двумя сотрудниками. Кто из этих двоих является большим выбросом? Понятия не имею! Полустепень захода у обоих 0 даже при k = 20, то есть каким-то образом они все же связаны, не так ли? Было бы неплохо иметь расчет, привязывающий к работнику длительное значение степени «выбросовости». С помощью следующих двух методов мы будем пытаться сделать именно это. Сначала посмотрим на ранжирование выбросов с помощью величины под названием k-расстояние. K-расстояние — это расстояние от сотрудника до его k-го соседа. Прекрасно и просто, но так как результатом является расстояние, а не подсчет, можно ранжировать эту величину. Для удобства создайте новую вкладку в книге под названием K-Distance. В качестве k у нас будет 5, что значит сбор расстояний всех служащих до их пятых ближайших соседей. Если у меня по соседству живут 5 соседей и я сам, сколько места мы занимаем все вместе? Если мне надо идти в гости к пятому соседу 30 минут, то, похоже, я живу в захолустье. Так что напишите в А3 «How many employees are in my neighborhood?» («Сколько у меня соседей?»), а в В1 поместите 5. Это ваше значение k. 401
402 Много цифр Начиная с А3, назовите столбцы соответственно персональным номерам работников «Employee ID» и вставьте эти номера во вкладки. Теперь можно начать расчет k-расстояний сотрудника 144624 в ячейке В4. Так как же вычислить расстояние между 144624 и его пятым ближайшим соседом? Ранг пятого ближайшего сотрудника в строке 2 (строка 144624) вкладки Rank должен быть равен 5. Вы можете просто использовать оператор IF/ЕСЛИ, установив его значение на 1 в векторе из нулей, а затем умножив его на строку расстояний для 144624 вкладки Distances. И, наконец, складываем все вместе. Таким образом в В4 получается: {=SUM(IF(Rank!B2:OK2=$B$1,1,0)хDistances!C3:OL3)} {=СУММА(ЕСЛИ(Rank!B2:OK2=$B$1,1,0)хDistances!C3:OL3)} Обратите внимание: значение k в В1 зафиксировано абсолютными ссылками, так что можете смело растягивать формулу. А еще она работает для массива целиком — ведь оператор IF/ЕСЛИ проверяет его весь. Кликните на формуле дважды, чтобы раскопировать ее на весь лист, и примените условное форматирование, выделяя большие расстояния. И снова лидируют два выброса из предыдущего раздела (рис. 9-15). Рис. 9-15. Сотрудник 143406 дает пять На этот раз есть один небольшой нюанс. По одной этой таблице видно, что плохой работник, 143604, оказывается существенно дальше, чем 137155, и оба эти значения сильно превосходят следующее по величине значение, равное 3,53. Все же у этого метода есть недостаток, показанный на рис. 9-16. Использование одного k-расстояния дает чувство глобальной принадлежности
9. Определение выбросов: выделяющиеся не значит важные к выбросам, в чем вы можете убедиться, выделив цветом точки, наиболее отдаленные от своих соседей. Но после знакомства с рисунком 9–16 становится ясно, что хотя треугольная точка — самый что ни на есть выброс, но все же его k-расстояние меньше, чем у некоторых ромбов. Неужели эти ромбики еще страннее, чем треугольник? Только не для меня! Дело здесь в том, что треугольник не является глобальным выбросом, потому что он — локальный выброс. Причина, по которой ваши глаза зафиксировали в качестве странного именно его, заключается в том, что он ближе к кластеру кружков. Если бы треугольник оказался среди разбредшихся ромбов, все было бы иначе. Но это не так. Наоборот, похоже, это его «круглые» соседи. В итоге у нас получается суперсовременная техника под названием факторы локальных выбросов (ФЛВ). Рис. 9-16. k-расстояние не работает с локальными выбросами Определение выбросов на графе, метод 3: факторы локальных выбросов — это то, что надо Как и k-расстояния, факторы локальных выбросов дают по одному «баллу» за каждую точку. Чем больше баллов, тем в большей степени выбросом является точка. Но ФЛВ дает вам нечто немного большее: чем ближе балл к единице, тем более обыкновенна данная точка локально. С ростом балла точка считается все менее типичной и более относящейся к выбросам. В отличие 403
404 Много цифр от k-расстояния, подход «единица типична» никак не сказывается на масштабе графа, что действительно круто. На высоком уровне это работает так: ты являешься выбросом, если k твоих ближайших соседей считают тебя дальше, чем их соседи считают их самих. Алгоритму интересны друзья точек и их друзья. Так он понимает слово «локальный». Анализируя рис. 9-16, можно понять, что именно делает треугольник выбросом. У него может не быть лучшего k-расстояния, но отношение расстояния треугольника к его ближайшим соседям по сравнению с их расстояниями друг до друга довольно велико (рис. 9-17). Рис. 9-17. Треугольник не настолько далек от своих соседей, как далеки они друг от друга Начнем с достижимости Перед тем, как свести вместе все факторы локальных выбросов для каждого сотрудника, нужно рассчитать еще одну последовательность чисел — расстояние достижимости. Расстояние достижимости сотрудником А сотрудника В — это обычное расстояние между ними, пока А не оказывается по соседству с В, то есть удаленным на k-расстояние, которое и превращается в таком случае в расстояние достижимости. Другими словами, если А попадает в окрестность точки В, вы округляете расстояние от А до В до размера окрестности, а если же нет — то просто оставляете без изменений. Использование расстояния достижимости вместо обычного расстояния при расчете ФЛВ помогает немного стабилизировать вычисления.
9. Определение выбросов: выделяющиеся не значит важные Создайте новый лист под названием Reach-dist и замените расстояния из вкладки Distances новыми расстояниями достижимости. Первое, что нужно сделать — вставить транспонированные значения из матрицы работников листа K-Distance специальной вставкой в верхнюю часть таблицы слева направо, начиная со строки 3. Получится пустая таблица, изображенная на рис. 9-18. Рис. 9-18. Скелет таблицы расстояний достижимости Начиная с ячейки В4 вы будете перебирать расстояния от 144624 до него самого из вкладки Distances (Distances! C3), пока оно не окажется меньше, чем k-расстояние наверху в В1. Это обычная формула MAX/МАКС: =MAX(B$1,Distances!C3) =МАКС(B$1,Distances!C3) Абсолютная ссылка на k-расстояние позволяет вам копировать формулу на весь лист. Скопировав ее до ОК4, выделите вычисления в строке 4 и кликните на них дважды, чтобы распространить на всю таблицу до строки 403. Таким образом заполняются все расстояния достижимости, как показано на рис. 9-19. Сводим воедино все факторы локальных выбросов Теперь все готово к вычислению факторов локальных выбросов для каждого сотрудника. Создайте новую вкладку, назовите ее LOF, а затем вставьте в столбец А персональные номера сотрудников. Как я упоминал ранее, факторы локальных выбросов характеризуют то, как точка выглядит с точки зрения своих соседей относительно того, как выглядят 405
406 Много цифр остальные соседи с такой точки зрения. Если я живу в 30 километрах от города, мои ближайшие соседи могут считать меня деревенщиной, но сами они в то же время считаются среди односельчан членами одного сообщества. Это значит, что локально я в большей степени выброс, чем мои соседи. Нужно запечатлеть этот феномен. Эти значения держатся на средней достижимости каждого сотрудника его k ближайшими соседями. Рис. 9-19. Все расстояния достижимости Пусть работник 144624 находится у нас в строке 2. Значение k уже установлено на 5. Вопрос в том, каково среднее расстояние достижимости 144624 его пятью ближайшими соседями? Чтобы его вычислить, выберите вектор из единиц в таблице Rank для пяти сотрудников, ближайших к 144624, и из нулей для кого-нибудь еще (вы делали нечто похожее во вкладке K-Distance). Такой вектор можно создать с помощью оператора IF//ЕСЛИ, собрав всех соседей с высоким рангом, но исключив самого работника: IF(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*IF(Rank!B2:OK2>0,1,0) ЕСЛИ(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*ЕСЛИ(Rank!B2:OK2>0,1,0) Умножьте этот вектор-индикатор на расстояния достижимости 144624, сложите результаты и разделите все на k= 5. В ячейке В2 у вас получится:
9. Определение выбросов: выделяющиеся не значит важные =SUM(IF(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*IF(Rank!B2: OK2>0,1,0)*‘Reach-dist’!B4:OK4)/’K-Distance’!B$1} =СУММ(ЕСЛИ(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*ЕСЛИ(Rank!B2: OK2>0,1,0)*‘Reach-dist’!B4:OK4)/’K-Distance’!B$1} Как только вы вычислили k-расстояние, эта формула становится формулой массива. Распространите ее на всю таблицу, кликнув на ней дважды (рис. 9-20). Таким образом, в этом столбце отображается то, как выглядит каждый сотрудник с точки зрения пяти своих ближайших соседей. Фактор локального выброса для сотрудника — это среднее значение отношений расстояний достижимости этого сотрудника, разделенное на средние достижимости каждого из k своих соседей. Рис. 9-20. Средняя достижимость каждого сотрудника относительно его соседей Сначала мы выполним расчет ФЛВ для сотрудника 144624 в ячейке С2. Как и в предыдущих расчетах, оператор IF//ЕСЛИ дает нам вектор из единиц для пяти ближайших соседей 144624: IF(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*IF(Rank!B2:OK2>0,1,0) ЕСЛИ(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*ЕСЛИ(Rank!B2:OK2>0,1,0) Затем мы умножаем это на отношение средней достижимости 144624, разделенное на среднюю достижимость каждого из соседей: 407
408 Много цифр IF(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*IF (Rank!B2:OK2>0,1,0)*B2/TRANSPOSE(B$2:B$401) ЕСЛИ(Rank!B2:OK2<=’K-Distance’!B$1,1,0)*ЕСЛИ (Rank!B2:OK2>0,1,0)*B2/ТРАНСП(B$2:B$401) Обратите внимание: в формуле массива используются фигурные скобки. Нажмите Ctrl+Shift+Enter (Command+Return в MacOS) чтобы получить ФЛВ для 144624. Результат равен 1,34, что несколько больше единицы. Это значит, что данный сотрудник в некоторой степени является локальным выбросом. Раскопируйте эту формулу на всю таблицу двойным кликом, а затем проверьте остальных работников. Условное форматирование поможет найти самые значительные выбросы. Например, промотав таблицу вниз до конца, вы обнаруживаете, что сотрудник 143406, штатный халтурщик, — самая отдаленная точка с ФЛВ, равным 1,97 (рис. 9-21). Его соседи видят его вдвое дальше, чем другие соседи видят их самих. Это довольно далеко от группы. Рис. 9-21. ФЛВ сотрудников. Кое-кто вплотную подошел к 2 Вот и все! Теперь у вас есть по одному значению, соотнесенному с каждым сотрудником, которое ранжирует его как локальный выброс и измеряется независимо от размера графа. Великолепно!
9. Определение выбросов: выделяющиеся не значит важные Подытожим Между главой о модулярности графа и данной главой про определение выбросов вы столкнулись с мощью анализа данных на графе, то есть с соотнесением расстояний и ребер между наблюдениями. В отличие от глав про кластеризацию, где группы изучались на предмет наличия общего признака, здесь данные исследовались на предмет точек, находящихся вне групп. Вы были свидетелями простой силы степени полузахода, демонстрирующей, кто влиятелен, а кто изолирован. Больше информации об определении выбросов можно найти в обзоре SIAM 2010, скомпилированном Кригелем, Крогером и Зимеком, по адресу конференции SIAM http://www.siam.org/meetings/sdm10/tutorial3.pdf. Там показаны все техники из этой главы, а также несколько других. Обратите внимание, что эти модели, в отличие от других, не требуют никакого изнурительного процесса. Для получения ФЛВ существует конечное количество шагов, так что их довольно просто программировать для промышленных нужд вместе с базами данных. Если вы ищете подходящий язык программирования для этих целей — R отлично подойдет. Функция bplot строит ящичковые диаграммы данных со встроенными границами Тьюки. Способность отображать последние графически в Excel так ужасна, что я даже не буду пробовать описать ее в этой книге. Пакет DmwR для R (который сопровождает чудесную книгу Торго Data Mining with R [Chapman and Hall, 2010]) содержит ФЛВ в функции под названием lofactor. Для построения и анализа степени вершин на графе также есть отличный пакет для R — igraph. 409

10 П Переходим от таблиц к программированию осле того, как на протяжении всех девяти предыдущих глав я «внутривенно» вводил вам Excel, пришло время сказать: бросаем! Ну, не совсем, но будем честны: Excel идеален не для всех статистических задач. Excel прекрасен для изучения аналитики, потому что в нем можно посмотреть и «потрогать» данные на любом этапе превращения их алгоритмом из вводных в результат. Но вы пришли, посмотрели, научились —и наверняка задались вопросом: неужели обязательно каждый раз делать все эти шаги вручную? К примеру, действительно ли нужно настраивать оптимизацию под каждую свою логистическую регрессию? Или самостоятельно вводить определения вроде близости косинусов? Теперь, когда вы изучили все это, вам разрешается немного схитрить… и заставить кого-то другого сделать нудную работу за вас! Думайте о себе как Вольфганг Пак . Готовит ли он сам во всех своих ресторанах? Я очень надеюсь, что нет. После изучения вам тоже должно быть доступно использование написанного другими с помощью этих алгоритмов. Вышесказанное — одна из многих причин, (как и ссылки из одного слова на всю таблицу с данными), по которым настало время перейти от Excel к языку программирования R, ориентированному на статистику и аналитику. В этой последней главе мы снова решим некоторые задачи из других глав, но уже не в Excel, а в R — с теми же данными, теми алгоритмами, но в другой среде. Вы увидите, насколько все просто! Сразу предупрежу: эта глава — не учебник R. Мы будем двигаться со скоростью тысяча миль в час, чтобы изловчиться вместить все требуемые алгоритмы в одну главу. Если вы чувствуете необходимость более обстоятельного введения, обратитесь к списку книг в конце главы. Также вынужден предупредить: если вы не прочитали до конца какую-то из предыдущих глав, то эту можете и не начинать. В ней я исхожу из того, что вы знакомы с данными, задачами и методами из предыдущих глав. Моя
412 Много цифр книга — не из разряда «выбери себе приключение». Дочитывайте то, что не дочитали, и возвращайтесь! Налаживаем контакт с R R можно скачать с сайта www.r-project.org. Нажмите на ссылку загрузки, выберите ближайшее зеркало и скачивайте установщик для вашей ОС. Запустите его (в Windows лучше устанавливать программы под учетной записью администратора) и откройте приложение. В Windows и MacOS загрузится консоль R. Выглядит она примерно так, как показано на рис. 10-1. Рис. 10-1. Консоль R в MacOS В этой консоли после значка > печатаются команды, которые запускаются нажатием клавиши Return (Enter в Windows). Вот такие: > print("No regrets. Texas forever.") [1] "No regrets. Texas forever." > 355/113 [1] 3.141593 Чтобы система вывела вам текст или содержимое файла, вызывайте функцию print. Еще можно задавать ей арифметические выражения, а она будет вычислять результат. А вот моя стандартная схема работы:
10. Переходим от таблиц к программированию Загрузить данные в R. • Поделать с ними разные научные штуки. • Вытащить результаты из R, чтобы другие люди или процессы могли ими • пользоваться. Когда наступает время делать первый шаг, то есть переносить данные в R, приходится выбирать из множества вариантов. Чтобы лучше понять переменные и типы данных, начнем с введения их вручную. Пошевелим пальцами Самый простой способ поместить данные в R — точно такой же, как и в Excel. Введение данных вручную и запись нажатий клавиш. Можете начать с сохранения одного значения в переменной: > almostpi <- 355/113 > almostpi [1] 3.141593 > sqrt(almostpi) [1] 1.772454 В этой маленькой части кода вы сохранили 355/113 в переменной под названием almostpi («почти пи» — англ.). Вбив затем переменную обратно в консоль и нажав Return/Enter, выведите на экран ее содержимое. Теперь с этой переменной можно делать множество вещей (в моем примере — извлечь квадратный корень). Краткий справочник многих встроенных в R функций (тех, что доступны без загрузки дополнительных пакетов… они вам пригодятся позже) находится здесь: http://cran.r-project.org/doc/contrib/Short-refcard.pdf. Чтобы понять, алгоритм действия функции, просто поставьте перед ее названием вопросительный знак в консоли: > ?sqrt Тогда после нажатия клавиши Return/Enter появится всплывающее окно справки по функции (рис. 10-2 показывает такое окно для функции sqrt). Можете напечатать даже перед функцией два вопросительных знака, чтобы найти какую-либо информацию, например: ??log Поиск по слову log приводит к результатам, изображенным на рис. 10-3. 413
414 Много цифр ЗАМЕТКА Существует невероятное множество отличных ресурсов для поиска доступных вам в R функций или пакетов, кроме дурацкого «??». К примеру, rseek.org — отличный поисковик по всему связанному с R. Конкретные же вопросы можно задавать здесь: stackoverflow.com (http://stackoverflow.com/questions/tagged/r) или писать сюда: www.r-project.org/mail.html. Рис. 10-2. Окно справки для функции квадратного корня
10. Переходим от таблиц к программированию Векторная алгебра и факторинг Числовой вектор можно вставить с помощью функции с() (с здесь означает combine — «объединять»). Запустим в переменную немного простых чисел : > someprimes <- 0(1,2,3,5,7,11) > someprimes [1] 1 2 3 5 7 11 Рис. 10-3. Результаты поиска по слову log Функция Length() («длина» — англ.) поможет вам сосчитать количество элементов вектора: > length(someprimes) [1] 6 А квадратные скобки — обратиться к определенному элементу вектора: > someprimes[4] [1] 5 415
416 Много цифр Мы получаем четвертый элемент вектора, которым оказывается 5. Также с помощью с() можно задать несколько элементов вектора или обозначить промежуток двоеточием: > someprimes [с (4, 5,6) ] [1] 5 7 11 > someprimes[4:6] [1] 5 7 11 В обоих этих случаях вы получаете элементы вектора с четвертого по шестой. Также для вызова значений можно использовать логические операторы. К примеру, если вам нужны только простые числа меньше семи, то используйте функцию which(), чтобы получить их номера в векторе: > which(someprimes<7) [1] 12 3 4 > someprimes[which(someprimes<7)] [1] 12 3 5 Поместив данные в переменную, можно выполнять операции надо всем набором, а результат записать в новую переменную. К примеру, умножим все числа на 2 (times 2 — англ.): > primestimes2 <- someprimes*2 > primestimes2 [1] 246 10 14 22 Подумайте, как бы вы это делали в Excel. Ввели бы в соответствующую ячейку формулу и раскопировали бы ее на весь столбец. R позволяет вам озаглавить этот столбец или ряд данных и оперировать им дальше как одной переменной, что гораздо удобнее. Одна полезная функция для проверки данных на странные значения — функция summary: > summary(someprimes) Min. 1st Qu. Median 1.000 2.250 4.000 Mean 4.833 3rd Qu. 6.500 Max. 11.000 И еще можно работать с текстом: > somecolors <- с("blue","red","green","blue", "green","yellow","red","red") > somecolors [1] "blue" "red" "green" "blue" "green" "yellow""red" "red"
10. Переходим от таблиц к программированию Если суммировать somecolors, то вы получите только немного описательных данных: summary(somecolors) Length Class 8 character Mode character Эти цвета можно рассматривать как категории и превратить этот вектор в категорийные данные, «факторизуя» их: > somecolors <- factor(somecolors) > somecolors [1] blue red green blue green yellow red red Levels: blue green red yellow Просуммировав данные, вы получаете подсчет каждого «уровня» (уровень — это отдельная категория): > summary(somecolors) blue green red yellow 2 2 3 1 Двумерные матрицы Векторы, с которыми мы забавлялись до этого, были одномерными. Есть кое-что чуть больше похожее на электронную таблицу — это матрица, двумерный массив чисел. Можно построить ее функцией matrix: >amatrix<-matrix(data=c(someprimes,primestimes2),nrow=2,ncol=6) >amatrix [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 3 7 2 6 14 [2,] 2 5 11 4 10 22 И сосчитать число столбцов и строк: > nrow(amatrix) [1] 2 > ncol(amatrix) [1] 6 Если захотите транспонировать данные (как делали на протяжении всей книги с помощью опции транспонирования в меню специальной вставки) – воспользуйтесь функцией t(): 417
418 Много цифр > t(amatrix) [,1] [,2] [1,] 1 2 [2,] 3 5 [3,] 7 11 [4,] 2 4 [5,] 6 10 [6,] 14 22 Для выбора отдельных записей или промежутков используйте те же квадратные скобки, только ссылки на столбцы и строки нужно разделять запятыми: > amatrix[1:2,3] [1] 7 11 Здесь мы получили значения строк с 1 по 2 для столбца 3. Впрочем, особой нужды ссылаться на обе строки, 1 и 2 нет, потому что в данной матрице больше нет строк. Вместо этого можно просто не писать ничего на месте ссылки на строку — и вы получите содержимое всей строки: > amatrix[,3] [1] 7 11 Функции rbind() и cbind() помогут пристроить в матрице новые строки или столбцы данных: > primestimes3 <- someprimes*3 > amatrix <- rbind(amatrix,primestimes3) > amatrix [,1] [,2] [,3] [,4] [,5] [,6] 1 3 7 2 6 14 2 5 11 4 10 22 primestimes3 3 6 9 15 21 33 Здесь вы создали новую строку данных (primestimes3) и использовали rbind(), чтобы приклеить ее к переменной amatrix и записать результат обратно в amatrix. Самый лучший тип данных из всех: датафрейм (dataframe) Датафрейм— идеальный способ работы с реальным миром, база данных, похожая на таблицу в R. Датафрейм в R — это особая версия типа данных «list». Так что же такое list? List («список», англ.) — это коллекция объектов в R, которые могут быть разного типа. К примеру, вот list правдивой информации о вашем покорном слуге:
10. Переходим от таблиц к программированию > John<-list(gender="male", age="ancient", height = 72, spawn = 3, spawn_ages = с(.5,2,5)) > John $gender [1] "male" $age [1] "ancient" $height [1] 72 $spawn [1] 3 $spawn_ages [1] 0.5 2.0 5.0 Датафрейм — это такой тип подобного списка, чрезвычайно похожего на таблицу Excel. В принципе это двумерная таблица, ориентированная по столбцам, которые могут считаться численными или категорийными векторами. Создать датафрейм можно, вызвав функцию data.frame() для импортированных или вбитых вручную данных. Для иллюстрации следующего примера я использовал данные из фильмов о Джеймсе Бонде. Сначала создайте несколько векторов: > bondnames <- с("connery","lazenby","moore","dalton", "brosnan","craig") > firstyear <- с(1962,1969,1973,1987,1995,2006) > eyecolor <- с("brown","brown","blue", "green", "blue", "blue") > womenkissed <- с(17,3,20,4,12,4) > countofbondjamesbonds <- с(3,2,10,2,5,1) Итак, на данном этапе у нас 5 векторов — численных и текстовых — и все одинаковой длины. Скомбинируйте их в один датафрейм под названием bonddata: > bonddata <- data.frame(bondnames,firstyear,eyecolor,womenkissed, countofbondjamesbonds) > bonddata bondnames firstyear eyecolor womenkissed countofbondjamesbonds 1 connery 1962 brown 17 3 2 lazenby 1969 brown 3 2 3 moore 1973 blue 20 10 4 dalton 1987 green 4 2 5 brosnan 1995 blue 12 5 6 craig 2006 blue 4 1 419
420 Много цифр Функция dataframe позаботится о распознавании того, что в этих столбцах является фактором, а что — числом. Убедитесь в разнице, вызвав функции str() и summary(): > str(bonddata) 'data.frame': 6 obs. of 5 variables: $bondnames : Factor w/ 6 levels "brosnan","connery: 2 5 6 4 1 3 $firstyear : num 1962 1969 1973 1987 1995 ... $eyecolor : Factor w/ 3 levels "blue","brown": 2 2 1 3 1 1 $womenkissed : num 17 3 20 4 12 4 $countofbondjamesbonds : num 3 2 10 2 5 1 > summary(bonddata) bondnames firstyear eyecolor womenkissed countofbondjamesbonds brosnan:1 Min. :1962 blue :3 Min. : 3.00 Min. : 1.000 connery:1 1st Qu.:1970 brown:2 1st Qu.: 4.00 1st Qu.: 2.000 craig :1 Median :1980 green:1 Median : 8.00 Median : 2.500 dalton :1 Mean :1982 Mean :10.00 Mean : 3.833 lazenby:1 3rd Qu.:1993 3rd Qu.:15.75 3rd Qu.: 4.500 moore :1 Max. :2006 Max. :20.00 Max. :10.000 Обратите внимание, что год считается числом. Можно факторизовать этот столбец с помощью функции factor(), если хотите считать его категорийным. Самое прекрасное в датафреймах — то, что можно ссылаться на столбцы, используя значок $ и название столбца, как показано: > bonddata$firstyear <- factor(bonddata$firstyear) > summary(bonddata) bondnames firstyear eyecolor womenkissed countofbondjamesbonds brosnan:1 1962:1 blue :3 Min. : 3.00 Min. : 1.000 connery:1 1969:1 brown:2 1st Qu.: 4.00 1st Qu.: 2.000 craig :1 1973:1 green:1 Median : 8.00 Median : 2.500 dalton :1 1987:1 Mean :10.00 Mean : 3.833 lazenby:1 1995:1 3rd Qu. :15.75 3rd Qu.: 4.500 moore :1 2006:1 Max. :20.00 Max. :10.000 При запуске функции summary годы считаются как категорийные данные, а не числовые. Также не забывайте, что когда бы вы ни транспонировали датафрейм, результатом будет являться старая добрая двумерная матрица, а не другой датафрейм. И это, безусловно, имеет смысл — ведь в транспонированной версии данных о Бонде нет соответствующего типа данных в каждом столбце.
10. Переходим от таблиц к программированию Чтение данных в R ЗАМЕТКА Файл CSV, использованный в этой части, WineKMC.csv, можно загрузить на сайте книги, www.wiley.com/go/datasmart. Отлично! Мы научились складывать данные в различные типы данных вручную, но как быть с теми, что записаны в файл? Первое, что нужно усвоить — это понятие «рабочая директория». Рабочая директория — это папка, в которую вы записываете данные, чтобы консоль R могла их найти и прочитать. Функция getwd() отображает текущую рабочую директорию: > getwd() [1] "/Users/johnforeman/RHOME" Если вам она не нравится, можете сменить ее командой setwd(). Помните: даже на компьютерах с Windows R считает, что директории должны быть разделены правым слэшем. К примеру, setwd("/Users/johnforeman/datasmartfiles") Используйте эту команду для установки своей рабочей директории — места, где вы будете хранить свои данные. Начните с помещения в эту директорию файла WineKMC.csv. Это файл с данными, разделенными запятыми, из вкладки Matrix книги кластеризации по k-средним из главы 2. Давайте прочитаем его. Для чтения используйте функцию read.csv(): > winedata <- read.csv("WineKMC.csv") Эти данные должны выглядеть в точности как вкладка Matrix из главы 2. Выведя на экран первые несколько столбцов (я выбрал 9, чтобы уместились на странице), вы увидите описательные данные о каждом из 32 предложений, на которые откликались покупатели. Они отражены в векторах, записанных в столбцах: > winedata[,1:9] Offer Mth Varietal 1 1 Jan Malbec 2 2 Jan Pinot Noir 3 3 Feb Espumante MinQty Disc 72 56 72 17 144 32 Origin PastPeak Adams Allen France FALSE NA NA France FALSE NA NA Oregon TRUE NA NA 421
422 Много цифр 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 4 Feb Champagne 5 Feb Cab. Sauv. 6 Mar Prosecco 7 Mar Prosecco 8 Mar Espumante 9 Apr Chardonnay 10 Apr Prosecco 11 May Champagne 12 May Prosecco 13 May Merlot 14 Jun Merlot 15 Jun Cab. Sauv. 16 Jun Merlot 17 Jul Pinot Noir 18 Jul Espumante 19 Jul Champagne 20 Aug Cab. Sauv. 21 Aug Champagne 22 Aug Champagne 23 Sept Chardonnay 24 Sept Pinot Noir 25 Oct Cab. Sauv. 26 Oct Pinot Noir 27 Oct Champagne 28 Nov Cab. Sauv. 29 Nov P. Grigio 30 Dec Malbec 31 Dec Champagne 32 32 Dec Cab. Sauv. 72 144 144 6 6 144 72 72 72 6 72 144 72 12 6 12 72 12 72 144 6 72 144 72 12 6 6 72 72 48 France 44 NZ 86 Chile 40 Australia 45 S. Africa 57 Chile 52 CA 85 France 83 Australia 43 Chile 64 Chile 19 Italy 88 CA 47 Germany 50 Oregon 66 Germany 82 Italy 50 CA 63 France 39 S. Africa 34 Italy 59 Oregon 83 Australia 88 NZ 56 France 87 France 54 France 89 France 45 Germany TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE NA NA NA NA NA NA NA NA NA NA NA NA NA NA 1 NA NA NA NA NA NA NA NA NA NA 1 1 NA NA NA NA NA NA 1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 1 NA NA NA NA TRUE NA NA Все уместилось! Однако нельзя не заметить, что пустые ячейки в векторах (которые Excel воспринимает как 0) превратились в NA. Нужно превратить их обратно в 0 с помощью функции is.na() внутри квадратных скобок: > winedata[is.na(winedata)] <- 0 > winedata[1:10,8:17] Adams Allen Anders Bailey Baker 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 5 0 0 0 0 0 Barnes Bell Bennett 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 Brooks Brown 0 0 0 0 1 0 0 0 0 0
10. Переходим от таблиц к программированию 6 7 8 9 10 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 Бах! NA превратились в 0. Настоящая научная работа с данными Итак, вы научились работать с переменными и типами данных, вбивать данные вручную и читать их из файлов CSV. Но как на самом деле используются алгоритмы, рассмотренные в этой книге? Поскольку у вас уже есть загруженные данные о вине, начнем с небольшой кластеризации по k-средним. Сферическое k-среднее винных данных в нескольких линиях В этом разделе мы проведем кластеризацию на основе близости косинусов (которая также называется сферическим k-средним). Скачайте и загрузите в R пакет сферического k-среднего под названием skmeans. Для справки; skmeans не является частью R, он написан сторонними специалистами. Эти гении сделали всю работу за вас, а вам осталось только с благодарностью пользоваться плодами их трудов. Как и большинство пакетов для R, этот пакет вы можете установить (почитав об этом, если требуется) из Comprehensive RArchive Network (CRAN). CRAN — это хранилище многих полезных пакетов для расширения функциональности R. Их список находится здесь: http://cran.r-project.org/web/packages/. Вбейте в поиск rseek.org «shperical k-means». Первым «выскочит» PDF, описывающий этот пакет. Функция, которую вы ищете, называется skmeans(). R изначально настроена на загрузку пакетов с CRAN, так что для загрузки skmeans можно использовать функцию R install.packages() (R может попросить установить персональную библиотеку при первом запуске): > install.packages("skmeans",dependencies = TRUE) trying URL 1 http://mirrors.nics.utk.edu/cran/bin/macosx/leopard/ contrib/2.15/skmeans_0.2-3.tgz' Content type 1application/x-gzip' length 224708 bytes (219 Kb) opened URL ================================================================ downloaded 219 Kb 423
424 Много цифр Видите, как в коде я установил значение dependencies=TRUE в запросе на установку. Теперь я уверен в том, что если пакет skmeans зависит от какихлибо других пакетов, R загрузит и их тоже. По запросу соответствующий моей версии R пакет (у меня 2.15 для MacOS) загружается с зеркала сайта и инсталлируется в положенное место. Сам пакет можно загрузить с помощью функции library(): library(skmeans) Чтобы узнать, как пользоваться skmeans(), наберите перед названием функции? Документация определяет свойство skmeans() принимать матрицы, в которых каждый столбец соотнесен с объектом или кластером. Ваши данные ориентированы по столбцам с кучей описательных параметров сделок в начале, которые не будут видны алгоритму. Поэтому нужно их транспонировать (обратите внимание, что функция транспонирования делает матрицу из датафрейма). С помощью функции ncol() видно, что столбцы покупателей идут до 107, так что вы можете выбрать только векторы покупок в строках для каждого покупателя, транспонировав данные из столбцов с 8 по 107 и записав их в новую переменную под названием winedata.transposed: > ncol(winedata) [1] 107 > winedata.transposed <- t(winedata[,8:107]) > winedata.transposed[1:10,1:10] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8][,9] [,10] Adams 0 0 0 0 0 0 0 0 0 0 Allen 0 0 0 0 0 0 0 0 1 0 Anders 0 0 0 0 0 0 0 0 0 0 Bailey 0 0 0 0 0 0 1 0 0 0 Baker 0 0 0 0 0 0 1 0 0 1 Barnes 0 0 0 0 0 0 0 0 0 1 Bell 0 1 0 0 0 0 0 0 0 0 Bennett 0 0 0 0 0 0 0 1 0 0 Brooks 0 0 1 0 0 0 0 1 0 0 Brown 0 0 0 0 0 0 1 0 0 0 Примените функцию skmeans к набору данных, чтобы получить пять средних значений и использовать генетический алгоритм (похожий на тот, что мы использовали в Excel). Результаты запишите обратно в объект winedata. clusters:
10. Переходим от таблиц к программированию > winedata.clusters <- skmeans(winedata.transposed, 5, method="genetic") Обратившись затем к этому объекту из консоли, можно получить отчет о его содержимом (ваши результаты наверняка отличаются, ведь мы пользовались алгоритмом оптимизации): > winedata.clusters A hard spherical к-means partition of 100 objects into 5 classes. Class sizes: 16, 17, 15, 29, 23 Call: skmeans(x = winedata.transposed, к = 5, method = "genetic") Вызывая str() для кластерного объекта, убедитесь, что текущие кластерные соотнесения хранятся в списке «cluster»: > str(winedata.clusters) List of 7 $ prototypes: num [1:5, 1:32] 0.09 0.153 0 0.141 0 ... ..- attr(*, "dimnames")=List of 2 .. ..$ : chr [1:5] "I" "2" "3" "4" ... .. ..$ : NULL $ membership : NULL $ cluster : int [1:100] 5 4 1 5 2 2 1 3 3 5 ... $ family : List of 7 ..$ description: chr "spherical k-means" ..$ D : function (x, prototypes) ..$ С : function (x, weights, control) ..$ init : function (x, k) ..$ e : num 1 ..$ .modify : NULL ..$ .subset : NULL ..- attr(*, "class")= chr "pclust_family" $ m : num 1 $ value : num 38 $ call : language skmeans(x = winedata.transposed, к = 5, method = "genetic") - attr(*, "class")= chr [1:2] "skmeans" "pclust" Если вы, к примеру, хотите посмотреть кластерное соотнесение для строки 4, используйте матричную запись кластерного вектора: > winedata.clusters$cluster[4] [1] 5 425
426 Много цифр Каждая строка называется фамилией покупателя (вы сами их так назвали, когда читали их функцией read.csv()), так что соотнесения можно искать также по ним, пользуясь функцией row.names () вместе с which(): > winedata.clusters$cluster[ which(row.names(winedata.transposed)=="Wright") ] [1] 4 Более того, если понадобится, вы можете выписать все эти кластерные отнесения функцией write.csv(). Воспользуйтесь ?, чтобы узнать, как она работает. Спойлер: очень похоже на read.csv(). Во время работы с Excel вы «расшифровывали» кластер, понимая поведение параметров описания сделок, определяющих их. Вы считали общее количество сделок, совершенных в каждом кластере, и сортировали их. Как сделать что-то подобное в R? Для выполнения расчетов подойдет aggregate(), где в поле «by» нужно выбрать конкретные элементы кластера — то есть «собрать (aggregate — англ.) заказы по элементам». Также выберете тип группировки по своему желанию: сумму по сравнению со средним, минимумом, максимумом, медианой и т. д.: aggregate(winedata.transposed, by=list(winedata.clusters$cluster),sum) Используйте транспонирование, чтобы сохранить эти значения в кластере в виде пяти столбцов (прямо как в Excel), — и вы обрежете первую строку группы, которая просто возвращает фамилии элементов кластера. Затем сохраните все это в переменной winedata.clustercounts: > winedata.clustercounts <-t(aggregate(winedata.transposed, by=list (winedata.clusters$cluster),sum) [,2:33]) > winedata.clustercounts VI V2 V3 V4 V5 V6 V7 V8 V9 [,1] 2 7 0 0 0 0 0 0 0 [,2] 5 3 2 5 0 8 3 1 2 [,3] 0 0 3 1 0 1 1 15 0 [,4] 3 0 0 6 4 3 0 0 8 [,5] 0 0 1 0 0 0 15 4 0
10. Переходим от таблиц к программированию VI0 VI1 V12 V13 V14 VI5 V16 V17 V18 VI9 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 1 0 1 0 0 0 1 7 0 0 0 0 0 1 12 0 12 1 0 0 0 0 0 4 7 3 0 3 3 1 0 1 4 2 1 17 1 0 3 0 4 5 1 4 16 2 1 1 0 2 0 0 0 0 4 1 0 1 2 0 0 0 0 1 0 4 4 1 0 0 4 0 0 6 3 3 0 0 0 4 1 2 3 0 3 3 3 0 0 1 0 2 1 1 1 4 0 0 0 0 9 0 0 1 0 0 0 0 0 0 1 12 13 0 0 И вот, наконец, — количество сделок по кластерам. Приделаем эти семь столбцов описательных данных обратно к сделкам с помощью функции cbind(): > winedata.desc.plus.counts <cbind(winedata[,1:7],winedata.clustercounts) > winedata.desc.plus.counts Offer Mth Varietal MinQty Disc Origin PastPeak 1 2 3 4 5 V1 1 Jan Malbec 72 56 France FALSE 2 5 0 3 0 V2 2 Jan Pinot Noir 72 17 France FALSE 7 3 0 0 0 V3 3 Feb Espumante 144 32 Oregon TRUE 0 2 3 0 1 V4 4 Feb Champagne 72 48 France TRUE 0 5 1 6 0 V5 5 Feb Cab. Sauv. 144 44 NZ TRUE 0 0 0 4 0 V6 6 Mar Prosecco 144 86 Chile FALSE 0 8 1 3 0 V7 7 Mar Prosecco 6 40 Australia TRUE 0 3 1 0 15 V8 8 Mar Espumante 6 45 S. Africa FALSE 0 1 15 0 4 V9 9 Apr Chardonnay 144 57 Chile FALSE 0 2 0 8 0 VI0 10 Apr Prosecco 72 52 CA FALSE 1 4 1 0 1 VI1 11 May Champagne 72 85 France FALSE 0 7 1 4 1 427
428 Много цифр V12 V13 V14 VI5 V16 V17 V18 VI9 V2 0 V21 V22 V23 V24 V25 V26 V27 V28 V2 9 V3 0 V31 V32 12 May 13 May 14 Jun 15 Jun 16 Jun 17 Jul 18 Jul 19 Jul 20 Aug 21 Aug 22 Aug 23 Sept 24 Sept 25 Oct 26 Oct 27 Oct 28 Nov 29 Nov 30 Dec 31 Dec 32 Dec Prosecco Merlot Merlot Cab. Sauv. Merlot Pinot Noir Espumante Champagne Cab. Sauv. Champagne Champagne Chardonnay Pinot Noir Cab. Sauv. Pinot Noir Champagne Cab. Sauv. P. Grigio Malbec Champagne Cab. Sauv. 72 6 72 144 72 12 6 12 72 12 72 144 6 72 144 72 12 6 6 72 72 83 Australia 43 Chile 64 Chile 19 Italy 88 CA 47 Germany 50 Oregon 66 Germany 82 Italy 50 CA 63 France 39 S. Africa 34 Italy 59 Oregon 83 Australia 88 NZ 56 France 87 France 54 France 89 France 45 Germany FALSE 1 3 FALSE 0 0 FALSE 0 3 FALSE 0 3 FALSE 1 1 FALSE 7 0 FALSE 0 1 FALSE 0 4 FALSE 0 2 FALSE 0 1 FALSE 0 17 FALSE 1 1 FALSE 12 0 TRUE 0 3 FALSE 12 0 FALSE 1 4 TRUE 0 5 FALSE 0 1 FALSE 0 4 FALSE 0 16 TRUE 0 2 0 2 0 0 0 0 4 1 0 1 2 0 0 0 0 1 0 4 4 1 0 0 1 0 4 6 0 3 0 3 0 0 0 0 9 0 0 4 0 1 1 2 0 3 0 0 0 3 0 3 0 3 0 0 1 0 12 1 13 0 0 2 0 Также данные можно отсортировать функцией order() внутри скобок датафрейма. Вот сортировка для поиска самых популярных сделок для кластера 1. Обратите внимание: я поставил минус перед данными, чтобы отсортировать их по убыванию. Это можно сделать и другим способом — поставив флажок decreasing=TRUE в функции order(): > winedata.desc.plus.counts[order(-winedata.desc.plus.counts[,8]),] Offer Mth Varietal MinQty Disc Origin PastPeak 1 2 3 4 5 V24 24 Sept Pinot Noir 6 34 Italy FALSE 12 0 0 0 0 V26 26 Oct Pinot Noir 144 83 Australia FALSE 12 0 0 3 0 V2 2 Jan Pinot Noir 72 17 France FALSE 7 3 0 0 0 V17 17 Jul Pinot Noir 12 47 Germany FALSE 7 0 0 0 0 VI 1 Jan Malbec 72 56 France FALSE 2 5 0 3 0 VI0 10 Apr Prosecco 72 52 CA FALSE 1 4 1 0 1 V12 12 May Prosecco 72 83 Australia FALSE 1 3 0 0 1 V16 16 Jun Merlot 72 88 CA FALSE 1 1 0 3 0 V23 23 Sept Chardonnay 144 39 S. Africa FALSE 1 1 0 3 0 V27 27 Oct Champagne 72 88 NZ FALSE 1 4 1 3 0 V3 3 Feb Espumante 144 32 Oregon TRUE 0 2 3 0 1 V4 4 Feb Champagne 72 48 France TRUE 0 5 1 6 0
10. Переходим от таблиц к программированию V5 V6 V7 V8 V9 VI1 V13 V14 VI5 V18 VI9 V2 0 V21 V22 V25 V28 V2 9 V3 0 V31 5 6 7 8 9 11 13 14 15 18 19 20 21 22 25 28 29 30 31 Feb Mar Mar Mar Apr May May Jun Jun Jul Jul Aug Aug Aug Oct Nov Nov Dec Dec Cab. Sauv. Prosecco Prosecco Espumante Chardonnay Champagne Merlot Merlot Cab. Sauv. Espumante Champagne Cab. Sauv. Champagne Champagne Cab. Sauv. Cab. Sauv. P. Grigio Malbec Champagne 144 144 6 6 144 72 6 72 144 6 12 72 12 72 72 12 6 6 72 V32 32 Dec Cab. Sauv. 72 44 NZ 86 Chile 40 Australia 45 S. Africa 57 Chile 85 France 43 Chile 64 Chile 19 Italy 50 Oregon 66 Germany 82 Italy 50 CA 63 France 59 Oregon 56 France 87 France 54 France 89 France 45 Germany TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE 0 0 0 0 8 1 0 3 1 0 1 15 0 2 0 0 7 1 0 0 2 0 3 0 0 3 0 0 1 4 0 4 1 0 2 0 0 1 1 0 17 2 0 3 0 0 5 0 0 1 4 0 4 4 0 16 1 4 0 3 0 0 15 0 4 8 0 4 1 0 4 6 0 3 0 0 9 0 0 4 0 1 1 2 0 3 0 0 1 0 12 1 13 0 0 TRUE 0 2 0 2 0 При взгляде на самые популярные ссылки становится ясно, что кластер 1 — это кластер пино нуар. (Напоминаю, что ваша нумерация может отличаться. Генетический алгоритм никогда не дает двух одинаковых решений подряд.) А теперь, чтобы повторить все до конца, отбросив разглагольствования, прилагаю код, в котором написана в R большая часть главы 2 этой книги: > setwd("/Users/johnforeman/datasmartfiles") > winedata <- read.csv("WineKMC.csv") > winedata[is.na(winedata)] <- 0 > install.packages("skmeans",dependencies = TRUE) > library(skmeans) > winedata.transposed <- t(winedata[,8:107]) > winedata.clusters <- skmeans(winedata.transposed, 5, method="genetic") > winedata.clustercounts <t(aggregate(winedata.transposed,by=list(winedata.clusters$cluster),sum) [,2:33]) > winedata.desc.plus.counts <-cbind(winedata[,1:7],winedata.clustercounts) > winedata.desc.plus.counts[order(-winedata.desc.plus.counts[,8]),] 429
430 Много цифр Вот и все — от чтения данных из файла до анализа кластеров. Элементарно! Ведь обращение к функции skmeans() берет на себя большую часть сложных расчетов. Ужасно для обучения, прекрасно для работы. Построение моделей ИИ для данных о беременных ЗАМЕТКА Файл CSV, использованный в этой части, Pregnancy.csv, доступен для скачивания на сайте книги, www.wiley.com/go/datasmart. В этом разделе мы воспроизведем некоторые модели предсказания беременности из глав 6 и 7. Точнее, мы построим два классификатора с помощью функции glm() с логистической функцией связи, а также функции randomForest() (которая генерирует деревья, причем любые, от простых «пеньков» до полноценных деревьев принятия решений). Обучающие и тестовые данные разделены на два файла CSV — Pregnancy. csv и Pregnancy_Test.csv. Сохраните их в своей рабочей директории, а потом загрузите в пару датафреймов: >PregnancyDatа<-read.сsv("Pregnancy.csv") >PregnancyData.Test<-read.csv("Pregnancy_Test.csv") Чтобы «прочувствовать» эти данные, запустите над ними summary() и str(). Моментально становится очевидным, что данные пола и типа адреса были загружены как категорийные, но в выведенных функцией str() данных итоговая переменная (1 означает беременных, 0 — «не-беременных») также воспринимается как числовое значение вместо двух разных классов: > str(PregnancyData) 'data.frame': 1000 obs. $ Implied.Gender $ Home.Apt..PO.Box $ Pregnancy.Test $ Birth.Control $ Feminine.Hygiene $ Folic.Acid $ Prenatal.Vitamins $ Prenatal.Yoga $ Body.Pillow $ Ginger.Ale of : : : : : : : : : : 18 variables: Factor w/3 levels Factor w/3 levels int 1 1 1 0 0 0 int 0 0 0 0 0 0 int 0 0 0 0 0 0 int 0 0 0 0 0 0 int 1 1 0 0 0 1 int 0 0 0 0 1 0 int 0 0 0 0 0 0 int 0 0 0 1 0 0 "F","M","U": 2 2 2 3 1 "A","H","P": 1 2 2 2 1 0 0 0 0 ... 1 0 0 0 ... 0 0 0 0 ... 1 0 0 0 ... 1 0 0 1 ... 0 0 0 0 ... 0 0 0 0 ... 0 0 1 0 ...
10. Переходим от таблиц к программированию $ $ $ $ $ $ $ $ Sea.Bands Stopped.buying.ciggies Cigarettes Smoking.Cessation Stopped.buying.wine Wine Maternity.Clothes PREGNANT : : : : : : : : int int int int int int int int 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 ... ... ... ... ... ... ... ... Отличная новость для randomForest() — мы факторизируем эту итоговую переменную в два класса (класс 0 и класс 1), и это значение уже не считается целочисленным! Делается это следующим образом: PregnancyData$PREGNANT <- factor(PregnancyData$PREGNANT) PregnancyData.Test$PREGNANT <- factor(PregnancyData. Test$PREGNANT) Теперь суммирование столбца дает два счетчика элементов для каждого класса, при этом 0 и 1 считаются категориями: > summary(PregnancvData$PREGNANT) 0 1 500 500 Для построения логистической регрессии нужна функция glm(), встроенная в исходный пакет R. Для функции randomForest() вам понадобится инсталлировать пакет randomForest. Также неплохо было бы построить кривые ошибок, которые вы встречали в главах 6 и 7. Для таких графиков есть специальный пакет — ROCR. Установка этих двух пакетов займет совсем немного времени: install.packages("randomForest",dependencies=TRUE) install.packages("ROCR",dependencies=TRUE) library(randomForest) library(ROCR) Ну что ж, данные внутри, пакеты загружены. Пришло время строить модель! Начнем с логистической регрессии: > Pregnancy.lm <- glm(PREGNANT ~ ., data=PregnancyData,family=binomial("logit")) Функция glm() строит линейную модель, которую вы определили как логистическую регрессию, пользуясь опцией family=binomial("logit"). Снабжение функции данными происходит через поле data=PregnancyData. Теперь вам, 431
432 Много цифр наверное, интересно, что значит PREGNANT ~. Это — формула в R. Она означает: «Обучи мою модель прогнозировать столбец PREGNANT с помощью остальных столбцов». Тильда (~) означает «с помощью», а период значит «все остальные столбцы». Конкретное подмножество столбцов также выбираются путем набора их названий: > Pregnancy.lm <- glm(PREGNANT ~ Implied.Gender + Home.Apt..PO.Box + Pregnancy.Test + Birth-Control, data=PregnancyData,family=binomial("logit")) Но вы используете обращение PREGNANT~, потому что для обучения модели хотите использовать все столбцы. После построения линейной модели взгляните на ее коэффициенты и проанализируйте, какие переменные имеют статистическую значимость (подобно проверке на критерий Стьюдента в главе 6), суммируя модель: summary(Pregnancy.lm) Call: glm(formula = PREGNANT ~., family = binomial("logit"), data = PregnancyData) Deviance Residuals: Min IQ -3.2012 -0.5566 Median -0.0246 3Q 0.5127 Max 2.8658 Coefficients: (Intercept) Implied.GenderM Implied.GenderU Home.Apt..PO.BoxH Home.Apt..PO.BoxP Pregnancy.Те st Birth-Control Feminine.Hygiene Folic.Acid Prenatal.Vitamins Prenatal.Yoga Body.Pillow Estimate -0.343597 -0.453880 0.141939 -0.172927 -0.002813 2.370554 -2.300272 -2.028558 4.077666 2.479469 2.922974 1.261037 Std. Error z value 0.180755 -1.901 0.197566 -2.297 0.307588 0.461 0.194591 -0.889 0.336432 -0.008 0.521781 4.543 0.365270 -6.297 0.342398 -5.925 0.761888 5.352 0.369063 6.718 1.146990 2.548 0.860617 1.465 Pr(>|z|) 0.057315 0.021599 0.644469 0.374180 0.993329 5.54e-06 3.03e-10 3.13e-09 8.70e-08 1.84e-ll 0.010822 0.142847 . * *** *** *** *** *** *
10. Переходим от таблиц к программированию Ginger.Ale 1.938502 0.426733 4 .543 5.55e-06 *** Sea.Bands 1.107530 0.673435 1.645 0.100053 Stopped.buying.cig 1.302222 0.342347 3.804 0.000142 *** Cigarettes -1.443022 0.370120 -3.899 9.67e-05 *** Smoking.Cessation 1.790779 0.512610 3.493 0.000477 *** Stopped.buying.win 1.383888 0.305883 4 .524 6.06e-06 *** Wine -1.565539 0.348910 -4.487 7.23e-06 *** Maternity.Clothes 2.078202 0.329432 6.308 2.82e-10 *** --Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Коэффициенты, не имеющие хотя бы одного *, представляют собой сомнительную ценность. Точно так же можно обучить модель случайного леса с помощью функции randomForest(): > Pregnancy.rf <randomForest(PREGNANT~.,data=PregnancyData,importance=TRUE) Синтаксис в целом такой же, как и при вызове функции glm() (выполните ?randomForest, чтобы узнать больше о подсчете деревьев и глубине). Обратите внимание на значение importance=TRUE в вызове. Это позволит вам графически отобразить важность переменных с помощью другой функции, varImpPlot(), которая поможет понять, какие переменные важны, а какие не стоят внимания. Пакет randomForest позволяет оценить вклад каждой переменной в снижение средней загрязненности. Чем он больше, тем важнее переменная. Можете воспользоваться этим, чтобы выбрать и убрать переменные, которые могут вам понадобиться для другой модели. Чтобы взглянуть на эти данные, используйте функцию varImpPlot() с type=2, ранжируя их согласно расчету загрязненности, приведенному в главе 7 (не стесняйтесь использовать команду ?, чтобы прочитать о разнице между type=1 и type=2): varlmpPlot(Pregnancy.rf, type=2) Все это приводит нас к графику ранжировки, изображенному на рис. 10-4. Фолиевая кислота выходит вперед вместе с витаминами и приемом противозачаточных. Теперь, когда вы построили модели, можно приступить к прогнозированию — для этого в R есть функция predict(). Вызовите ее, сохранив результат в две разные переменные, чтобы можно было их сравнить. Принцип работы этой функции в целом таков, что она принимает модель, набор данных для прогнозирования и разные другие специальные опции: 433
434 Много цифр Рис. 10-4. График важности переменных в R > PregnancyData.Test.lm.Preds <predict(Pregnancy.lm,PregnancyData.Test,type="response") > PregnancyData.Test.rf.Preds <predict(Pregnancy.rf,PregnancyData.Test,type="prob") Вызвав predict дважды, вы увидите, что оба раза она работала с разными моделями, тестовыми данными и параметрами type, необходимыми данной модели. В случае линейной модели type="response" устанавливает значения прогноза между 0 и 1, как исходные значения PREGNANT. При работе со случайным лесом type="prob" обеспечивает нам уверенность в том, что в итоге мы получим классовые вероятности — два столбца данных: в одном вероятность покупателя оказаться беременным, в другом — «не-беременным».
10. Переходим от таблиц к программированию Эти результаты выглядят немного по-разному, но, повторюсь, используются разные алгоритмы, разные модели и т. д. Важно «поиграть» с ними и почитать описания. Вот отчет о результате прогноза: summary(PregnancyData.Test.lm.Preds) Min. 1st Qu. Median Mean 3rd Qu. Max. .001179 0.066190 0.239500 0.283100 0.414300 0.999200 summary(PregnancyData.Test.rf.Preds) 0 1 Min. :0.0000 Min. :0.0000 1st Qu.:0.7500 1st Qu.:0.0080 Median :0.9500 Median :0.0500 Mean :0.8078 Mean :0.1922 3rd Qu.:0.9920 3rd Qu.:0.2500 Max. :1.0000 Max. :1.0000 Второй столбец, из прогноза случайного леса, вероятностно ассоциирован с беременностью (а первый, соответственно, с ее отсутствием), так что он чем-то похож на прогноз логистической регрессии. С помощью квадратных скобок выберите отдельные записи или наборы записей, чтобы взглянуть на вводные данные и прогноз (я транспонировал строку, чтобы лучше смотрелось): > t(PregnancyData.Test[1,]) 1 Implied.Gender "U" Home.Apt..PO.Box "A" Pregnancy.Test "0" Birth.Control"0" Feminine.Hygiene "0" Folic.Acid "0" Prenatal.Vitamins "0" Prenatal.Yoga"0" Body.Pillow"0" Ginger.Ale "0" Sea.Bands "I" Stopped.buying.ciggies "0" Cigarettes "0" Smoking.Cessation "0" Stopped.buying.wine "1" Wine "I" 435
436 Много цифр Maternity.Clothes "0" PREGNANT "I" > t(PregnancyData.Test.lm.Preds[1]) 1 [1,] 0.6735358 > PregnancyData.Test.rf.Preds[1,2] [1] 0.504 Обратите внимание: при выводе вводной строки я оставляю номер столбца пустым в квадратных скобках [1,], так что выводится вся строка целиком. Этот конкретный покупатель неизвестного пола, живущий в апартаментах, покупал браслеты от укачивания и вино, но вино затем покупать перестал. Логистическая регрессия дает ему 0,67 баллов, а случайный лес — 0,5. В данном случае покупательница действительно беременна — очко в пользу логистической регрессии! Теперь у вас есть два вектора классовой вероятности для каждого из вариантов. Сравните модели в терминах действительно положительных значений и значений ложноположительных, как мы делали ранее в этой книге. К счастью для вас, пакет ROCR для R способен рассчитать и построить кривые ошибок, так что вам не придется заниматься этим вручную. Так как вы уже загрузили пакет ROCR, первое, что нужно сделать — это создать в нем два объекта предсказания с помощью функции ROCR prediction(). Эта функция считает количество прогнозов положительного и отрицательного классов на границах различных уровней классовых вероятностей: > pred.lm <prediction(PregnancyData.Test.lm.Preds, PregnancyData.Test$PREGNANT) > pred.rf <prediction(PregnancyData.Test.rf.Preds[,2], PregnancyData.Test$PREGNANT) Обратите внимание: во втором вызове вы попадаете во второй столбец классовых вероятностей (прогноз случайного леса), как обсуждалось ранее. Затем можно превратить эти объекты прогнозирования в рабочие объекты ROCR, запустив над ними функцию performance(). Такой объект принимает классификацию, данную моделью в тестовом наборе для различных граничных значений, и использует их для построения кривой вашего выбора (в нашем случае кривой ошибок): > perf.lm <- performance(pred.lm,"tpr"fpr") > perf.rf <- performance(pred.rf,"tpr","fpr")
10. Переходим от таблиц к программированию ЗАМЕТКА Для любопытных: у performance() много других способностей, кроме tpr и fpr, например prec для точности и rec для отклика. Все они подробно описаны в документации ROCR. Визуализируйте эти кривые функцией plot(). Сначала кривую линейной модели (флажки xlim и ylim используются для установки нижней и верхней границ по осям x и y): > plot(perf.lm/xlim=c(0,1),ylim=c(0,1)) Кривую случайного леса можно построить, добавив флажок add=TRUE, чтобы наложить ее сверху, и lty=2(lty— сокращение от line type, тип линии; подробнее можно узнать из описания функции ?plot): plot(perf.rf/xlim=c(0,1),ylim=c(0,1),lty=2,add=TRUE) На рис. 10-5 мы видим две линии: сплошную кривую линейной модели и пунктирную — модели случайного леса. По большей части логистическая регрессия превосходит выборку случайного леса, который вырывается вперед только в крайней правой части графика. Рис. 10-5. Отклик и точность, отображенные в R 437
438 Много цифр Итак, мы освоили две разные прогностические модели, использовали их на тестовом наборе и сравнили их точность и отклик с помощью следующего кода: > PregnancyData <- read.сsv("Pregnancy.сsv") > PregnancyData.Test <- read.csv("Pregnancy_Test.csv") > PregnancyData$PREGNANT <- factor(PregnancyData$PREGNANT) > PregnancyData.Test$PREGNANT <- factor(PregnancyData. Test$PREGNANT) > install.packages("randomForest",dependencies=TRUE) > install.packages("ROCR",dependencies=TRUE) > library(randomForest) > library(ROCR) > Pregnancy.lm <- glm(PREGNANT ~ ., data=PregnancyData,family=binomial("logit")) > summary(Pregnancy.lm) > Pregnancy.rf <randomForest(PREGNANT-.,data=PregnancyData,importance=TRUE) > PregnancyData.Test.rf.Preds <predict(Pregnancy.rf,PregnancyData.Test,type="prob") > varlmpPlot(Pregnancy.rf, type=2) > PregnancyData.Test.lm.Preds <predict(Pregnancy.lm,PregnancyData.Test,type="response") > PregnancyData.Test.rf.Preds <predict(Pregnancy.rf,PregnancyData.Test,type="prob") > pred.lm <prediction(PregnancyData.Test.lm.Preds, PregnancyData.Test$PREGNANT) > pred.rf <prediction(PregnancyData.Test.rf.Preds[,2], PregnancyData.Test$PREGNANT) > perf.lm <- performance(pred.lm,"tpr","fpr") > perf.rf <- performance(pred.rf,"tpr","fpr") > plot(perf.lm,xlim=c(0,1),ylim=c(0,1)) > plot(perf.rf,xlim=c(0,1),ylim=c(0,1),lty=2,add=TRUE) Действительно, довольно простой подход. Особенно если вспомнить сравнение двух разных моделей в Excel.
10. Переходим от таблиц к программированию Прогнозирование в R ЗАМЕТКА Файл CSV, использованный в этом разделе, можно скачать с сайта книги, www.wiley. com/go/datasmart. Этот раздел поистине безумен. Почему? Потому что мы регенерируем прогноз экспоненциального сглаживания из главы 8 так быстро, что голова кружится. Для начала загрузим данные спроса на мечи в SwordDemand.csv и выведем его в консоль: > sword <- read.csv("SwordDemand.csv") > sword SwordDemand 1 165 2 171 3 147 4 143 5 164 6 160 7 152 8 150 9 159 10 169 11 173 12 203 13 169 14 166 15 162 16 147 17 188 18 161 19 162 20 169 21 185 22 188 23 200 24 229 25 189 439
440 Много цифр 26 27 28 29 30 31 32 33 34 35 36 218 185 199 210 193 211 208 216 218 264 304 У нас загружено 36 месяцев спроса — просто и со вкусом. Первое, что нужно сделать — сообщить R, что это временной ряд данных. «Информатором» служит функция ts(): sword.ts <- ts(sword,frequency^12,start=c(2010,1)) Мы снабжаем функцию ts() данными, значением частоты (количество наблюдений в единицу времени; в нашем примере — 12 в год) и начальной точкой (в нашем примере — январь 2010). Если вывести sword.ts на экран через терминал, R «запомнит», что его нужно выводить помесячно как таблицу: > sword.ts Jan Feb 2010 165 171 2011 169 166 2012 189 218 Mar 147 162 185 Apr 143 147 199 May 164 188 210 Jun 160 161 193 Jul 152 162 211 Aug 150 169 208 Sep 159 185 216 Oct 169 188 218 Nov 173 200 264 Dec 203 229 304 Отлично! Также можно построить график: > plot(sword.ts) На этом этапе мы готовы прогнозировать, для чего отлично подходит пакет forecast . Смело ищите его на CRAN (http://cran.r-project.org/ package=forecast) или послушайте, как автор рассказывает о нем на YouTube: http://www.youtube.com/watch?v=1Lh1HlBUf8k. Для прогнозирования с помощью этого пакета нужно вызвать функцию forecast() для объекта временного ряда. При этом функция сама определяет подходящий метод. Помните, как мы перебирали техники в главе 8? Функция forecast() сделает это за вас!
10. Переходим от таблиц к программированию Рис. 10-6. График спроса на мечи > install.packages("forecast",dependencies=TRUE) > library(forecast) > sword.forecast <- forecast(sword.ts) Ну вот и все! Прогноз со встроенными прогностическими интервалами сохранен в объекте sword.forecast. Он выглядит так: > sword.forecast Point Forecast Jan 2013 242.9921 Feb 2013 259.4216 Mar 2013 235.8763 Apr 2013 234.3295 May 2013 274.1674 Jun 2013 252.5456 Jul 2013 257.0555 Aug 2013 262.0715 Lo 80 230.7142 246.0032 223.0885 220.6882 256.6893 234.6894 236.7740 238.9718 Hi 80 255.2699 272.8400 248.6640 247.9709 291.6456 270.4019 277.3370 285.1711 Lo 95 224.2147 238.8999 216.3191 213.4669 247.4369 225.2368 226.0376 226.7436 Hi 95 261.7695 279.9433 255.4334 255.1922 300.8980 279.8544 288.0734 297.3993 441
442 Много цифр Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov 2013 2013 2013 2013 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 Dec 2014 279.4771 289.7890 320.5914 370.3057 308.3243 327.6427 296.5754 293.3646 341.8187 313.6061 317.9789 322.9807 343.1975 354.6286 391.0099 252.0149 258.1684 281.9322 321.2097 263.6074 275.9179 245.8459 239.2280 274.0374 247.0271 245.9468 245.1532 255.4790 258.7390 279.4304 306.9392 321.4097 359.2506 419.4018 353.0413 379.3675 347.3049 347.5013 409.5999 380.1851 390.0109 400.8081 430.9160 450.5181 502.5893 237.4774 241.4294 261.4673 295.2198 239.9357 248.5364 218.9913 210.5698 238.1562 211.7823 207.8153 203.9538 209.0436 207.9782 220.3638 321.4768 338.1487 379.7155 445.3917 376.7130 406.7490 374.1594 376.1595 445.4812 415.4299 428.1424 442.0075 477.3513 501.2790 561.6559 450.1820 314.9086 585.4554 243.2992 657.0648 С тем, какой метод выбрал R, можно познакомиться, вбив значение «method» в объект sword.forecast: > sword.forecast$method [1] "ETS(M,A,M)" MAM означает мультипликативную погрешность, добавочный тренд и мультипликативную сезонность. Функция forecast() выбрала экспоненциальное сглаживание Холта–Винтерса. Вам не нужно вообще ничего делать! При построении автоматически получается диаграмма с областями, как на рис. 10-7: plot(sword.forecast) А вот код, повторяющий содержание главы 8: sword <- read.csv("SwordDemand.csv") sword.ts <- ts(sword,frequency=12/start=c(2010,1)) install.packages("forecast",dependencies=TRUE) 1ibrary(forecast) > sword.forecast <- forecast(sword.ts) > plot(sword.forecast) Вот она — прелесть использования пакетов, написанных другими людьми, специально для таких задач!
10. Переходим от таблиц к программированию Рис. 10-7. Диаграмма с областями прогноза спроса Определение выбросов ЗАМЕТКА Файлы, использованные в этом разделе, PregnancyDuration.csv и CallCenter.csv, можно найти на сайте книги, www.wiley.com/go/datasmart. В этом разделе мы повторим в R еще одну главу из книги, чтобы окончательно убедиться в том, насколько это просто. Для начала считайте данные о продолжительности беременности из файла PregnancyDuration.csv, расположенного на сайте книги: > PregnancyDuration <- read.csv("PregnancyDuration.csv") В главе 9 мы вычисляли медиану, первый и третий квартили и внутренние и внешние границы Тьюки. Квартили можно получить простой функцией summary(): 443
444 Много цифр > summary(PregnancyDuration) GestationDays Min. :240.0 1st Qu. :260.0 Median :267.0 Mean :266.6 3rd Qu. :272.0 Max. :349.0 Межквартильный размах оказывается равным 272 минус 260 (другой способ — вызвать встроенную функцию IQR() для столбца GestationDays): > PregnancyDuration.IQR <- 272 - 260 > PregnancyDuration.IQR <- IQR(PregnancyDuration$GestationDays) > PregnancyDuration.IQR [1] 12 Теперь рассчитайте нижние и верхние границы Тьюки: > LowerInnerFence <- 260 - 1.5*PregnancyDuration.IQR > UpperlnnerFence <- 272 + 1.5*PregnancyDuration.IQR > LowerInnerFence [1] 242 > UpperlnnerFence [1] 290 Нам снова пригодится функция which() — для определения точек, вылезающих за границы, и их положения: > which(PregnancyDuration$GestationDays > UpperlnnerFence) [1] 1 249 252 338 345 378 478 913 > PregnancyDuration$GestationDays[ which(PregnancyDuration$GestationDays > UpperlnnerFence) ] [1] 349 292 295 291 297 303 293 296 Конечно, один из лучших способов справиться с задачей — вызвать функцию boxplot(). Она отобразит медиану, первый и третий квартили, границы Тьюки, а также выбросы (при их наличии): boxplot(PregnancyDuration$GestationDays) Так получается диаграмма, изображенная на рис. 10-8.
10. Переходим от таблиц к программированию Границы Тьюки можно превратить во «внешние» границы, изменив флажок ранжировки при вызове функции boxplot() (по умолчанию там стоит 1,5, умноженное на IQR). Установите range=3 — тогда границы Тьюки проводятся по самым крайним точкам 3*IQR: > boxplot(PregnancyDuration$GestationDays, range=3) На рис. 10-9 видно, что выброс всего один — это пресловутая беременность миссис Хадлум сроком в 349 дней. Рис. 10-8. Ящичковая диаграмма данных продолжительности беременности Рис. 10-9. Ящичковая диаграмма с границами Тьюки, выраженными тройным IQR 445
446 Много цифр Также можно сделать и обратное — вывести данные с диаграммы в консоль. Список stats выдает границы и квартили: > boxplot(PregnancyDuration$GestationDavs,range=3)$stats [,l] [1,] 240 [2,] 260 [3,] 267 [4,] 272 [5,] 303 А список out выводит значения выбросов: > boxplot(PregnancyDuration$GestationDays,range=3)$out [1] 349 Итак, это была задача об определении продолжительности беременности. Теперь перейдем к более сложной — поиску выбросов в данных о работе сотрудников службы поддержки. Данные эти находятся в файле CallCenter.csv на сайте книги. Загрузив и вызвав summary, получаем: > CallCenter <- read.csv("CallCenter.csv") > summary(CallCenter) ID AvgTix Rating Min. :130564 Min. :143.1 Min. :2.070 1st Qu. :134402 1st Qu.:153.1 1st Qu.:3.210 Median :137906 Median :156.1 Median :3.505 Mean :137946 Mean :156.1 Mean :3.495 3rd Qu. :141771 3rd Qu.:159.1 3rd Qu.:3.810 Max. :145176 Max. :168.7 Max. :4.810 Tardies Min. :0.000 1st Qu. :1.000 Median :1.000 Mean :1.465 3rd Qu. :2.000 Max. :4.000 Graveyards Min. :0.000 1st Qu. :1.000 Median :2.000 Mean :1.985 3rd Qu. :2.000 Max. :4.000 PercSickOnFri Min. :0.0000 1st Qu.:0.0000 Median :0.2500 Mean :0.3522 3rd Qu.:0.6700 Max. :1.0000 Weekends Min. :0.0000 1st Qu.:1.0000 Median :1.0000 Mean :0.9525 3rd Qu.:1.0000 Max. :2.0000 SickDays Min. :0.000 1st Qu.:0.000 Median :2.000 Mean :1.875 3rd Qu.:3.000 Max. :7.000 EmployeeDevHrs ShiftSwapsReq ShiftSwapsOffered Min. : 0.00 Min. :0.000 Min. :0.00 1st Qu. : 6.00 1st Qu.:1.000 1st Qu. :0.00 Median :12.00 Median :1.000 Median :1.00
10. Переходим от таблиц к программированию Mean :11.97 3rd Qu. :17.00 Max. :34.00 Mean :1.448 3rd Qu.:2.000 Max. :5.000 Mean :1.76 3rd Qu. :3.00 Max. :9.00 Как и в главе 9, необходимо нормализовать и отцентрировать данные. Для этого нужна только функция scale(): CallCenter.scale <- scale(CallCenter[2:11]) summary(CallCenter.scale) AvgTix Min. : 2.940189 1st Qu.:-0.681684 Median :-0.008094 Mean : 0.000000 3rd Qu.: 0.682476 Max. 2.856075 Rating Min. :–3.08810 1st Qu. :-0.61788 Median : 0.02134 Mean : 0.00000 3rd Qu. : 0.68224 Max. : 2.84909 Tardies Min. :-1.5061 1st Qu. :-0.4781 Median :-0.4781 Mean : 0.0000 3rd Qu.: 0.5500 Max. : 2.6062 Graveyards Min. :-2.4981 1st Qu. :-1.2396 Median : 0.0188 Mean : 0.0000 3rd Qu. : 0.0188 Max. : 2.5359 Weekends Min. :-1.73614 1st Qu. : 0.08658 Median : 0.08658 Mean : 0.00000 3rd Qu. : 0.08658 Max. : 1.90930 SickDays Min. :-1.12025 1st Qu. :-1.12025 Median : 0.07468 Mean : 0.00000 3rd Qu. : 0.67215 Max. : 3.06202 PercSickOnFri Min. :-0.8963 1st Qu. :-0.8963 Median :-0.2601 Mean : 0.0000 3rd Qu.: 0.8088 Max. : 1.6486 EmployeeDevHrs Min. :-1.60222 1st Qu.:-0.79910 Median : 0.00401 Mean : 0.00000 3rd Qu.: 0.67328 Max. : 2.94879 ShiftSwapsReq ShiftSwapsOffered Min. :-1.4477 Min. 1st Qu. :-0.4476 1st Qu. Median :-0.4476 Median Mean : 0.0000 Mean 3rd Qu. : 0.5526 3rd Qu. Max. : 3.5530 Max. :–0.9710 :–0.9710 :–0.4193 : 0.0000 : 0.6841 : 3.9942 Подготовив данные, пропустите их через функцию lofactor(), которая находится в пакете DmwR: install.packages("DMwR",dependencies=TRUE) library(DMwR) Вставьте данные и значение k (в этом примере 5, как и в главе 9) — и функция выдаст значения ФЛВ: CallCenter.lof <- lofactor(CallCenter.scale,5) 447
448 Много цифр Данные с самыми большими значениями (ФЛВ обычно несколько выше 1) — самые «выпуклые» точки. К примеру, можно выделить данные, ассоциированные с теми сотрудниками, чей ФЛВ превышает 1,5: > which(CallCenter.lof > 1.5) [1] 299 374 > CallCenter[which(CallCenter.lof > 1.5),] ID AvgTix Rating Tardies Graveyards Weekends 299 374 137155 165.3 4.49 1 3 143406 145.0 2.33 3 1 PercSickOnFri EmployeeDevHrs ShiftSwapsReq 299 0.00 30 1 374 0.83 30 4 SickDays 2 1 0 6 ShiftSwapsOffered 7 0 Это все те же два выдающихся сотрудника, которых мы уже встречали в главе 9. Но какая огромная разница в количестве строк кода, необходимых для данной операции: > > > > > CallCenter <- read.csv("CallCenter.csv") install.packages("DMwR",dependencies=TRUE) library(DMwR) CallCenter.scale <- scale(CallCenter[2:11]) CallCenter.lof <- lofactor(CallCenter.scale,5) Вот и все! Подытожим Мы с вами только что провели быструю и яростную гонку по просторам R, исход которой зависит от трех составляющих. Это: загрузки и работа с данными в R; • поиск и установка необходимых пакетов; • вызов функций для вашего набора данных из этого пакета. • Вся ли это информация, которую нужно знать для работы в R? Нет. Я не коснулся написания собственных функций, огромной части построения графиков и визуализации, связи с базами данных, уймы возможностей функции apply() и т. д. Но я надеюсь, что теперь вам захочется узнать больше. Есть множество отличных книг про R в продолжение этой главы. Вот некоторые из них:
10. Переходим от таблиц к программированию Beginning R: The Statistical Programming Language by Mark Gardener (John • Wiley & Sons, 2012). R in a Nutshell, 2nd Edition by Joseph Adler (O’Reilly, 2012). • Data Mining with R: Learning with Case Studies by Luis Torgo (Chapman and • Hall, 2010). Machine Learning for Hackers by Drew Conway and John Myles White (O’Reilly, • 2012). Вперед, вгрызайтесь в R! 449

Заключение Где я? Что случилось? Вы начинали чтение этой книги, обладая весьма тривиальным набором навыков в математике и моделировании с помощью электронных таблиц. Но если вы выполняли описываемые операции вместе со мной (а не просто перелистали первые 10 глав), то смело можете считать себя знатоком моделирования с обоймой различных техник анализа данных! В этой книге освещены многие задачи: от основанных на классических методах (оптимизации, методе Монте-Карло и прогнозировании) до контролируемого ИИ (регрессия, деревья решений и наивный Байес). Работая с данными на таком уровне, вы должны чувствовать себя довольно уверенно. Я надеюсь, что глава 10 продемонстрировала вам, что теперь, когда вы поняли техники и алгоритмы науки о данных, ими очень просто пользоваться и в языках программирования, таких как R. Если же вас заинтересовала какая-то конкретная техника или задача, упомянутая в книге, — копайте глубже! Хотите больше R, больше оптимизации, больше машинного обучения? Возьмите один из ресурсов, которые я рекомендую в конце каждой главы, и читайте. Там есть чему поучиться. В этой книге я лишь слегка затронул практическую аналитику. Но подождите… Перед тем как попрощаться Пользуясь законной возможностью написать это заключение, хочу высказать некоторые мысли о значении практической науки о данных в реальном мире, потому что одних твердых знаний в математике специалисту в этой области явно недостаточно.
452 Много цифр Все, кто меня хорошо знает, в курсе, что я — не самая светлая голова. Мои математические способности довольно средние, но я видел, как парни гораздо умнее меня терпят оглушительное фиаско как профессиональные аналитики. Проблема в том, что, несмотря на свой ум, они не знают мелочей, способных стать причиной провала технических новаций в бизнес-среде. Уделив внимание подобным вещам, которые могут привести к успеху или, наоборот, к краху вашего аналитического проекта, а порой и карьеры. Подход к проблеме Мой любимый фильм всех времен — это «Тихушники» 1992 года. Главные герои — банда тестировщиков уязвимости под началом Роберта Редфорда — крадут «черный ящик», который можно вскрыть с помощью шифрования RSA. Далее следует бурное веселье. (Если вы его не смотрели, то я вам завидую, потому что у вас есть возможность посмотреть его в первый раз!) В одной из сцен Роберт Редфорд обнаруживает электронную клавиатуру на закрытой двери офиса в аналитическом центре, в который ему нужно прорваться. Связь с командой, ждущей в фургоне снаружи, он держит через наушники и микрофон. «Кому-нибудь доводилось взламывать электронную клавиатуру?» — спрашивает он. «Это нереально!» — восклицает Сидней Пуатье. Но Дэна Эйкройда, сидящего с ним в фургоне, осеняет идея. Ее незамедлительно транслируют Редфорду в микрофон. Редфорд кивает головой, говорит: «Хорошо, попробую!» и… просто выбивает дверь. Понимаете, проблема состояла вовсе не во взломе электронной клавиатуры. Она состояла в попадании в комнату. Дэн Эйкройд понимал это. Понять, какую именно проблему предстоит решить, и есть фундаментальная задача аналитики. Вы должны изучить ситуацию, процессы, данные и обстоятельства. Вы должны охарактеризовать все, что касается задачи, насколько это возможно, чтобы точно определить, каким будет идеальное решение. В науке о данных мы часто сталкиваемся с «плохо поставленными задачами»: У кого-то в бизнесе возникает проблема. • Он использует прошлый опыт и (недостаточные?) аналитические знания • для описания задачи. Со своей концепцией проблемы он идет к аналитику, выдавая ее за хорошо • поставленную задачу.
Заключение Аналитик принимает его версию и решает проблему как есть. • Такой подход может сработать. Но он не идеален, потому что задача, которую просят решить, часто не несет решения проблемы. А вот если эта задача действительно про ту проблему, то профессиональный аналитик просто не может остаться в стороне. Нельзя решать проблемы в том виде, в котором они встречаются в бизнессреде. Если вы носите гордое звание аналитика, никогда не позволяйте себе руководствоваться чужим видением. Найдите общий язык с заказчиками, над чьими проблемами вы работаете, дабы убедиться, что вы решаете нужную задачу. Изучите бизнес-процессы, сгенерированные и сохраненные данные. Поинтересуйтесь, как подобные задачи решаются сегодня и какие параметры при этом используются (или игнорируются), приводя в итоге к успеху. Решайте правильную, хотя порой и искаженную задачу. Никакая математическая модель не может крикнуть: «Эй, ты отлично сформулировал эту оптимизационную модель, но, мне кажется, тебе не стоит городить огород, а лучше вернуться на шаг назад и внести небольшие изменения в свой бизнес». Поэтому учитесь общаться! Нам нужно больше «переводчиков» Если вы прочитали эту книгу, то можно с уверенностью утверждать: вы кое-что понимаете в аналитике. Вы знакомы с доступными вам инструментами и даже создавали с их помощью прототипы. Такой опыт позволяет вам видеть аналитические возможности лучше других, потому что вы знаете, что именно возможно. Вам не нужно ждать, пока кто-то принесет вам эту возможность — вы в состоянии найти ее сами. Но без общения невозможно понять вызовы и задачи, стоящие перед другими людьми, обсудить перспективы сотрудничества и объяснить, над чем вы сейчас работаете. В современной деловой среде совершенно непозволительно хорошо разбираться в чем-то одном. Специалисты, которые занимаются наукой о данных, должны быть полиглотами, понимающими языки математики, программирования и бизнеса. Наилучший способ научиться общаться с другими людьми, как и единственный способ освоить математику — это практика. Используйте любую подвернувшуюся возможность, формальную и неформальную, чтобы поговорить об аналитике. Ищите способы обсудить аналитические концепции конкретно в вашем деловом аспекте. Настаивайте на том, чтобы менеджеры разрешали вам участвовать в планировании и развитии бизнеса. Очень часто профессиональные аналитики 453
454 Много цифр допускаются к проекту только после составления его плана, но ваши знания о техниках и доступных данных совершенно необходимы для успеха дела на этапе раннего планирования. Прилагайте усилия, чтобы в вас видели человека, с которым стоит посоветоваться, а не тупое продолжение «цифрожевательной» машины, в которую задачи забрасывают с безопасного расстояния. Чем более открыт и общителен аналитик в своей организации, тем более эффективен его труд. К аналитикам слишком долго относились как к женщинам в викторианскую эпоху — держали подальше от сложных бизнес-проблем, потому что они наверняка не смогли бы их понять. Позвольте людям почувствовать значимость ваших навыков и широту кругозора — то, что окружающие не способны к расчетам, еще не значит, что с ними нельзя обсудить слайд из презентации. Втягивайтесь, пачкайте руки — и говорите! Остерегайтесь трехголового змея: инструментов, параметров работы и математического совершенства Существует множество ошибок, способных подорвать авторитет аналитики в организации. В этом списке — политика и внутренние конфликты, неудачный опыт предыдущего проекта «предприятия по бизнес-аналитике с управлением через облако» или подразделений, не решавшихся оптимизировать или автоматизировать свои темные делишки из страха, что их моментально расформируют. Не все препятствия создаются профессиональным аналитиком, но кое-какие несомненно. Есть три основных способа испортить собственную работу: чрезмерная сложность моделирования, одержимость инструментами и фиксация на параметрах работы. Сложность Много лет назад я работал над оптимизационной моделью цепи снабжения одной компании, входящей в Fortune 500. Честно сказать, это была бестолковая модель. Понабрав бизнес-правил всех мастей от заказчика, мы смоделировали по ним полный процесс снабжения как смешанно-целочисленную программу. Мы даже спрогнозировали нормально распределенный будущий спрос, причем новаторски, за что нас и опубликовали. Но, повторяю, модель была ужасной. Обреченной с самого начала. Под словом «обреченная» я не имею в виду, что она была неверна, но лучше бы мы ее не использовали. Честно признаюсь, после ухода нескольких научных сотрудников в компании не осталось никого, кто мог бы обновлять значения кумулятивной
Заключение погрешности прогноза и стандартного отклонения. Рабочие на объекте так и не смогли «въехать», как это делается, несмотря на все наше обучение. Вот в чем разница между наукой и индустрией! В науке успех не определяется пользой. Новаторская оптимизационная модель ценна сама по себе, даже если она слишком сложна для аналитика цепи снабжения. Но на производстве аналитикам приходится работать на результат, и для модели практическая ценность играет такую же роль, что и новизна. В случае с этой злосчастной моделью мы потратили слишком много времени на сложные математические конструкции для оптимизации цепи снабжения и совершенно упустили из виду то, что модель, возможно, некому будет обновлять. Признак настоящего профессионала-аналитика, как и каждого настоящего художника — умение «вычленить» момент для внесения изменений. Помните, что в аналитике лучшее — враг хорошего. Лучшая модель — та, в которой достигнут правильный баланс между функциональностью и простотой в обращении. Если аналитическая модель не используется, она ничего не стоит. Инструменты Сегодня в мире аналитики (или, если вам больше нравится, «науки о данных», «больших данных», «бизнес-аналитике», «облачного чего-то там» и т. д.) людей все больше интересуют инструменты и архитектура. Инструменты, безусловно, важны. Они позволяют развернуть во всей красе ваши аналитические проекты и проекты по управлению данными. Но когда люди говорят о «лучшем инструменте в их работе», это часто является признаком фокусировки на инструменте, а не на работе. Компании, производящие программное обеспечение, заинтересованы в продаже вам продукта, решающего проблемы, которых у вас, возможно, и нет. А у многих есть еще и боссы, которые, начитавшись Harvard Business Review, велят нам с умным видом: «Надо сделать эту штуку с большими данными. Сходи, купи что-нибудь и запускай свой Hadoop». Все это привело к опасным тенденциям в современном бизнесе, когда менеджмент заботится только об инструментах, причем настолько рьяно, что аналитикам ничего не остается, как молча подчиняться. Производители же, в свою очередь, только и мечтают продать нам инструменты, чтобы нам было чем заняться, но я бы не стал утверждать, что в этом случае речь идет о настоящем анализе. Вот простое правило: перед размышлением об инструментах как можно более детально выбирайте аналитические возможности, за которые вы хотели бы взяться. 455
456 Много цифр Нужен ли вам Hadoop? Зависит от того, требует ли ваша задача принципа «разделяй и властвуй» для кучи несортированных данных? Нет? Тогда ответ, наверное, тоже отрицательный. Не ставьте телегу впереди лошади и не покупайте программы (это же относится к консультантам, которым для работы нужны инструменты с открытым кодом), только чтобы потом сказать: «Отлично! И что теперь делать со всем этим добром?» Параметры работы Если бы мне давали монетку каждый раз, когда кто-нибудь поднимает брови, слыша, что в MailChimp мы используем R в антиспамовых моделях, я бы уже купил фабрику Mountain Dew. Все считают этот язык неподходящим из-за настроек производительности. Если бы я занимался торговлей на бирже с огромным потоком данных, то, думаю, утверждение это было бы верно. Я бы лучше написал все в С. Но я не торгую на бирже — и этим все сказано. Что касается MailChimp, то большую часть времени мы проводим не в R. Оно уходит на перемещение данных в модели ИИ. Не на саму работу модели ИИ и уж точно не на ее обучение. Я встречал ребят, уверенных в скорости, с которой их ПО обучает модель ИИ. Может ли модель обучаться параллельно, на языке нижнего уровня, в живой среде? Они постоянно спрашивают себя, что из их набора необходимо в данный момент, вместо того чтобы перестать тратить уйму времени на полировку лишней части своего аналитического проекта. В MailChimp мы обучаем наши модели офлайн раз в квартал, тестируем их, а уже затем запускаем обратно в производство. В R на обучение модели у меня уходит несколько часов. И даже несмотря на то, что у нас, как у любой компании, объем данных измеряется в терабайтах, размер однажды созданного обучающего набора — всего 10 гигабайт, так что я могу обучать модели даже на ноутбуке. С ума сойти! При этом я не фокусируюсь на скорости обучения в R. Я сосредотачиваюсь на более важных вещах, например точности модели. Я отнюдь не утверждаю, что вы вообще не должны уделять внимание параметрам работы. Но заниматься ими надо спокойно, без фанатизма и только когда этого требует ситуация. Вы — не самая важная функция в своей организации Выше мы говорили о трех вещах, которых стоит опасаться. Добавлю также, что большинство компаний не занимается аналитическим бизнесом — вы должны
Заключение помнить об этом. Они добывают деньги другими способами, и аналитика призвана лишь обслуживать эти способы. Наверняка вы где-то слышали, что специалист по работе с данными — «самая привлекательная работа века». Это все оттого, что наука о данных служит индустрии. Главное слово здесь — «служит». Представьте себе индустрию авиаперевозок. Отраслевики десятилетиями анализируют огромный объем данных, чтобы выдавить из вас последний цент за место, на котором вы едва помещаетесь. Все это делается с помощью моделей оптимизации доходов. Это огромная победа для математики. Но знаете что? Самая важная часть авиабизнеса — это полеты. Продукция и услуги, продаваемые организацией, значат больше, чем модели, прибавляющие центы к этим долларам. Вашей целью должно быть использование данных для улучшения выделения целевых групп, прогнозирования, ценообразования, принятия решений, составления отчетов, соблюдения юридических норм и т. д. Другими словами, работайте вместе со всей своей организацией над лучшим бизнесом, а не над наукой о данных ради нее самой. Подходите ко всему творчески и будьте на связи! Но довольно мудрствований! Прорвавшись сквозь основные главы, вы приобрели хорошую основу для того, чтобы начать мечтать, прототипировать и применять решения к аналитическим задачам, предоставляемым вашим бизнесом. Поговорите с коллегами и подойдите к делу творчески. Может быть, есть аналитическое решение для области, которая держится лишь на интуиции и «ручном» управлении? Смело бросайтесь на амбразуру! И, по ходу освоения процесса применения этих и других техник в вашей повседневной жизни, будьте на связи. Я в Twitter @John4man. Находитесь и рассказывайте свою историю. Или проклинайте меня и эту книгу. Я с благодарностью приму любой отзыв. Приятной вам обработки данных! 457

Благодарности Э та книга появилась после того, как мой блог Analytics Made Skeezy стал популярным среди огромного количества народа. Так что я хочу поблагодарить всех моих читателей и тех, кто следил за моими аналитическими заметками в Twitter. Огромное спасибо Аарону Уолтеру, Крису Миллсу и Джону Дакетту за то, что убедили Wiley взяться за книгу на основе моих глупых твитов. Отдельное спасибо команде MailChimp: без их помощи и поддержки я никогда бы не решился писать такую сложную техническую книгу параллельно с работой и воспитанием троих мальчишек. А без Нила Бэйнтона и Мишель Риггин-Рэнсом я бы просто умер. Я в огромном долгу перед Роном Льюисом, Джосом Розенбаумом и Джейсоном Тревисом за их работу над обложкой и рекламным ролике о книге. Благодарю Кэрол Лонг из издательства Wiley за то, что она поверила в меня, и всю команду редакторов за их работу и опыт. Огромное спасибо Грегу Дженнингсу за создание таблиц! И, родители, спасибо, что кода-то прочли мой научно-фантастический рассказ и не сказали, что мне не стоит больше писать.

Форман Джон МНОГО ЦИФР Анализ больших данных при помощи Excel Руководитель проекта М. Шалунова Корректор Е. Чудинова Компьютерная верстка К. Свищёв Дизайн обложки Ю. Буга Подписано в печать 30.10.2015. Формат 84 × 108 1⁄16. Бумага офсетная № 1. Печать офсетная. Объем 29,0 печ. л. Тираж 1500 экз. Заказ № ООО «Альпина Паблишер» 123060, Москва, а/я 28 Тел. +7 (495) 980-53-54 www.alpina.ru e-mail: info@alpina.ru Знак информационной продукции (Федеральный закон № 436-ФЗ от 29.12.2010 г.)
ȇ șȟȈșȚȓȐȊȣȑ ȟȍȓȖȊȍȒ, ȊȍȌȤ ț Ȕȍȕȧ ȚȈȒȈȧ ȗȘȍȒȘȈșȕȈȧ ȘȈȉȖȚȈ: ȐșȒȈȚȤ Ȑ ȐȏȌȈȊȈȚȤ țȔȕȣȍ ȒȕȐȋȐ, ȖȉȡȈȚȤșȧ ș Ȑȝ ȈȊȚȖȘȈȔȐ, țȏȕȈȊȈȚȤ ȖȚ ȕȐȝ ȔȕȖȋȖ ȕȖȊȖȋȖ Ȑ ȐȕȚȍȘȍșȕȖȋȖ. ǰȏȌȈȊ ȕȍșȒȖȓȤȒȖ șȖȚȍȕ ȌȍȓȖȊȣȝ Ȑ ȘȈȏȊȐȊȈȦȡȐȝ ȒȕȐȋ, ȔȖȋț țȊȍȘȍȕȕȖ șȒȈȏȈȚȤ, ȟȚȖ ȒȕȐȋȈ Ȍȓȧ ȈȊȚȖȘȈ ȗȖȟȚȐ ȊșȍȋȌȈ – ȕȍ ȞȍȓȤ, Ȉ ȘȍȏțȓȤȚȈȚ. Ǫ ȒȈȒȖȑ-ȚȖ ȔȖȔȍȕȚ ȈȊȚȖȘ ȗȖȕȐȔȈȍȚ, ȟȚȖ ȖȉȓȈȌȈȍȚ țȕȐȒȈȓȤȕȣȔ ȖȗȣȚȖȔ, ȘȈșșȒȈȏ Ȗ ȒȖȚȖȘȖȔ ȗȖȔȖȎȍȚ ȌȘțȋȐȔ ȓȦȌȧȔ șȚȈȚȤ ȓțȟȠȍ Ȑ țȏȕȈȚȤ Ȗ ȎȐȏȕȐ ȟȚȖ-ȚȖ ȗȖȓȍȏȕȖȍ. ǿȍȘȍȏ ȕȍȒȖȚȖȘȖȍ ȊȘȍȔȧ ȥȚȖ ȗȖȕȐȔȈȕȐȍ șȚȈȕȖȊȐȚșȧ ȕȈșȚȖȓȤȒȖ ȖșȖȏȕȈȕȕȣȔ, ȟȚȖ Ȋ ȗȘȧȔȖȔ șȔȣșȓȍ șȓȖȊȈ ȌȖȊȖȌȐȚ ȈȊȚȖȘȈ ȌȖ ȘțȟȒȐ (ȐȓȐ ȌȖ ȒȓȈȊȐȈȚțȘȣ), ȏȈșȚȈȊȓȧȧ ȕȈȗȐșȈȚȤ ȒȕȐȋț. ǪȗȖȓȕȍ ȊȖȏȔȖȎȕȖ, ȟȚȖ Ǫȣ, ȟȐȚȈȦȡȐȑ ȥȚȐ șȚȘȖȒȐ șȍȑȟȈș, – ȗȖȚȍȕȞȐȈȓȤȕȣȑ ȈȊȚȖȘ ȒȕȐȋȐ, ȒȖȚȖȘȈȧ șȚȈȕȍȚ ȉȍșȚșȍȓȓȍȘȖȔ Ȑ ȌȈșȚ ȓȦȌȧȔ ȕțȎȕȣȍ ȏȕȈȕȐȧ Ȑ ȕȈȊȣȒȐ. Ǵȣ ȉțȌȍȔ ȖȟȍȕȤ ȘȈȌȣ șȚȈȚȤ ȐȏȌȈȚȍȓȍȔ ǪȈȠȍȑ ȒȕȐȋȐ! ǵȈȠȈ ȒȘȍȈȚȐȊȕȈȧ ȒȖȔȈȕȌȈ ȗȘȐȓȖȎȐȚ Ȋșȍ țșȐȓȐȧ, ȟȚȖȉȣ ǪȈȠȈ ȒȕȐȋȈ ȗȖȓțȟȐȓȈșȤ ȒȘȈșȐȊȖȑ Ȑ ȒȈȟȍșȚȊȍȕȕȖȑ, ȟȚȖȉȣ ȖȕȈ ȉȣȓȈ ȏȈȔȍȚȕȈ Ȋ ȔȈȋȈȏȐȕȈȝ, ȟȚȖȉȣ ȍȍ ȈȒȚȐȊȕȖ ȖȉșțȎȌȈȓȐ. ǷȘȐșȣȓȈȑȚȍ ȕȈȔ ǪȈȠȐ ȘțȒȖȗȐșȐ, ǪȈȔ ȗȖȕȘȈȊȐȚșȧ ȘȈȉȖȚȈȚȤ ș ȕȈȔȐ! ǹ țȊȈȎȍȕȐȍȔ, ǹȍȘȋȍȑ ǺțȘȒȖ, ȒȈȕȌȐȌȈȚ ȥȒȖȕȖȔȐȟȍșȒȐȝ ȕȈțȒ, ȋȓȈȊȕȣȑ ȘȍȌȈȒȚȖȘ ȐȏȌȈȚȍȓȤșȚȊȈ «ǨȓȤȗȐȕȈ ǷȈȉȓȐȠȍȘ» Заходите сюда alpina.ru/a

К концу книги вы не только будете иметь представление о нижеперечисленных техниках, но и приобретете опыт их применения: • оптимизация с использованием линейного и интегрального программирования; • работа с временными рядами данных, определение трендов и изменений сезонного характера, а также прогнозирование методом экспоненциального сглаживания; • моделирование методом Монте-Карло в оптимизации и прогнозировании сценариев для количественного выражения и адресации рисков; • искусственный интеллект с использованием общей линейной модели, функции логистических звеньев, ансамблевых методов и наивного байесовского классификатора; • измерение расстояния между клиентами с помощью близости косинусов угла, создание К-ближайших граф, расчет модулярности и кластеризация клиентов; • определение выбросов в одном измерении по методу Тьюки или в нескольких измерениях с помощью локальных факторов выброса; • применение пакетов R для использования результатов работы других программистов при выполнении этих задач.