Альтернатива для r Модель пространственного сглаживания состояния пространства в python/scikit/numpy

В R есть одна хорошая модель прогнозирования, например:

ets(y, model="ZZZ", damped=NULL, alpha=NULL, beta=NULL, gamma=NULL, 

phi=NULL, additive.only=FALSE, lambda=NULL, 

lower=c(rep(0.0001,3), 0.8), upper=c(rep(0.9999,3),0.98), 

opt.crit=c("lik","amse","mse","sigma","mae"), nmse=3, 

bounds=c("both","usual","admissible"), ic=c("aicc","aic","bic"),

restrict=TRUE, allow.multiplicative.trend=FALSE, use.initial.values=FALSE, ...)

В этом методе, если мы назначаем какую-либо переменную, он автоматически получает тип сезона, тренд и тип ошибки, например model="ZZZ"/"AMA"/"MMZ", и некоторые из коэффициентов автоматически настраиваются для получения точных результатов.

  • В python мы имеем что-то похожее на ets в любом pandas/NumPy/SciPy/scikit?

    По моим исследованиям:
    Ewma в pandas аналогичен, но нам нужно жестко скопировать все параметры в фиксированные.
    В Holtwinter нам нужно написать подробные методы для всех типов трендов и сезонов.

  • Итак, вместо этого у нас есть любые готовые функции, которые берут dataframes как входные данные и обеспечивает прогнозные значения, без письменного разрешения любые внутренние функции для параметров сами?

  • Любые тонкие настроенные модели регрессии scikit/statsmodels?

Ответ 1

После поиска немного, я не нашел ничего, что кажется действительно перспективным как альтернатива ets для python. Есть несколько попыток: StatsModels и pycast Методы прогнозирования, которые вы можете проверить, соответствуют ли они вашим потребностям.

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

Чтобы сделать это позже:

  • Вам нужно создать R script (например, my_forecast.R), который будет рассчитать (используя ets) и распечатать прогнозы в файле или на stdout (с помощью команды cat()), чтобы использовать их после script работает.
  • Вы можете запустить R script из python script следующим образом:

    import subprocess
    
    # You need to define the command that will run the Rscript from the subprocess
    command = 'Rscript'
    path2script = 'path/to/my_forecast.R'
    cmd = [command, path2script]
    
    # Option 1: If your script prints to a file
    subprocess.run(cmd)
    f = open('path/to/created/file', 'r')
    (...Do stuff from here...)
    
    # Option 2: If your script prints to stdout
    forecasts = subprocess.check_output(cmd, universal_newlines=True)
    (...Do stuff from here...)
    

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

    args = [arg0, arg1, ...]
    
    cmd = [command, path2script] + args 
    Then pass cmd to the subprocess
    

EDIT:

Я нашел примерную серию статей о прогнозировании Холт-Зитер: part1, part2 и part3. Помимо легкого для понимания анализа в этих статьях, Григорий Трубецкой (автор) предоставил код, который он разработал:

Начальная тенденция:

def initial_trend(series, slen):
    sum = 0.0
    for i in range(slen):
        sum += float(series[i+slen] - series[i]) / slen
    return sum / slen

# >>> initial_trend(series, 12)
# -0.7847222222222222

Исходные сезонные компоненты:

def initial_seasonal_components(series, slen):
    seasonals = {}
    season_averages = []
    n_seasons = int(len(series)/slen)
    # compute season averages
    for j in range(n_seasons):
        season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
    # compute initial values
    for i in range(slen):
        sum_of_vals_over_avg = 0.0
        for j in range(n_seasons):
            sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
        seasonals[i] = sum_of_vals_over_avg/n_seasons
    return seasonals

# >>> initial_seasonal_components(series, 12)
# {0: -7.4305555555555545, 1: -15.097222222222221, 2: -7.263888888888888,
#  3: -5.097222222222222,  4: 3.402777777777778,   5: 8.069444444444445,  
#  6: 16.569444444444446,  7: 9.736111111111112,   8: -0.7638888888888887,
#  9: 1.902777777777778,  10: -3.263888888888889, 11: -0.7638888888888887}

Наконец, алгоритм:

def triple_exponential_smoothing(series, slen, alpha, beta, gamma, n_preds):
    result = []
    seasonals = initial_seasonal_components(series, slen)
    for i in range(len(series)+n_preds):
        if i == 0: # initial values
            smooth = series[0]
            trend = initial_trend(series, slen)
            result.append(series[0])
            continue
        if i >= len(series): # we are forecasting
            m = i - len(series) + 1
            result.append((smooth + m*trend) + seasonals[i%slen])
        else:
            val = series[i]
            last_smooth, smooth = smooth, alpha*(val-seasonals[i%slen]) + (1-alpha)*(smooth+trend)
            trend = beta * (smooth-last_smooth) + (1-beta)*trend
            seasonals[i%slen] = gamma*(val-smooth) + (1-gamma)*seasonals[i%slen]
            result.append(smooth+trend+seasonals[i%slen])
    return result

# # forecast 24 points (i.e. two seasons)
# >>> triple_exponential_smoothing(series, 12, 0.716, 0.029, 0.993, 24)
# [30, 20.34449316666667, 28.410051892109554, 30.438122252647577, 39.466817731253066, ...

Вы можете поместить их в файл, например: holtwinters.py внутри папки со следующей структурой:

forecast_folder
|
└── __init__.py
|
└── holtwinters.py

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