Как Dropbox использует машинное обучение для прогнозирования следующего файла, который вам нужен?

машинное обучение искусственный интеллект
Как Dropbox использует машинное обучение для прогнозирования следующего файла, который вам нужен?

As we laid out in our blog post introducing DBXi, Dropbox is building features to help users stay focused on what matters. Searching through your content can be tedious, so we built content suggestions to make it easier to find the files you need, when you need them.

Мы создали эту функцию, используя современные методы машинного обучения (ML), но процесс ее создания начался с простого вопроса: как люди находят свои файлы? Какие модели поведения наиболее распространены? Мы выдвинули гипотезу о следующих двух категориях. будут наиболее распространены:

  • Recent files: файлы, которые вам нужны, часто являются теми, которые вы использовали в последнее время. Они, конечно, меняются со временем, но часто недавнее прошлое является хорошим индикатором ближайшего будущего. Сюда также могут входить файлы, которые недавно Мероприятияby others,не только вами. Например, коллега только что написал первый черновик отчета и поделился им с вами, чтобы вы могли его отредактировать. Даже если вы еще не открыли его, тот факт, что он был недавно предоставлен ты сильный подсказка, что вы, возможно, захотите отредактировать его сейчас.
  • Frequent files: Другая категория ваших файлов — это те, к которым вы возвращаетесь снова и снова. Это может быть ваш личный список дел, заметки о еженедельных собраниях или каталог команды. Здесь есть некоторое совпадение с предыдущей категорией — если вы усердно работаете над отчетом, который нужно сдать на следующей неделе, вы, вероятно, будете открывать отчет довольно частоandон также будет одним из самых последних файлов, к которым вы обращались.

Heuristics

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

  • Recency: мы можем представить вам ваши файлы в обратном хронологическом порядке, т. е. сначала самые последние. Сегодня мы уже показываем это пользователям на dropbox.com, и это хорошая основа для улучшения.
  • Frequency: Your most frequently used files over the last week are likely to be different from the ones over the last year. For simplicity, we started with a middle-ground between these options, e.g., one month. We count the number of accesses of each of your files in the last month and display the files with the highest counts.
  • Frecency: The combination of the two options above is a heuristic called frecency, Он ищет ваши файлы, которые недавно были активны и/или к которым часто обращались, ранжируя файлы, соответствующие обоим критериям, выше. Мы уменьшаем вес, присвоенный каждому доступу, в зависимости от того, как давно это было. Например, доступ к файлу пять раз за последнюю неделю повышает вероятность того, что вы скоро снова воспользуетесь им, по сравнению с в файл, который вы доступ десять раз пару месяцев назад.

Deploying and improving heuristics

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

Logging was critical for this initial version. Once we have a feature launched to some users (we often run initial experiments to a small % of users with our feature gating system Stormcrow), we can start seeing how often they find these suggestions helpful, and use that to help us determine what to do next. We can also compare different variants (e.g., the different heuristics) to see how they perform relative to each other.

В нашем случае мы обнаружили ряд проблем с эвристикой, когда впервые протестировали ее на пользователях.Например, иногда у пользователя может быть только один файл, над которым он недавно работал, и больше ничего в течение длительного периода до этого. Однако, поскольку мы всегда показывали первые три предложения, пользователи не понимали, почему последний файл отображается вместе с другими совершенно не связанными с ними файлами.Мы решили эту проблему,thresholding the heuristics: only showing files if their score was higher than a threshold value.

We can pick a threshold value by looking at a logged dataset of the suggestions shown, the score for each suggestion, and the ones users clicked on. By setting different threshold values offline, we can make a tradeoff between precision (what fraction of shown results were clicked) and recall(какая часть кликов была показана). В нашем случае мы были заинтересованы в повышении точности, чтобы избежать ложных срабатываний, и поэтому выбрали довольно высокий порог. файлы с эвристическими оценками ниже этого значения не будут предлагаться.

Еще одна проблема, которую мы обнаружили, заключалась в том, что в предложения иногда включались файлы, к которым обращались программы, установленные на компьютере пользователя (такие как антивирусные сканеры или временные файлы), но не через непосредственные действия пользователя.Мы создали фильтр для исключения такие файлы в наших предложениях. Мы также обнаружили другие классы поведения пользователей, которые мы не включили в наш первоначальный набор эвристик. В частности, доступ к некоторым файлам осуществлялся периодически, что не было зафиксировано нашей эвристикой. Это могли быть документы, такие как ежеквартальные отчеты или документы ежемесячных совещаний.

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

Machine learning model v1

One way to design an ML system is to work backwards from how we want the system to operate at prediction time. In this case, we wanted a fairly standard prediction pipeline:

ML prediction pipeline for the content suggestions system

The steps are as follows:

  1. Get candidate files: для каждого пользователя нам нужен набор файлов-кандидатов для ранжирования. Поскольку у пользователей Dropbox потенциально могут быть тысячи или даже миллионы файлов, ранжировать их все было бы очень дорого и не очень полезно. поскольку ко многим файлам редко обращаются, вместо этого мы можем ограничиться самыми последними файлами, с которыми взаимодействовал пользователь, без существенной потери точности.
  2. Fetch signals: для каждого файла-кандидата нам нужно получить необработанные сигналы, которые нас интересуют, связанные с этим файлом, включая его историю (открытие, редактирование, совместное использование и т. д.), какие пользователи работали с файлом и другие свойства. файла, например его тип и размер. Мы также включаем сигналы о текущем пользователе и «контексте» (например, текущее время и тип устройства, на котором работает пользователь), чтобы результаты стали более персонализированными без необходимости обучения отдельных моделей. для каждого пользователя. Модель обучается на активности огромного количества пользователей, что защищает ее от смещения в сторону представления действий (или раскрытия поведения) любого данного пользователя. Для первой версии мы использовали только сигналы, основанные на активности (например, история доступа), а не основанные на содержании (например, ключевые слова в документах). Преимущество этого заключается в том, что мы можем обрабатывать все файлы одинаково, вместо того, чтобы вычислять различные виды сигналов в зависимости от типа файла. В будущем мы можем добавить сигналы на основе контента, если это необходимо.
  3. Encode feature vectors: Since most ML algorithms can only operate on extremely simple forms of inputs, such as a vector of floating-point numbers, we encode the raw signals into what is called a feature vector. There are standard ways of doing this for different kinds of input, which we adapted as necessary.
  4. Score: мы, наконец, готовы выполнить фактическое ранжирование. Мы передаем вектор признаков для каждого файла алгоритму ранжирования, получаем оценку для каждого файла и сортируем по этой оценке. демонстрируется пользователю.

Of course, this all has to happen very quickly for each user and their files, since the user is waiting for the page to load. We spent a fair amount of time optimizing different parts of the pipeline. Luckily, we could take advantage of the fact that these steps can be done independently for each candidate file, thus allowing us to parallelize the entire process. In addition, we already had a fast database for getting a list of recent files and their signals (steps 1 and 2). This turned out to be enough to meet our latency budget, without having to significantly optimize steps 3 and 4.

Training the model

Теперь, когда мы знаем, как система будет работать в производственной среде, нам нужно выяснить, как обучать модель.Первоначально мы сформулировали проблему как двоичную классификацию: мы хотим определить, будет ли данный файл открыт сейчас («положительно») или не («отрицательное»). Мы можем использовать прогнозируемую вероятность этого события в качестве оценки для ранжирования результатов.Для конвейера обучения общее руководство состоит в том, чтобы попытаться максимально приблизить сценарий обучения к сценарию прогнозирования.Таким образом, мы остановились на следующем шаги, точно соответствующие нашему конвейеру прогнозирования.

  1. Get candidate files: As the input to the entire system, getting this step right is crucial to the final accuracy, and despite its apparent simplicity, it was one of the most challenging, for a number of reasons.
    • Where to get positive examples: Our logging gives us a list of historic file opens. However, whichдолжны ли мы считаться положительными примерами? Данные эвристической версии этой функции, или общие открытые данные файла Dropbox? Первые являются гораздо более «подходящими» кандидатами, потому что мы знаем, что пользователь открыл эти файлы именно в том контексте, в котором мы будем развертывать эту модель; однако модели, обученные только на данных из одного Контекст может страдать от туннельного зрения при использовании в более широком контексте. С другой стороны, более общая история файла более репрезентативна для всех видов поведения пользователя, но может включать больше шума. Сначала мы использовали первый метод. так как журналы было намного проще обрабатывать, но мы переключились на сочетание обоих (с большим акцентом на последнем), как только у нас был наш обучающий конвейер, потому что результаты были намного лучше.
    • Where to get negative examples: Теоретически каждый файл в Dropbox пользователя, который былnotОткрытие является отрицательным! Однако, помня о нашем руководстве («Сценарий тренировки должен быть как можно ближе к сценарию прогнозирования возможно»), мы используем список последних файлов,at the time of the positive file open, как набор возможных отрицательных значений, потому что это больше всего напоминает то, что произойдет во время предсказания. чтобы быть намного больше, чем набор положительных результатов — с чем системы машинного обучения часто не справляются, — мы подбираем отрицательные значения лишь на небольшой коэффициент, больший, чем положительные.
  2. Fetch signals: This is just like in the prediction scenario, except it requires access to historic data, because we need the signals as they would have appeared at the time of each training example. To facilitate this, we have a Spark clusterкоторые могут работать с историческими данными. Например, одним из наших сигналов является «ранг недавности», который представляет собой ранг файла в списке недавно открытых файлов, отсортированных по времени последнего доступа. Для исторических данных это означает реконструкцию как этот список выглядел бы в данный момент времени, чтобы мы могли вычислить правильный ранг.
  3. Encode features: Again, we keep this exactly as in production. In our iterative training process, we started with very simple encodings of the data, and made them more sophisticated over time as needed.
  4. Train: The major decision here was what ML algorithm to use. We started with an extremely simple choice: a linear Support Vector Machine (SVM). These have the advantage of being extremely fast to train, easy to understand, and come with many mature and optimized implementations.

The output of this process is a trained model, which is just a vector containing weight coefficients for each feature dimension (i.e., floats). Over the course of this project, we experimented with many different models: trained on different input data, with different sets of signals, encoded in various ways, and with different classifier training parameters.

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

Metrics and iteration

После того, как у нас был работающий конвейер обучения и прогнозирования, нам нужно было выяснить, как предоставить пользователям наилучшую возможную систему. Однако что на самом деле означает «лучшая»? В Dropbox наши усилия по машинному обучению ориентированы на продукт: в первую очередь мы хотим улучшить опыт продукта для наших пользователей, и любое машинное обучение, которое мы создаем, служит этому.Поэтому, когда мы говорим об улучшении системы, в конечном итоге мы хотим иметь возможность измерить выгоду для наших пользователей.

We start by defining the product metrics. In the case of content suggestions, the primary goal was engagement. We use several metrics to track this, so we decided to start simple: if our suggestions are helpful, we would expect users to click on them more. This is straightforward to measure, by counting the number of times people clicked on a suggestion divided by the number of times a user was shown suggestions. (This is also called the Click-Through Rate, or CTR.) To achieve statistical significance, we would show subsets of users the suggestions from different models over the course of a week or two and then compare the CTRs for the different variants. In theory, we could launch models every few weeks and slowly improve engagement over time.

In practice, we ran into a few major issues (and some minor ones). First was how to attribute increases (or drops) in the CTR due to changes in the product design vs. changes in the ML model. A large body of research and industry case-studies have shown that even seemingly small changes in the user experience (UX) can cause big changes in user behavior (hence the prevalence of A/B testing). So, while one team of engineers was focusing on improving the ML model, another team of engineers, designers, and product managers was focusing on improving the design of the feature. Some high-level examples of this design iteration are shown below:

Учитывая, что мы можем изменить как модель UX, так и модель машинного обучения для новой версии, как мы узнаем, какое изменение повлияло на CTR (и насколько)?На самом деле решить проблему было еще сложнее, чем мы думали изначально. на, мы обнаружили что в довольно большом количестве случаев мы предлагали пользователю нужные файлы, но они не нажимали на них из раздела предложений, вместо этого они переходили к файлу каким-то другим способом и открывали его оттуда. много возможных причины этого — большее знакомство с существующими способами доступа к файлам, отсутствие важной контекстуальной информации (такой как имена родительских папок, которые мы добавили как часть нашей итерации дизайна) и т. д. — конечным результатом было то, что мы не могли полагаться на в Цифры CTR как наша единственная мера точности модели.Нам нужно было найти прокси-метрику, которая более точно отражала бы точность нашей модели и была бы как можно более независимой от UX.

Была еще одна веская причина для перехода на прокси-метрику: скорость итерации. Пару недель на проведение A/B-тестирования звучит не очень долго, но это как раз то время, которое необходимо для полноценного выполнения каждого эксперимента. чтобы проанализировать результаты, приходите со списком предлагаемых улучшений, внедрить их и, наконец, обучить новую модель. Все это означало, что выпуск новой версии мог занять более месяца. Чтобы добиться серьезного прогресса, нам нужно было бы резко сократить это время. , в идеале что-то, что мы могли бы измерить «офлайн» — без предоставления пользователям.

Hit ratios

Наш тренировочный процесс позволил нам измерить различные величины на предоставленных наборах тренировочных данных, таких как точность и полнота (как описано ранее) или точность классификатора, но мы не обнаружили сильной корреляции между этими метриками и CTR, когда мы фактически запустили модель для пользователей. Вместо этого мы придумали метрику «коэффициент совпадений», которая удовлетворяла всем нашим критериям. Для каждого данного предложения мы проверяли, обращался ли пользователь к этому файлу в последующий час, независимо от того, как они пришли к файл. Если это так, мы засчитывали это как «попадание». Затем мы могли рассчитать как «коэффициент совпадений» для каждого предложения (процент совпадений) и коэффициент совпадения для сеанса (процент сеансов, в которых хотя бы одно предложение было хитом). Мы могли бы измерить это как онлайн и офлайн (просматривая исторические журналы поведения пользователей).

This metric proved invaluable not just for iterating on the ML faster, but also for diagnosing UX issues. For example, when we first moved from displaying content suggestions as a list of files to a set of thumbnails, we expected CTR to increase. Not only were we showing the files in less vertical space, we were also showing thumbnails to make it easier for users to identify the files. However, CTR actually dropped. We tried a few different design iterations and used our hit ratio metric to verify that the quality of the suggestions was not to blame. We discovered a number of issues that we rectified, such as the missing folder names mentioned earlier.

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

With extensive internal testing, we uncovered a number of other issues, including many that affected the very beginning of the pipeline: what data we used. Here are a few interesting examples:

  • Short clicks: мы обнаружили, что наши обучающие данные включали случаи, когда пользователи открывали файл в папке, а затем прокручивали другие файлы в этой папке с помощью клавиш со стрелками влево и вправо. считаются положительными обучающими образцами, хотя такое поведение неприменимо на домашней странице, где мы показываем только несколько изображений за раз. Поэтому мы разработали простой метод маркировки этих «коротких кликов» и отфильтровали их из наш данные тренировки.
  • Very recent file activity: A commonly used Dropbox feature is automatically saving screenshots to Dropbox, Пользователи, переходящие на главную страницу, ожидают увидеть эти правильные далеко, но наш функциональный конвейер не был достаточно отзывчивым, чтобы уловить их.Настроив задержку различных компонентов, мы также смогли включить их в результаты.
  • Newly created folders: In a similar vein, users expect to see newly created folders show up on the home page, since these are often created specifically to move files into. In this case, we had to temporarily use a heuristic to detect such folders and merge them into the suggestions, since the kind of signals we have for folders is much more limited (and different from files).

Machine learning model v2

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

Another big area of ML investment at Dropbox proved to be quite important for improving the content suggestions: learning embeddingsдля распространенных типов сущностей. Встраивания — это способ представления дискретных наборов объектов — скажем, каждого пользователя или файла Dropbox — в виде компактного вектора чисел с плавающей запятой, которые можно рассматривать как векторы в многомерном пространстве, где обычно используются меры расстояния, такие какcosine or Euclidean distanceфиксировать семантическое сходство объектов. Например, мы ожидаем, что встраивания для пользователей с похожим поведением или файлы с похожей активностью шаблоны, чтобы быть «близкими» в пространстве встраивания. Эти вложения можно узнать из различных сигналов, которые мы имеем в Dropbox, а затем применить в качестве входных данных для любой системы машинного обучения. Для предложений контента эти вложения обеспечивают заметное повышение точности.

Finally, we upgraded our classifier to a neural network. Our network is currently not very deep, but just by being able to operate non-linearly on combinations of input features, it has a huge advantage over linear classifiers. For example, if some users tend to open PDF files on their phones in the morning, and PowerPoint files on desktop in the afternoon, that would be quite hard to capture with a linear model (without extensive feature combinations or augmentations), but can be easily picked up by neural nets.

We also changed how we framed our training problem slightly. Instead of binary classification, we switched to a Learning-To-Rank (LTR) formulation. This class of methods is better suited to our problem scenario. Rather than optimizing for whether a file will be clicked or not, completely independent of other predictions, LTR optimizes for ranking clicked files higher than not-clicked files. This has the effect of redistributing output scores in a way that improves the final results.

With all of these improvements, we were able to significantly boost our hit ratio and improve overall CTR. We have also laid the groundwork for additional improvements in the future.

Acknowledgements

Этот проект был результатом тесного сотрудничества между командами по продукту, инфраструктуре и машинному обучению. Хотя здесь слишком много людей, чтобы перечислять их по отдельности, мы хотели бы выразить особую признательность Яну Бейкеру за создание крупных деталей. системы (а также за улучшение практически всех остальных компонентов в процессе разработки), а также Эрмо Вэю за то, что он возглавил большую часть работы по итерации машинного обучения.

Все наши команды в настоящее время набирают сотрудников, поэтому, если подобные проблемы кажутся вам интересными, мы будем рады, если выjoin us!