R tbats Модель Сезонный Флаг клиента Нет результатов - PullRequest
0 голосов
/ 23 октября 2018

Я слежу за этим блогом, чтобы идентифицировать сезонных клиентов в моих данных временных рядов: https://www.kristenkehrer.com/seasonality-code

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

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

Я что-то упускаю из виду?я не надумал попробовать это, будучи совсем новым для python?

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

Спасибо

Sample Data

import pandas as pa
import numpy as np
import pyodbc as py

cnxn = py.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password)

original = pa.read_sql_query('SELECT s.customer_id, s.yr, s.mnth, Case when s.usage<0 then 0 else s.usage end as usage  FROM dbo.Seasonal  s   Join   ( Select Top 2000  customer_id, SUM(usage) as usage   From dbo.Seasonal where Yr!=2018    Group by customer_id ) t ON s.customer_id = t.customer_id Where yr!= 2018 Order by customer_id, yr, mnth', cnxn)

grouped = original.groupby(by='customer_id')

def yearmonth_to_justmonth(year, month):

    return year * 12 + month - 1

def fillInForOwner(group):
    min = group.head(1).iloc[0]
    max = group.tail(1).iloc[0]
    minMonths = yearmonth_to_justmonth(min.yr, min.mnth)
    maxMonths = yearmonth_to_justmonth(max.yr, max.mnth)
    filled_index = pa.Index(np.arange(minMonths, maxMonths, 1), name="filled_months")
    group['months'] = group.yr * 12 + group.mnth - 1
    group = group.set_index('months')
    group = group.reindex(filled_index)
    group.customer_id = min.customer_id
    group.yr = group.index // 12
    group.mnth = group.index % 12 + 1
    group.usage = np.where(group.usage.isnull(), 0, group.usage).astype(int)
    return group

filledIn = grouped.apply(fillInForOwner)
newIndex = pa.Index(np.arange(filledIn.customer_id.count()))

import rpy2 as r
from rpy2.robjects.packages import importr
from rpy2.robjects import r, pandas2ri, globalenv
pandas2ri.activate()

base = importr('base')
colorspace = importr('colorspace')
forecast = importr('forecast')
times = importr('timeSeries')
stats = importr('stats')

outfile = 'results.csv'
df_list = []

for customerid, dataForCustomer in filledIn.groupby(by=['customer_id']):
    startYear = dataForCustomer.head(1).iloc[0].yr
    startMonth = dataForCustomer.head(1).iloc[0].mnth
    endYear = dataForCustomer.tail(1).iloc[0].yr
    endMonth = dataForCustomer.tail(1).iloc[0].mnth


    customerTS = stats.ts(dataForCustomer.usage.astype(int),
                      start=base.c(startYear,startMonth),
                      end=base.c(endYear, endMonth), 
                      frequency=12)
    r.assign('customerTS', customerTS)

    try:
        seasonal = r('''
                        fit<-tbats(customerTS, seasonal.periods = 12, 
                        use.parallel = TRUE)
                        fit$seasonal
                     ''')
    except: 
        seasonal = 1
    df_list.append({'customer_id': customerid, 'seasonal': seasonal})
    print(f' {customerid} | {seasonal} ')

seasonal_output = pa.DataFrame(df_list)
print(seasonal_output)
seasonal_output.to_csv(outfile)

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Обращаясь к ответу, я понял, как это работает, просто передав «оригинальный» кадр данных в цикл for.У моих данных уже были пустые $ 0 месяцев, поэтому мне не понадобилась эта часть кода для запуска.Спасибо всем за помощь

0 голосов
/ 26 октября 2018

Кристен здесь (это мой код).1 на самом деле означает, что клиенты не сезонные (или он не мог их забрать), а NULL также означает не сезонные.Если у них есть модель сезонного использования (период 12 месяцев, то есть то, что ищет код), он выдаст [12].

Вы всегда можете подтвердить это, изучив график поведения отдельных клиентов изатем положить его через алгоритм.Мне также понравилось перепроверять алгоритм сезонного разложения в Python или R.

Вот код R для просмотра декомпозиции вашего временного ряда.Если на графике нет сезонного окна, ваши результаты не являются сезонными:

library(forecast)
myts<-ts(mydata$SENDS, start=c(2013,1),end=c(2018,2),frequency = 12)
plot(decompose(myts))

Кроме того, вы упомянули о проблемах с некоторыми из 0, не заполняющих (из вашего разговора в твиттере), у меня не было этогопроблема, но мои клиенты имеют различную продолжительность пребывания от 2 до 13 лет.Не уверен, что проблема здесь.

Дайте мне знать, могу ли я чем-нибудь помочь:)

...