Какие хорошие подходы к прогнозированию времени завершения длительного процесса?
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
и т.д.