# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3 (ipykernel)
#     language: python
#     name: python3
# ---

# +
# A chain of supermarket sotre wishes to build a sales prediction model that can help it understand what products sell in which 
# type of store. The data set contains a snappshot of historical sales from a selection of 10 stores on 1559 SKUs. The focus is
# on building a predictive model for sales based on the available features. 

#The first analysis is done using the statistical model followed by the machine learning approach.
# -

import pandas as pd 
import numpy as np 
import sklearn as skl 
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestRegressor
import statsmodels.api as sm

train_df = pd.read_csv('Train.csv')
test_df  = pd.read_csv('Test.csv')
sales_df = pd.read_csv('sales-data.csv')

train_df.isna().sum()

test_df.isna().sum()

train_df.describe()
#sales_df.describe()

# # Step 1 : Traditional Method of Building the Model 

# +
# In traditional approach we begin with a set of hypotheses around what to expect before we look at the output from the model.
# For this problem, few probable hypothesis could be that expected SKU sales would be more for the outlets where (1) the items
# is displayed prominently , (2) stores that are large and (3) price of the SKU is less on average.

# The next step once a set of hypotheses are formulated is to incorporate specific inputs as features into a model(usually linear)
# and test if our hypotheses are actually true.
# -

train_df.columns

#df1 = df[['a', 'b']]
#df1 = df.iloc[:, 0:2] # Remember that Python does not slice inclusive of the ending index.
x = train_df[['Item_Visibility','Item_MRP','Outlet_Establishment_Year']]
print(train_df.columns)
#x = train_df['Outlet_Type']
y = train_df['Item_Outlet_Sales']

sales_model = LinearRegression().fit(x,y)

sales_model.coef_

#X = sm.add_constant(X.ravel())
results = sm.OLS(y,x).fit()
results.summary() 

# +
#This is the traditional marketing research approach. It is important to note that generating a set of hypotheses about 
#the data generating process and collecting data allows the analyst to test these hypotheses. 
# -

train_x = train_df.drop('Item_Outlet_Sales',axis=1)

#Step 1 : Metric choice and data split 
#Since this is a problem involves prediction of numeric outcome i.e. sales , we choose RMSE as the metric. We then split the 
#training data further into training and vaildation subsets.
x_train,x_test,y_train,y_test = train_test_split(train_x,y,random_state=123,test_size=0.20)

x_train.reset_index().drop('index',axis=1)

y_train.reset_index().drop('index',axis=1)

x_test.reset_index().drop('index',axis=1)

y_test.reset_index().drop('index',axis=1)

# +
# We reiterate the fact that we do not touch the test data until we have the final models tuned to the training data.
# -

# # Step 2 : Pre-processing

x_train['Item_MRP'].describe()

x_train['Item_MRP_sc'] = (x_train['Item_MRP']- x_train['Item_MRP'].mean())/x_train['Item_MRP'].std()
x_train['Item_MRP_sc'].describe()

x_test['Item_MRP_sc'] = (x_test['Item_MRP']- x_test['Item_MRP'].mean())/x_test['Item_MRP'].std()
x_test['Item_MRP_sc'].describe()

x_train['Item_Visibility_sc'] = (x_train['Item_Visibility']- x_train['Item_Visibility'].mean())/x_train['Item_Visibility'].std()
x_train['Item_Visibility_sc'].describe()

x_test['Item_Visibility_sc'] = (x_test['Item_Visibility']- x_test['Item_Visibility'].mean())/x_test['Item_Visibility'].std()
x_test['Item_Visibility_sc'].describe()

x_train.head()

x_test.head()

len(x_train)

x_train_01 = x_train.copy()

len(x_test)

# +
#imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
#imputer.fit(x_train_01)
# -

x_train.head()

x_train['Outlet_Type']

x_train['Outlet_Identifier'].value_counts()

Label_enc = LabelEncoder()
Label_enc.fit(x_train['Outlet_Identifier'])
x_train.Outlet_Identifier  = Label_enc.transform(x_train.Outlet_Identifier)


def label_enc(col_arr,df):
    Label_enc = LabelEncoder()
    
    for i in range(0,len(col_arr)):
        Label_enc.fit(df[col_arr[i]])
        df[col_arr[i]]  = Label_enc.transform(df[col_arr[i]]) 


label_enc(['Item_Type','Item_Fat_Content','Item_Type','Outlet_Type','Outlet_Identifier','Outlet_Size','Outlet_Location_Type'],x_train)

label_enc(['Outlet_Identifier','Outlet_Type','Item_Type','Item_Fat_Content','Item_Type','Outlet_Identifier','Outlet_Size','Outlet_Location_Type'],x_test)

x_test.head()

# +
#x_train['Item_Weight'].fillna(method = 'ffill')
#x_train['Item_Weight'].fillna(method = 'bfill')

# +
#x_test['Item_Weight'].fillna(method = 'bfill')
#x_test['Item_Weight'].fillna(method = 'ffill')

# +
#x_test.head()

# +
#x_test['Item_Weight'].fillna(method = 'bfill')
#x_test['Item_Weight'].fillna(method = 'ffill')
# -

x_train['Item_Weight'].fillna(x_train['Item_Weight'].mean(),inplace = True)

x_test['Item_Weight'].fillna(x_test['Item_Weight'].mean(),inplace = True)

x_train.head()

x_test.head()

# # Step 3 : Model Training,performance measurement and model choice.

# +
# Here we usually start with models that have worked for this kind of data from prior experience or even just a choice of go-to 
# models. To illustrate the hyperparameter tuning process involved in training a machine learning model, we use a random forest
# model to learn from the data. This model is importanat hyperparameter that needs to be tuned during training- the number of trees.
# Focus is on tuning the model.

# +
# class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2,
#min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, 
#bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, 
#ccp_alpha=0.0, max_samples=None)

# +
#class sklearn.ensemble.RandomForestRegressor(n_estimators=100, *, criterion='squared_error', max_depth=None, 
#min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, 
#min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, 
#warm_start=False, ccp_alpha=0.0, max_samples=None)
# -

sales_model_random_forest = RandomForestRegressor(n_estimators= 1500,random_state = 42 )

x_train_01 = x_train.drop('Item_Identifier',axis=1)

x_train_01

sales_model_random_forest.fit(x_train_01,y_train)

sales_model_random_forest.score(x_train_01,y_train)

x_test_01 = x_test.drop('Item_Identifier',axis=1)

y_predicted = sales_model_random_forest.predict(x_test_01)

y_test_01 = y_test.reset_index().drop('index',axis=1)

y_predicted_01 = pd.Series(y_predicted)

y_predicted_01

# +
data = {"y_test" : y_test_01,
        "y_predicted" : y_predicted_01}

z = pd.concat(data,axis=1)
z
# -

len(x_test_01)

y_test_01 = np.array(y_test_01)

y_predicted_01 = np.array(y_predicted)

#Calculate absolute errors 
errors = abs(y_predicted_01 - y_test_01)
np.mean(errors)

#calculate the MAPE 
mape = 100* (errors/y_test_01)
np.mean(mape)

# +
# To be continued with Decision Tree Project 

StarcoderdataJupyterScriptsDedupFiltered