5种用于预测销售的机器学习技术

即将开播:4月29日,民生银行郭庆谈商业银行金融科技赋能的探索与实践

预测销售是机器学习(ML)的常见且必不可少的用途。预测销售可用于确定基准并确定新计划的增量影响,根据预期需求规划资源以及规划未来预算。在本文中,我将展示如何实现5种不同的ML模型来预测销售。

初期准备

首先我们先加载数据并将其转换为一个结构,然后将其用于每个模型。以原始格式,每一行数据代表十个商店中一天的销售额。我们的目标是预测月度销售额,因此我们将首先将所有商店和天数合并为月度总销售额。

def load_data():   
    return pd.read_csv('D:\Jupyter\dataset\demand-forecasting-kernels-only/train.csv')   
 
 
def monthly_sales(data): 
    monthly_data = data.copy() 
    monthly_datamonthly_data.date = monthly_data.date.apply(lambda x: str(x)[:-3]) 
    monthly_datamonthly_data = monthly_data.groupby('date')['sales'].sum().reset_index() 
    monthly_data.date = pd.to_datetime(monthly_data.date) 
    return monthly_data 
 
monthly_df = monthly_sales(sales_data) 
monthly_df.head() 

5种用于预测销售的机器学习技术

在我们的新数据框中,每一行现在代表所有商店在给定月份的总销售额。

5种用于预测销售的机器学习技术

如果我们绘制随时间变化的每月总销售量,我们会看到平均每月销售量随时间增加,这意味着我们的数据不是固定的。为了使其平稳,我们将计算每月销售额之间的差异,并将其作为新列添加到我们的数据框中。

def get_diff(data): 
    data['sales_diff'] = data.sales.diff() 
    datadata = data.dropna() 
     
    data.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/stationary_df.csv') 
    return data 
 
stationary_df = get_diff(monthly_df) 

5种用于预测销售的机器学习技术

下面是差异转换前后数据外观的直观表示:

5种用于预测销售的机器学习技术

比较差异前后的平稳性

现在,我们的数据代表了每月的销售额,并且已经将其转换为固定值,接下来我们将为不同的模型类型设置数据。为此,我们将定义两种不同的结构:一种将用于ARIMA建模,另一种将用于其余的模型。

对于我们的Arima模型,我们只需要一个日期时间索引和因变量(销售额差异)列。

def generate_arima_data(data): 
    dt_data = data.set_index('date').drop('sales', axis=1) 
    dt_data.dropna(axis=0) 
     
    dt_data.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/arima_df.csv') 
     
    return dt_data 
 
arima_datetime = generate_arima_data(stationary_df) 

对于其他模型,我们将创建一个新的数据框,其中每个特征代表上个月的销售额。为了确定在我们的特征集中包含多少个月,我们将观察自相关和部分自相关图,并在ARIMA建模中使用选择滞后时间的规则。这样,我们就可以为我们的ARIMA和回归模型保持一致的回顾周期。

5种用于预测销售的机器学习技术

自相关和局部自相关图

基于上述情况,我们将选择回溯期为12个月。因此,我们将生成一个包含13列的数据框,12个月每个月为1列,而我们的因变量即销售额差异列为第1列。

def generate_supervised(data): 
    supervised_df = data.copy() 
     
    #create column for each lag 
    for i in range(1,13): 
        col_name = 'lag_' + str(i) 
        supervised_df[col_name] = supervised_df['sales_diff'].shift(i) 
     
    #drop null values 
    supervised_dfsupervised_df = supervised_df.dropna().reset_index(drop=True) 
     
    supervised_df.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/model_df.csv', index=False) 
     
    return supervised_df 
 
model_df = generate_supervised(stationary_df) 

5种用于预测销售的机器学习技术

现在我们有两个独立的数据结构,一个是Arima结构,它包含一个datetime索引,另一个是监督结构,它包含滞后时间特征。

5种用于预测销售的机器学习技术

ARIMA和受监督的数据框用于销售预测

建模

为了创建和评估所有的模型,我们使用了一系列执行以下函数的辅助函数。

  • 训练、测试、拆分:我们将数据分开,使过去的12个月成为测试集的一部分,其余数据用于训练我们的模型
  • 缩放数据:使用最小-最大缩放器,我们将缩放数据,以便所有变量都在-1到1的范围内
  • 反向缩放:运行模型后,我们将使用此辅助函数来反转步骤2的缩放
  • 创建一个预测数据框:生成一个数据框,其中包括在测试集中捕获的实际销售额和模型的预测结果,以便我们能够量化我们的成功
  • 对模型评分:这个辅助函数将保存我们预测的均方根误差(RMSE)和均值绝对误差(MAE),以比较五个模型的性能

1. 回归模型:线性回归,随机森林回归,XGBoost

对于我们的回归模型,我们可以使用scikit-learn库的fit-predict结构。因此,我们可以建立一个基础建模结构,我们将针对每个模型进行调用。下面的函数调用上面概述的许多辅助函数来拆分数据,运行模型并输出RMSE和MAE分数。

def regressive_model(train_data, test_data, model, model_name): 
     
    # Call helper functions to create X & y and scale data 
    X_train, y_train, X_test, y_test, scaler_object =  
        scale_data(train_data, test_data) 
     
    # Run regression model 
    mod = model 
    mod.fit(X_train, y_train) 
    predictions = mod.predict(X_test) 
    # Call helper functions to undo scaling & create prediction df 
    original_df = pd.read_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/train.csv') 
    unscaled = undo_scaling(predictions, X_test, scaler_object) 
    unscaled_df = predict_df(unscaled, original_df) 
    # Call helper functions to print scores and plot results 
    get_scores(unscaled_df, original_df, model_name) 
    plot_results(unscaled_df, original_df, model_name) 
 
# Separate data into train and test sets 
train, test = tts(model_df) 
# Call model frame work for linear regression 
regressive_model(train, test, LinearRegression(),'LinearRegression') 
# Call model frame work for random forest regressor  
regressive_model(train, test,  
                 RandomForestRegressor(n_estimators=100, 
                                       max_depth=20),         
                                       'RandomForest') 
# Call model frame work for XGBoost 
regressive_model(train, test, XGBRegressor(n_estimators=100, 
                                           learning_rate=0.2),  
                                           'XGBoost') 

5种用于预测销售的机器学习技术

下面的输出显示了每个回归模型的预测(红色)覆盖在实际销售(蓝色)之上。虽然结果看起来很相似,但细微的差别相当于几千美元的销售额,我们将在下面的比较部分中看到。

5种用于预测销售的机器学习技术

2. 长短期记忆(LSTM)

LSTM是一种递归神经网络,对于使用顺序数据进行预测特别有用。为此,我们将使用非常简单的LSTM。为了提高准确性,可以添加周期性特征和附加模型复杂性。

def lstm_model(train_data, test_data): 
     
    X_train, y_train, X_test, y_test, scaler_object = scale_data(train_data, test_data) 
     
    X_trainX_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1]) 
    X_testX_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1]) 
    
    model = Sequential() 
    model.add(LSTM(4, batch_input_shape=(1, X_train.shape[1], X_train.shape[2]),  
                   stateful=True)) 
    model.add(Dense(1)) 
    model.add(Dense(1)) 
    model.compile(loss='mean_squared_error', optimizer='adam') 
    model.fit(X_train, y_train, epochs=200, batch_size=1, verbose=1,  
              shuffle=False) 
    predictions = model.predict(X_test,batch_size=1) 
     
    original_df = load_original_df() 
    unscaled = undo_scaling(predictions, X_test, scaler_object, lstm=True) 
    unscaled_df = predict_df(unscaled, original_df) 
     
    get_scores(unscaled_df, original_df, 'LSTM') 
     
    plot_results(unscaled_df, original_df, 'LSTM') 

5种用于预测销售的机器学习技术

生成的图看起来与上面的三个回归图相似,因此我们将继续比较结果,直到我们看到下面的误差为止。

5种用于预测销售的机器学习技术

LSTM模型预测与实际销售额

3. ARIMA

ARIMA模型看起来与上面的模型略有不同。我们使用statsmodels SARIMAX软件包来训练模型并生成动态预测。SARIMA模型分为几个部分。

  • AR:表示为p,是自回归模型
  • I:用d表示,是微分项
  • MA:表示为q,是移动平均模型
  • S:使我们能够添加周期性成分

在下面的代码中,我们定义我们的模型,然后对数据的最后12个月进行动态预测。对于标准的非动态预测,下个月的预测是使用前几个月的实际销售额进行的。相反,对于动态预测,使用前几个月的预测销售额进行下个月的预测。

def lstm_model(train_data, test_data): 
     
    X_train, y_train, X_test, y_test, scaler_object = scale_data(train_data, test_data) 
     
    X_trainX_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1]) 
    X_testX_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1]) 
    
    model = Sequential() 
    model.add(LSTM(4, batch_input_shape=(1, X_train.shape[1], X_train.shape[2]),  
                   stateful=True)) 
    model.add(Dense(1)) 
    model.add(Dense(1)) 
    model.compile(loss='mean_squared_error', optimizer='adam') 
    model.fit(X_train, y_train, epochs=200, batch_size=1, verbose=1,  
              shuffle=False) 
    predictions = model.predict(X_test,batch_size=1) 
     
    original_df = load_original_df() 
    unscaled = undo_scaling(predictions, X_test, scaler_object, lstm=True) 
    unscaled_df = predict_df(unscaled, original_df) 
     
    get_scores(unscaled_df, original_df, 'LSTM') 
     
    plot_results(unscaled_df, original_df, 'LSTM') 

同样,结果看起来还不错。我们将在下面进一步进行挖掘。

5种用于预测销售的机器学习技术

ARIMA模型预测与实际销售额

比较模型

为了比较模型性能,我们将查看均方根误差(RMSE)和均值绝对误差(MAE)。这些指标通常都用于比较模型性能,但是它们的直觉和数学含义略有不同。

  • MAE:均值绝对误差告诉我们,我们的预测与真实值之间的距离。在这种情况下,所有误差的权重都相同。
  • RMSE:我们通过取所有平方误差之和的平方根来计算RMSE。当我们平方时,较大的误差对整体误差有较大的影响,而较小的误差对整体误差没有太大的影响。

从上面的辅助函数中,我们使用get_scores计算每个模型的RMSE和MAE分数。这些分数保存在字典中并保存起来。为了进行比较,我们将把字典转换成Pandas数据框并绘制结果。

def create_results_df(): 
    results_dict = pickle.load(open("model_scores.p", "rb")) 
     
    results_dict.update(pickle.load(open("arima_model_scores.p", "rb"))) 
     
    restults_df = pd.DataFrame.from_dict(results_dict, orient='index',  
                                        columns=['RMSE', 'MAE','R2']) 
     
    restults_dfrestults_df = restults_df.sort_values(by='RMSE', ascending=False).reset_index() 
     
    return restults_df 
 
results = create_results_df() 

这为我们提供了以下数据框。

5种用于预测销售的机器学习技术

我们可以看到,尽管我们的模型输出在上图中看起来相似,但它们的准确度确实有所不同。下面是可以帮助我们看到差异的视觉效果。

5种用于预测销售的机器学习技术

比较模型性能

结论

相关推荐