Какие хорошие подходы к прогнозированию времени завершения длительного процесса?

tl; dr: Я хочу предсказать завершение копирования файла. Каковы хорошие методы, учитывая время начала и текущий прогресс?

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

Текущий подход:

В настоящий момент я использую довольно наивную формулу, которую я придумал сам: (ETC означает приблизительное время завершения)

ETC = currTime + elapsedTime * (totalSize - sizeDone) / sizeDone

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

  • PRO: ETC будет постепенно меняться и становится все более и более точным, когда процесс близится к завершению.
  • CON: Он не очень хорошо реагирует на неожиданные события, такие как скопированная копия файла или быстрое ускорение.

Другая идея:

Следующей идеей, которую я имел, было сохранение записи о прогрессе за последние n секунд (или минут, учитывая, что эти архивы должны занимать часы), и просто выполните что-то вроде:

ETC = currTime + currAvg * (totalSize - sizeDone)

Это нечто противоположное первому методу:

  • PRO: Если скорость быстро изменится, ETC будет быстро обновляться, чтобы отразить текущее состояние дел.
  • CON: ETC может сильно перескакивать, если скорость несовместима.

Наконец

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

С учетом сказанного, другим вариантом, о котором я мог думать, было бы рассчитать среднее значение обоих из вышеперечисленного, возможно, с каким-то взвешиванием:

  • Вес более первого метода больше, если копия имеет довольно стабильную среднюю среднюю скорость, даже если она локально перескакивает локально.
  • Увеличьте второй способ, если скорость копирования непредсказуема и, вероятно, будет делать такие вещи, как ускорение/замедление в течение длительного времени или вообще прекращение в течение длительного времени.

Я действительно прошу:

  • Любые альтернативные подходы к двум, которые я дал.
  • Если и как вы могли бы объединить несколько разных методов, чтобы получить окончательное предсказание.

Ответы

Ответ 1

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

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

Я бы рискнул предположить, что линейная комбинация вашей текущей модели и "средняя за последние n секунд" будет очень хорошо справляться с этой проблемой, Оптимальные веса для линейной комбинации могут быть установлены с помощью линейной регрессии (однострочный в R).

Отличным ресурсом для изучения методов статистического обучения является Элементы Статистическое обучение Хасти, Тиббирани и Фридмана. Я не могу рекомендовать эту книгу достаточно высоко.

Наконец, ваша вторая идея (в среднем за последние n секунд) пытается измерить мгновенную скорость. Более надежной техникой для этого может быть использование фильтра Kalman, целью которого является именно это:

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

Основное преимущество использования фильтра Калмана, а не фиксированного n-второго скользящего окна заключается в том, что он адаптивный: он автоматически будет использовать более длинное окно усреднения, когда измерения скачкообразно скапливаются, чем когда они стабильны.

Ответ 2

Imho, плохие реализации ETC дико злоупотребляют, что позволяет хорошо посмеяться. Иногда бывает лучше отображать факты вместо оценок, например:

  • Скопировано 5 из 10 файлов.
  • 10 из 200 МБ были скопированы

Или отобразить факты и оценку, а также дать понять, что это всего лишь оценка. Но я бы не показал только оценку.

Каждый пользователь знает, что ETCs часто совершенно бессмысленны, и тогда трудно отличить значимые ETC и бессмысленные ETC, особенно для неопытных пользователей.

Ответ 3

Я применил два разных решения для решения этой проблемы:

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

  • Вместо того, чтобы показывать один ETC, покажите диапазон времени. Идея состоит в том, чтобы вычислить ETC с последних "n" секунд или минут (например, ваша вторая идея). Я отслеживаю лучшие и наихудшие средние значения и вычисляю ряд возможных ETC. Это довольно запутанно показывать в графическом интерфейсе, но нормально показывать в приложении командной строки.

Ответ 4

Здесь есть две вещи:

  • точная оценка
  • как представить его пользователю

1. По оценке

Помимо подхода к статистике один простой способ иметь хорошую оценку текущей скорости при стирании некоторого шума или пиков - это взвешенный подход.

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

Пример: предположим, что у вас есть 10 предыдущих окон (самый последний x0, самый последний x9), тогда вы можете вычислить скорость:

Speed = (10 * x0 + 9 * x1 + 8 * x2 + ... + x9) / (10 * window-time) / 55

Когда у вас есть хорошая оценка вероятной скорости, вы близки к хорошему расчетному времени.

2. При представлении

Главное помнить здесь, что вы хотите приятный пользовательский опыт, а не научный фронт.

Исследования показали, что пользователи очень плохо реагировали на замедление и очень позитивно для ускорения. Поэтому хороший индикатор прогресса/расчетное время должен быть консервативным в представленных оценках (время резервирования для потенциального замедления) вначале.

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

real-completion = 0.4
presented-completion = real-completion * factor(real-completion)

Где factor таково, что factor([0..1]) = [0..1], factor(x) <= x и factor(1) = 1. Например, кубическая функция дает хорошее ускорение к времени завершения. Другие функции могут использовать экспоненциальную форму 1 - e^x и т.д.