Мои данные лгали ещё до того, как я написал хоть строчку логики
Долгое время я верил, что мои проблемы живут в коде. Когда результаты выходили неверными, я отправлялся на охоту по своей логике, своим моделям, тем хитроумным фрагментам, которыми гордился. Настоящий же виновник почти всегда сидел на один слой ниже всего этого — тихий и неисследованный: сами данные. Они выглядели чистыми. Они таковыми не были. И всё, что я строил поверх них, добросовестно наследовало эту ложь.
Это самый скучный вид сбоя из всех существующих, и именно поэтому он так опасен. Никто не хочет тратить время на аудит строк с числами. Поэтому никто этого не делает, а гниль так и сидит на самом дне, удерживая на себе всё остальное.
Миф о чистых данных
Сырые рыночные данные выглядят успокаивающе опрятно. Аккуратные строки, упорядоченные временные метки, разумно выглядящие числа, марширующие в последовательности. Эта опрятность — костюм. Реальные данные, собранные из реальных систем, которые время от времени ломаются, изобилуют мелкими повреждениями, не объявляющими о себе: пропуски, где моменты попросту отсутствуют, дублирующиеся записи, временные метки, которые дрейфуют или сбиваются с выравнивания, значения, которые застывают и повторяются во время сбоя, изредка невозможные числа, целые отрезки, едва заметно сдвинутые со своего места.
Ничто из этого не приходит с предупреждающей этикеткой. Это выглядит ровно так же, как хорошие данные, потому что сидит в тех же аккуратных строках. Формат честен, даже когда содержимое — нет, а формат — это всё, что вы видите с первого взгляда.
Мусор на входе, уверенный мусор на выходе
Что нужно усвоить — это то, что система не знает, что данные неверны. Она не может этого знать. Она берёт всё, что вы ей вручаете, и обрабатывает повреждение ровно с тем же усердием, с каким она применяет к истине, а затем выдаёт чистый, уверенный, профессионально выглядящий результат, построенный поверх гнили.
Вот в этом и заключается вся ловушка, целиком. Вывод выглядит нормально. Повреждение не распространяется в виде очевидных, вопящих ошибок, которые указывают вам на проблему. Оно распространяется в виде правдоподобных неверных ответов — результатов, которые полностью убедительны, которые проходят вашу интуитивную проверку, поверх которых вы с радостью строите следующую вещь. К тому времени, когда ошибочность всплывёт на поверхность — если она вообще когда-нибудь всплывёт, — она уже погребена под слоями работы, каждый из которых исходил из допущения, что пол под ним прочен.
Ошибки, прячущиеся внутри правдоподобия
Я медленно научился тому, что опасные ошибки в данных — не очевидные. Цена в ноль, целый отсутствующий день, значение, явно лишённое смысла, — такие вы ловите, потому что они абсурдны на первый взгляд. Они срабатывают на первой же проверке здравого смысла.
Ошибки, которые действительно причиняют вам боль, — это правдоподобные. Значение, которое неверно, но всё ещё вполне укладывается в правдоподобный диапазон. Временная метка, сбитая на одну-единственную единицу. Пропуск, который что-то выше по потоку молча заполнило догадкой. Они проплывают прямо сквозь все имеющиеся у вас проверки здравого смысла, потому что выглядят в точности как законные данные — их невозможно отличить от истины, не отправившись специально сверять их с чем-то ещё. Самое дорогое повреждение — то, что достаточно вежливо, чтобы выглядеть правильным.
Я отлаживал не тот этаж здания
Постыдно долго моим инстинктом, когда что-то выходило странным, было отправиться искать баг в своей логике — в интересной, изощрённой части системы, в той части, о которой мне казалось стоящим размышлять. Бага почти никогда там не было. Он был внизу, в данных, в каком-нибудь допущении о входных данных, проверить которое я попросту никогда не удосуживался.
Я, по сути, обыскивал верхние этажи здания в поисках источника трещины, которая бежала сквозь фундамент. Я снова и снова осматривал элегантный код, не находил в нём ничего неправильного и всё больше и больше недоумевал — потому что с ним и не было ничего неправильного. Он корректно перерабатывал плохие входные данные в плохие выходные, ровно так, как был спроектирован. Логика была невинна. Виновата была земля, на которой она стояла.
Качество данных — не задача, которую заканчивают
Одним из самых отрезвляющих осознаний было то, что данные не чистят один раз и затем идут дальше. Это фантазия. Новые данные продолжают прибывать, и прибывают они с новыми повреждениями. Источник тихо меняет свой формат. У поставщика выше по потоку случается сбой, и затем он задним числом заполняет пропуск чем-то сомнительным. Что-то, что было надёжным месяцами, ломается невиданным прежде образом в обычный вторник.
Качество данных, как я пришёл к пониманию, — не разовая уборка, которую вычёркиваешь из списка. Это непрерывная дисциплина — постоянная поза подозрительности по отношению к каждому входу, поддерживаемая вечно, потому что момент, когда ты перестаёшь следить, — это ровно тот момент, когда новое и изобретательное повреждение беспрепятственно входит в дверь.
Проверяйте безжалостно, не доверяйте ничему
Практическое решение состояло в том, чтобы относиться к каждому входу как к виновному, пока не доказана его чистота. Проверяйте на пропуски. Проверяйте на дубликаты. Проверяйте на невозможные значения, на временные метки, которые не движутся равномерно вперёд, на подозрительные отрезки, где число перестаёт меняться так, как реальные данные никогда бы не повели себя. И, что критически важно, встраивайте эти проверки прямо в конвейер, чтобы повреждение ловилось громко у парадной двери, в тот же миг, когда оно прибывает, а не обнаруживалось месяцами позже как необъяснимая странность в результате, который вы уже не можете отследить.
Это нудная, оборонительная, глубоко неэффектная работа. Это также работа, которая решает, построено ли всё, что ниже по потоку, на камне или на песке. Громкий сбой у двери — подарок. Тихий, который вы наследуете и строите поверх него, — медленная катастрофа.
Более глубокий урок: фундамент задаёт потолок
Принцип, лежащий в основе всего этого, прост и беспощаден. Никакая блистательность в модели сверху не способна компенсировать гниль в данных снизу. Качество всего, что вы строите, ограничено, абсолютно, качеством того, чем вы это кормите. Вы не можете рассуждениями выбраться из плохих входных данных; вы можете лишь произвести более уверенную, более изощрённую ошибочность поверх них.
Так что тупой, неблагодарный труд по обеспечению чистых входных данных — не нечто, стоящее ниже настоящей работы, как я привык к нему относиться. Он и есть фундамент настоящей работы, и вся конструкция над ним всегда лишь настолько честна, насколько честно это основание. Раньше я хотел проскочить мимо него, чтобы добраться до интересных частей. Теперь я понимаю, что интересные части ничего не стоят, если скучная часть под ними лжёт.
— Никаких сигналов, никакой доходности, не является инвестиционным советом.