Компоненты для анализа и прогнозирования

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

UML - диаграмма класса представлена на рис. 3.4.


Рисунок 3.4 - UML-диаграмма класса Аналитик.

Функция прогнозирования вынесена в рамках отдельного модуля. Прогнозирование аукционует класс Forecaster. С модулем, доступно им класс Forecaster, можно ознакомиться в приложении D. UML диаграмма класса Forecaster доступен на рис. 3.5

Рисунок 3.5 - UML-диаграмма класса Forecaster.

Метод get_model генерирует множество моделей и сравнивает их с помощью AIC, присваивает модели, у которых AIC минимален. Код этого параметра отображается в листинге 7.

Листинг 7. Код метод аget_model.

defget_model (self):

p = d = q = диапазон (RANGE_LOW, RANGE_HIGH)

pdq = list (itertools. product (p, d, q))

сезонный = [(x [0], x [1], x [2], 12) для x в pdq]

aic = VERY_BIG_NUMBER

модель = {'pdq':(0,0,0), 'PDQs':(0,0,0,12)}

модель ['s'] = 12

 для параметра в pdq:

 для s_param в сезон:

пытаться:

mod = sm.tsa.statespace.SARIMAX (у,

порядок = пары,

seasonal_order = s_param,

enforce_stationarity = False,

enforce_invertibility = False)

результат = mod.fit ()

 печать (result.aic)

ifresult.aic<aic:

печать(«ЛУЧШЕ»)

aic = result.aic

модель ['pdq'] = парам

модель ['PDQs'] = s_param

Кроме:

Продолжать

самостоятельно. модель = модель

returnmodel

 

Get_modelсоздает список значений параметров, обходит этот список, включает значения в модели, расчитывает AIC и сравнивает с ранее имеющимся минимальным значением.

Метод fit_model () разрешает обучить модель закономерностям базам данных на входе. Статистические свойства модели показаны в консоли. После подготовки модель готова для создания прогнозов.

Метод get_prediction () возвращает список прогнозированных значений. Это самый значительный метод класса Прогноз: он использует методы, которые подготавливают модель, вычисляет прогноз и доверительные интервалы.

На листинге 8 показано, как работает метод get_prediction ().

Листинг 8. Кодget_prediction ()

defget_prediction (self, data, start, as_ts = False):

fit = self.fit_model (данные)

печать (self.model)

pred = fit.get_forecast (steps = 10)

печать (pred.predicted_mean)

pred_ci = pred.conf_int ()

еслиas_ts:

return [{'date': start, 'total': pred}]

возврат (начало, пред, пред_ци)

 

Сначала вызывается метод fit_model, он вызывает дает метод get_ model. Прогнозируется на 20 дней вперед переменной pred.Доверительный интервал записывают в переменную pred_ci.

 

Тестовые данные

 

Информация о продажах является коммерческой тайной. Это создало необходимость генерировать данные самостоятельно.

За модуль тестовых данных отвечает на модуль mock.py. Использована следующая система:

1. В названии продукта есть имена из 4 латинских букв. Эти буквы показывают определенное свойство товара. Первая буква- в каком количестве покупается товар. Клиенты чаще покупают этот продукт. Второй - продаваемость товара, выраженная как вероятность покупки, третий - цена, четвертый - качество.

2. При вычислении вероятности покупки товара используются следующие оценки:

a. Для последних трех букв: MARK_WEIGHT_5 = {'A': 0,255, 'B': 0,240, 'C': 0,233, 'D': 0,200, 'E': 0,153}.

b. Для первой буквы: MARK_WEIGHT_2 = {'A': 0,6, 'B': 0,4,}.

c. Для категорий (см. CATEGORY_WEIGHTв приложении 1).

3. Формула для этой вероятности: p = fr * ca * (1-pr) * qu + a, где p – вероятность, ca – вес категории, pr – вес цены, qu – вес качества, a – случайная величина.

4. Количество посетителей и число покупателей - случайные числа с распределением Пуассона в окрестностях некоторой точки, которые назначены разработчиком из соображений личного опыта.

Полный код модуля mock.py отображен в приложении 1.


 


Вывод

 

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

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

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

Разработка программного продукта: от внешнего вида до математических моделей прогнозирования. Реализованы спроектированные ранее модули и созданы проектируемое программное обеспечение. Была реализована поставленная задача.





Заключение

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

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

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


 


Список литературы

1. Kate, A. Smith. Neural Networks in Business: Techniques and Applications / A. Smith. Kate, N. D. Jatinder. – Лондон: Idea Group Publishing, 2002. – 272 c.

2. Django over view [Электронный ресурс]. – Режим доступа: https://www.django project.com/start/overview/, свободный. – Загл. с экрана.

3. How to Perform Sales Trend Analysis For Your Retail Business [Электронный ресурс]. – Режим доступа: https://www.nchannel.com/blog/how-to-perform-sales-trend-analysis/, свободный. – Загл. с экрана.

4. A Guide to Time Series Forecasting with ARIMA in Python 3 [Электронный ресурс]. – Режим доступа: https://www.digitalocean.com/community/tutorials/a-guide-to-time-series-forecasting-with-arima-in-python-3, свободный. – Загл. с экрана.

5. Stats Models Documentation [Электронный ресурс]. – Режим доступа:http://www.statsmodels.org/dev/index.html, свободный. – Загл. с экрана.

6. SARIMAX Analysis | Seasonal ARIMA Exogenous | Reference Manual | Num XL [Электронный ресурс]. – Режим доступа: http://www.spiderfinancial.com/support/documentation/numxl/reference-manual/arma-analysis/sarimax-analysis, свободный. – Загл. с экрана.

7. NumPyReference [Электронный ресурс]. – Режим доступа: https://docs.scipy.org/doc/numpy/reference/, свободный. – Загл. с экрана.

8. Стив, Макконнелл. Совершенный код. Мастер-класс / Макконнелл. Стив. – М.: "Русская редакция", 2010. – 889 c.

9. Sunil, Supra. Artificial Neural Networks: State of the Art in Business Intelligence / Supra. Sunil. // Business and Economics Journal. – 2016. – 7. –

С. 1-2.

10. Autoregressive integrated moving average - Wikipedia [Электронный ресурс]. – Режим доступа: https://en.wikipedia.org/wiki/Autoregressive_integrated_moving_average, свободный. – Загл. с экрана.

11. Akaike information criterion - Wikipedia [Электронный ресурс]. – Режим доступа: https://en.wikipedia.org/wiki/Akaike_information_criterion, свободный. – Загл. с экрана.





Приложения

Приложение А

fromcore.modelsimport *

fromdatetime import datetime, timedelta,date

import django.utils.timezone as tz

import random

from math import exp, pi,sqrt

from numpy.random import normal,standard_normal, poisson, ranf,sample,choice

#Constants

 

VISITORS_MEAN = 50

VISIT_TIME_MEAN = 18

HOURS_PER_DAY = 24

VISITOR_WANTS_TO_BUY_EDGE = 0.4

PRODUCTS_MEAN = 5

ITEMS_OBSERVED_MEAN = 12

ITEMS_BOUGHT_MEAN = 6

 

# Weights of categories

CATEGORY_WEIGHT = {

1:16/30,

2:20/30,

3:16/30,

4:12/30,

5:18/30,

6:14/30,

7:18/30,

8:13/30,

9:19/30,

10:13/30,

11:17/30,

12:10/30

}

MARK_WEIGHT_5 = {

'A': 0.255,

'B':0.245,

'C':0.233,

'D':0.204,

'E':0.153,

}

MARK_WEIGHT_2 = {

'A': 0.6,

'B': 0.4,

}

def get_probability_of_buying_product(product):

count, frequency, price, quality = tuple(product.name)

count_w = MARK_WEIGHT_2[count]

frequency_w = MARK_WEIGHT_5[frequency]

price_w = MARK_WEIGHT_5[price]

quality_w = MARK_WEIGHT_5[quality]

category_w = CATEGORY_WEIGHT[product.category.id]

return frequency_w*category_w*(1 - price_w)*quality_w+ranf(1)[0]

def create_product(signature,category):

"""

   Create product with signature and price of given category

"""

costs_marks={'A':1000,'B':800,'C':600,'D':400,'E':200}

cost_price = costs_marks[signature[2]]

sale_price = cost_price*1.6

prod = Product.objects.create(name=signature, cost_price=cost_price, sale_price=sale_price,category = category)

print("Product creating: {0}%".format(Product.objects.all().count()/3000*100))

def create_products():

"""

   Create some products with different names in different categories

"""

categories = Category.objects.all()

for q in ['A','B']:

   #Q: A - is bought in single, B - clients prefer to buy a lot of this Product at once

for f in ['A','B','C','D','E']:

       # f: Frequency(or popularity) A - popular; E - sometimes taken

for p in ['A','B','C','D','E']:

           # p: Price; A - expensive; E - cheap

for qu in ['A','B','C','D','E']:

               # qu: Quality: A - wow! E - nope;

for category in categories:

signature = q+f+p+qu

                   create_product(signature,category)

def imitate_clients_buying_stuff(date):

"""

   Randomly chooses items to buy and their count

"""

order = Order.objects.create(date=tz.make_aware(date),total=0)

items_count = poisson(ITEMS_OBSERVED_MEAN,1)%Product.objects.all().count()

products = choice(Product.objects.all(),size=items_count)

ps_of_products = [get_probability_of_buying_product(x) for x in products]

scale = 1/sum(ps_of_products)

ps_of_products = list(map(lambda x:x*scale,ps_of_products))

basket = choice(products,size=ITEMS_BOUGHT_MEAN, p = ps_of_products)

for x in set(basket):

   product_count = poisson(PRODUCTS_MEAN,1)

po = ProductsOrders.objects.create(order=order,product=x,count=product_count,total=x.get_revenue(product_count))

order.total+=po.total

order.save()

def time(year,month,day,hours):

"""

   Produces datetime object with given parameters, but if hours has remainder, minutes are also obtained.

   For example, 23.50 -> 23 hours and 30 minutes

"""

h = int(hours)

minutes = (hours-h)*60

return datetime(year=year, month=month,day=day,hour=h, minute=int(minutes))

def imitate_clients_entering_shop(dateFrom, dateTo):

"""

   Populate database with information about client behavior

"""

time_cursor = dateFrom

days_between = (dateTo-dateFrom).days

while time_cursor<dateTo:

   days_passed = (time_cursor-dateFrom).days

print('Populating...{0}%'.format(round(days_passed/days_between*100,2)))

   # Let count of incomers be Poisson-distributed variable with mean VISITORS_MEAN

incomers = poisson(VISITORS_MEAN,1)

   visit_times = normal(VISIT_TIME_MEAN,sqrt(HOURS_PER_DAY),incomers) # Times when visitor entered shop is normally distributed with mean at 18:00 and SD=sqrt(24)

for hour in visit_times:

day = time(time_cursor.year,time_cursor.month, time_cursor.day, hour%HOURS_PER_DAY)

Client.objects.create(date=tz.make_aware(day))

       visitor_wants_to_buy = ranf(1) # Assume that visitor's intention to buy is normally distributed

shock = ranf(1)        # Normally distributed error

       visitor_buys = shock + visitor_wants_to_buy

if visitor_buys >= VISITOR_WANTS_TO_BUY_EDGE:

           imitate_clients_buying_stuff(day)

   time_cursor+=timedelta(days=1)

def populate(dateFrom,dateTo):

#create_products()

imitate_clients_entering_shop(dateFrom,dateTo)

return Client.objects.all().count()

d1 = date.today()-timedelta(days=365)

d2 = date.today()+timedelta(days=1)

print("Clients added: ",populate(d1,d2))





ПриложениеB

from django.db import models

from pygments.lexers import get_all_lexers

from pygments.styles import get_all_styles

import core.utils as utils

from django.db.models import Sum

from datetime import datetime, timedelta,date

 

# Constants

CHAR_FIELD_MAX_LENGTH = 40

TOP_SIZE = 10

# Create your models here.

PROFILING = False

DEBUG = True

from core.utils import Profiler

def prepare_date(dt):

return dt.strftime('%Y-%m-%d')

class Client(models.Model):

date = models.DateField(null=False, blank=False)

def __str__(self):

return 'Client entered at: '+self.date.__str__()

def get_total_incomers(dateframe):

clients = Client.objects.filter(date__range=utils.get_interval(date.today(),dateframe))

return clients.count()

def get_conversion(dateframe):

purchases = Order.get_orders(dateframe).count()

incomers = Client.get_total_incomers(dateframe)

if incomers ==0:

return 0

return round(purchases/incomers*100,2);

class Category(models.Model):

name = models.CharField(null=False, blank=False,max_length=CHAR_FIELD_MAX_LENGTH)

def __str__(self):

return self.name

def get_top_products(self, topsize, dateframe):

   """

       Returns sorted list of bestseller products

   """

profiler = Profiler("Category.get_antitop_products")

profiler.start()

   # Form query for dateframe

today = datetime.today()

result = ProductsOrders.objects.values('product').\

filter(order__date__range=utils.get_interval(today,dateframe)).\

filter(product__category=self).\

annotate(prod_count=Sum('count')).\

       order_by('-prod_count')[:TOP_SIZE]  

result = sorted(result,reverse=True,key=lambda item:item['prod_count'])

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return [{"name":Product.objects.get(id=x['product']).name, "count":x['prod_count']} for x in result]

def get_antitop_products(self, topsize, dateframe):

   """

       Returns sorted list of worstseller products

   """

profiler = Profiler("Category.get_antitop_products")

profiler.start()

   # Form query for dateframe

today = datetime.today()

   date_query = {

       'order__date__year':today.year,

   }

if (dateframe == 'month'):

       date_query['order__date__month'] = today.month

elif(dateframe=='day'):

       date_query['order__date__month'] = today.month

       date_query['order__date__day'] = today.day

result = ProductsOrders.objects.values('product').\

filter(**date_query).\

filter(product__category=self).\

annotate(prod_count=Sum('count')).\

       order_by('prod_count')[:TOP_SIZE]       

result = sorted(result,key=lambda item:item['prod_count'])

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return [{"name":Product.objects.get(id=x['product']).name, "count":x['prod_count']} for x in result]

class Product(models.Model):

sale_price = models.FloatField(null=False, blank=False) #Price which is used by clients

name = models.CharField(max_length=CHAR_FIELD_MAX_LENGTH, null=False, blank=False)

cost_price = models.FloatField(null=False, blank=False)

category = models.ForeignKey('Category', on_delete=models.CASCADE)

def __str__(self):

return self.name

def get_revenue(self,count):

return self.sale_price *count

def is_category(self, category):

return self.category==category

def get_total_for_day(self,dt):

tomorrow = utils.get_tomorrow()

yesterday = utils.get_yesterday()

pos = ProductsOrders.objects.filter(order__date__gt=yesterday,order__date__lt=tomorrow).\

filter(product=self).aggregate(Sum('total'))

return pos['total__sum']

class Order(models.Model):

date = models.DateField(null=False, blank=False)

total = models.FloatField(default=0)

def __str__(self):

return 'Order<'+self.date.__str__()+'>'

def recalculate_total(self):

self.total = self.productsorders_set.all().aggregate(Sum('total'))['total__sum']

self.save()

def get_orders(dateframe):

   """

       Return orders for given dateframe

   """

orders = Order.objects.filter(date__range = utils.get_interval(date.today(),dateframe)) #Empty filterse

return orders

class ProductsOrders(models.Model):

order = models.ForeignKey('Order',on_delete=models.CASCADE)

product = models.ForeignKey('Product', on_delete=models.CASCADE)

count = models.IntegerField(null=False,blank=False)

total = models.FloatField(default=0)

def __str__(self):

return "<"+str(self.order.id)+":"+self.product.name+'-----'+str(self.count)+'>'

def recalculate_total(self):

self.total = self.product.get_revenue(self.count)

self.save()

def get_category_total(category,dateframe='day'):

   """

       Returns total income in given dateframe for category

   """

profiler = Profiler("PRoductsOrders.get_category_total")

profiler.start()

today = date.today()

total = 0

pos = ProductsOrders.objects.filter(

       product__category=category,

       order__date__range=utils.get_interval(today,dateframe))

for pos_rec in pos:

total+=pos_rec.product.get_revenue(pos_rec.count)

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return total

def get_time_series(dateframe, product,full=False):

today = datetime.today()

if full:

pos = ProductsOrders.objects.all()

else:

pos = ProductsOrders.objects.filter(order__date__range=utils.get_interval(today,dateframe))

   dates_total = pos.filter(product=product).\

values('order__date','total')

dates = {prepare_date(x['order__date']) for x in dates_total}

result = dict.fromkeys(dates,0)

for x in dates_total:

result[prepare_date(x['order__date'])]+=x['total']

result = sorted([{'date':x,'total':result[x]}for x in result.keys()],key=lambda x:x['date'])

return result





ПриложениеC

from django.db import models

from pygments.lexers import get_all_lexers

from pygments.styles import get_all_styles

import core.utils as utils

from django.db.models import Sum

from datetime import datetime, timedelta,date

# Constants

CHAR_FIELD_MAX_LENGTH = 40

TOP_SIZE = 10

# Create your models here.

PROFILING = False

DEBUG = True

from core.utils import Profiler

def prepare_date(dt):

return dt.strftime('%Y-%m-%d')

class Client(models.Model):

date = models.DateField(null=False, blank=False)

def __str__(self):

return 'Client entered at: '+self.date.__str__()

def get_total_incomers(dateframe):

clients = Client.objects.filter(date__range=utils.get_interval(date.today(),dateframe))

return clients.count()

def get_conversion(dateframe):

purchases = Order.get_orders(dateframe).count()

incomers = Client.get_total_incomers(dateframe)

if incomers ==0:

return 0

return round(purchases/incomers*100,2);

class Category(models.Model):

name = models.CharField(null=False, blank=False,max_length=CHAR_FIELD_MAX_LENGTH)

def __str__(self):

return self.name

def get_top_products(self, topsize, dateframe):

   """

       Returns sorted list of bestseller products

   """

profiler = Profiler("Category.get_antitop_products")

profiler.start()

   # Form query for dateframe

today = datetime.today()

result = ProductsOrders.objects.values('product').\

filter(order__date__range=utils.get_interval(today,dateframe)).\

filter(product__category=self).\

annotate(prod_count=Sum('count')).\

       order_by('-prod_count')[:TOP_SIZE]  

result = sorted(result,reverse=True,key=lambda item:item['prod_count'])

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return [{"name":Product.objects.get(id=x['product']).name, "count":x['prod_count']} for x in result]

def get_antitop_products(self, topsize, dateframe):

   """

       Returns sorted list of worstseller products

   """

profiler = Profiler("Category.get_antitop_products")

profiler.start()

   # Form query for dateframe

today = datetime.today()

   date_query = {

       'order__date__year':today.year,

   }

if (dateframe == 'month'):

       date_query['order__date__month'] = today.month

elif(dateframe=='day'):

       date_query['order__date__month'] = today.month

       date_query['order__date__day'] = today.day

result = ProductsOrders.objects.values('product').\

filter(**date_query).\

filter(product__category=self).\

annotate(prod_count=Sum('count')).\

       order_by('prod_count')[:TOP_SIZE]       

result = sorted(result,key=lambda item:item['prod_count'])

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return [{"name":Product.objects.get(id=x['product']).name, "count":x['prod_count']} for x in result]

class Product(models.Model):

sale_price = models.FloatField(null=False, blank=False) #Price which is used by clients

name = models.CharField(max_length=CHAR_FIELD_MAX_LENGTH, null=False, blank=False)

cost_price = models.FloatField(null=False, blank=False)

category = models.ForeignKey('Category', on_delete=models.CASCADE)

def __str__(self):

return self.name

def get_revenue(self,count):

return self.sale_price *count

def is_category(self, category):

return self.category==category

def get_total_for_day(self,dt):

tomorrow = utils.get_tomorrow()

yesterday = utils.get_yesterday()

pos = ProductsOrders.objects.filter(order__date__gt=yesterday,order__date__lt=tomorrow).\

filter(product=self).aggregate(Sum('total'))

return pos['total__sum']

class Order(models.Model):

date = models.DateField(null=False, blank=False)

total = models.FloatField(default=0)

def __str__(self):

return 'Order<'+self.date.__str__()+'>'

def recalculate_total(self):

self.total = self.productsorders_set.all().aggregate(Sum('total'))['total__sum']

self.save()

def get_orders(dateframe):

   """

       Return orders for given dateframe

   """

orders = Order.objects.filter(date__range = utils.get_interval(date.today(),dateframe)) #Empty filterse

return orders

class ProductsOrders(models.Model):

order = models.ForeignKey('Order',on_delete=models.CASCADE)

product = models.ForeignKey('Product', on_delete=models.CASCADE)

count = models.IntegerField(null=False,blank=False)

total = models.FloatField(default=0)

def __str__(self):

return "<"+str(self.order.id)+":"+self.product.name+'-----'+str(self.count)+'>'

def recalculate_total(self):

self.total = self.product.get_revenue(self.count)

self.save()

def get_category_total(category,dateframe='day'):

   """

       Returns total income in given dateframe for category

   """

profiler = Profiler("PRoductsOrders.get_category_total")

profiler.start()

today = date.today()

total = 0

pos = ProductsOrders.objects.filter(

       product__category=category,

       order__date__range=utils.get_interval(today,dateframe))

for pos_rec in pos:

total+=pos_rec.product.get_revenue(pos_rec.count)

profiler.finish()

if PROFILING:

print(profiler.get_verbose())

return total

def get_time_series(dateframe, product,full=False):

today = datetime.today()

if full:

pos = ProductsOrders.objects.all()

else:

pos = ProductsOrders.objects.filter(order__date__range=utils.get_interval(today,dateframe))

   dates_total = pos.filter(product=product).\

values('order__date','total')

dates = {prepare_date(x['order__date']) for x in dates_total}

result = dict.fromkeys(dates,0)

for x in dates_total:

result[prepare_date(x['order__date'])]+=x['total']

   result = sorted([{'date':x,'total':result[x]}for x in result.keys()],key=lambda x:x['date'])

return result


 


ПриложениеD

from core.models import *

# CONSTANT

RANGE_LOW = 0

RANGE_HIGH = 4

VERY_BIG_NUMBER = 10**1000

import pandas as pd

import itertools

import warnings

import statsmodels.api as sm

import matplotlib.pyplot as plt

import numpy as np

class Forecaster:

def get_dataframe(array):

   """Array = list of dict { date: value}"""

return pd.DataFrame(array)

model = None

def get_model(self,data):

   p = d = q = range(RANGE_LOW, RANGE_HIGH)

pdq = list(itertools.product(p,d,q))

seasonal = [(x[0],x[1],x[2],12) for x in pdq]

model = {'pdq':(0,0,0),'PDQs':(0,0,0,12)}

model['s'] = 12

aic = 100*10000

for param in pdq:

for s_param in seasonal:

try:

mod = sm.tsa.statespace.SARIMAX(data,

order=param,

                                           seasonal_order=s_param,

                                           enforce_stationarity=False,

                                           enforce_invertibility=False)

result = mod.fit()

print(result.aic)

if result.aic < aic:

print("BETTER")

aic = result.aic

model['pdq'] = param

model['PDQs'] = s_param

except TypeError:

continue

self.model = model

return model

def fit_model(self,data):

   pd_data = Forecaster.get_dataframe(data)

   pd_data = pd_data.set_index(['date'])

   pd_data.index = pd.to_datetime(pd_data.index)

   pd_data = pd_data.resample('MS').mean()

   pd_data = pd_data.dropna()

print(pd_data)

   pd_data = pd_data.fillna(pd_data.bfill())

print(pd_data)

   self.get_model(data)

mod = sm.tsa.statespace.SARIMAX(pd_data['total'].astype(float),

order=self.model['pdq'],

                           seasonal_order=self.model['PDQs'],

                           enforce_stationarity=False,

                           enforce_invertibility=False)

result = mod.fit()

print(result.summary().tables[1])

   #result.plot_diagnostics(figsize=(15,12))

   #plt.show()

return result

def get_prediction(self,data,start,as_ts=False):

fit= self.fit_model(data)

print(self.model)

pred = fit.get_forecast(steps=10)

print(pred.predicted_mean)

   pred_ci = pred.conf_int()

if as_ts:

return [{'date':start,'total':pred}]

return (start,pred,pred_ci)

 

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: