#!/usr/bin/env python
# coding: utf-8

# In[1]:


# import basic libraries
import numpy as np 
import pandas as pd 
import warnings
warnings.filterwarnings('ignore')
import pandas_profiling as pp
import random as rd # generating random numbers
import datetime # manipulating date formats

# import plot libraries
import seaborn as sns
sns.set_palette('Set2')
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')

# import ml libraries
from sklearn.linear_model import ElasticNet, Lasso,  BayesianRidge, LassoLarsIC, LinearRegression
from sklearn.ensemble import RandomForestRegressor,  GradientBoostingRegressor
from sklearn.svm import LinearSVR, SVR
from sklearn.kernel_ridge import KernelRidge
import xgboost as xgb
import lightgbm as lgb
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import LabelEncoder, MinMaxScaler, StandardScaler, RobustScaler
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from mlxtend.regressor import StackingCVRegressor
from sklearn.pipeline import make_pipeline
from sklearn import model_selection
import datetime


# TIME SERIES
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.statespace.sarimax import SARIMAX
from pandas.plotting import autocorrelation_plot
from statsmodels.tsa.stattools import adfuller, acf, pacf,arma_order_select_ic
import statsmodels.formula.api as smf
import statsmodels.tsa.api as smt
import statsmodels.api as sm
import scipy.stats as scs



# categories v1, v4, v8, v9, v11, v12, v16, classLabel
from sklearn.preprocessing import LabelEncoder
label = LabelEncoder()

# list number of files
import os
os.chdir(r'C:\Users\pokosun\Desktop\Python\Kaggle\Future Sales')


# In[2]:


# Import all of them 
sales=pd.read_csv("sales_train_v2.csv")
item_cat=pd.read_csv("item_categories.csv")
item=pd.read_csv("items.csv")
sub=pd.read_csv("sample_submission.csv")
shops=pd.read_csv("shops.csv")
test=pd.read_csv("test.csv")


# In[3]:


# display data

sales.head()


# In[4]:


# check column types

ctype = sales.dtypes.reset_index()
ctype.columns = ["Count", "Column Type"]
ctype.groupby("Column Type").aggregate('count').reset_index()

sales.info()


# In[5]:


#formatting the date column correctly
sales.date=sales.date.apply(lambda x:datetime.datetime.strptime(x, '%d.%m.%Y'))
# check
print(sales.info())


# In[6]:


# Aggregate to monthly level the required metrics

monthly_sales=sales.groupby(["date_block_num","shop_id","item_id"])[
    "date","item_price","item_cnt_day"].agg({"date":["min",'max'],"item_price":"mean","item_cnt_day":"sum"}).reset_index()

## Lets break down the line of code here:
# aggregate by date-block(month),shop_id and item_id
# select the columns date,item_price and item_cnt(sales)
# Provide a dictionary which says what aggregation to perform on which column
# min and max on the date
# average of the item_price
# sum of the sales


# In[7]:


# take a peak
monthly_sales.head(20)


# In[12]:


monthly_sales.describe()


# In[8]:


item.head()


# In[9]:


# number of items per cat 
x=item.groupby(['item_category_id']).count()
x=x.sort_values(by='item_id',ascending=False)
x=x.iloc[0:10].reset_index()
x
# #plot
plt.figure(figsize=(8,4))
ax= sns.barplot(x.item_category_id, x.item_id, alpha=0.8)
plt.title("Items per Category")
plt.ylabel('# of items', fontsize=12)
plt.xlabel('Category', fontsize=12)
plt.show()


# In[10]:


'''
Single series:
The objective requires us to predict sales for the next month at a store-item combination.

Sales over time of each store-item is a time-series in itself. Before we dive into all the combinations, first let's understand how to forecast for a single series.

I've chosen to predict for the total sales per month for the entire company.

First let's compute the total sales per month and plot that data.

'''

ts=sales.groupby(["date_block_num"])["item_cnt_day"].sum()
ts.astype('float')
plt.figure(figsize=(16,8))
plt.title('Total Sales of the company')
plt.xlabel('Time')
plt.ylabel('Sales')
plt.plot(ts);


# In[14]:


plt.figure(figsize=(16,6))
plt.plot(ts.rolling(window=12,center=False).mean(),label='Rolling Mean');
plt.plot(ts.rolling(window=12,center=False).std(),label='Rolling sd');
plt.legend();


# In[11]:


# multivariate analysis 

temp = train['item_cnt_day']
corrmat = temp.corr(method='spearman')
f, ax = plt.subplots(figsize=(20, 20))

sns.heatmap(corrmat, vmax=1., square=True, cmap="YlGnBu", annot=True)
plt.title("numerical variables correlation map", fontsize=15)
plt.show()


# In[ ]:


# split data

y = train.target
X = train.drop('target', axis=1, inplace=False)

X_train, X_val, y_train, y_val = train_test_split(X, y,random_state = 123)


# In[ ]:


# feature engineering on train/valid

label = LabelEncoder()
X_train['cat'] = label.fit_transform(X_train['cat']) # for categorical data

scaler = MinMaxScaler()            # for numerical data
scaler.fit(X_train)                      
X_train = scaler.transform(X_train)
X_val = scaler.transform(X_val)


# In[ ]:


# build model on train

model = linear_model.LogisticRegression(C=1e5) # RandomForestClassifier(), SVC(), RandomForestRegressor() etc

model.fit(X_train, y_train)

y_pred = model.predict(X_val)

model.score(X_train, y_train)


# In[ ]:


# evaluate on valid

confusion_matrix(y_val, y_pred) # for categorical target

mean_squared_error(y_true, y_pred) # for numerical target


# In[ ]:


# k-fold cross-validation

model = svm.SVC(kernel='linear', C=1)

scores = cross_val_score(model, X_train, y_train, cv=5)

print("Score: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))


# In[ ]:


# hyper-parameter tuning

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
    for C in [0.001, 0.01, 0.1, 1, 10, 100]:
        # for each combination of parameters,
        # train an SVC
        svm = SVC(gamma=gamma, C=C)
        # perform cross-validation
        scores = cross_val_score(svm, X_train, y_train, cv=5)
        # compute mean cross-validation accuracy
        score = np.mean(scores)
        # if we got a better score, store the score and parameters
        if score > best_score:
            best_score = score
            best_parameters = {'C': C, 'gamma': gamma}
# rebuild a model on the combined training and validation set
svm = SVC(**best_parameters)
svm.fit(X_train, y_train)


# In[ ]:




