- 金融商業算法建模:基于Python和SAS
- 趙仁乾 田建中 葉本華 常國珍
- 2391字
- 2021-11-05 17:52:05
2.1.2 Python案例:線性回歸建模
本節就如何使用線性回歸模型預測客戶價值進行舉例。信用卡部門擁有的客戶個人信息和信用卡支出信息存放在creditcard_exp.csv表中,目前尚有一些客戶注冊后沒有開卡,部門業務人員希望能夠預測其開卡后的消費情況,同時用于推斷的樣本外數據存放在creditcard_exp_out_of_sample.csv中。數據集的字段如表2-1所示。
表2-1 信用卡客戶價值預測數據集字段說明

creditcard_exp.csv保存了上一期的數據,Acc、avg_exp、avg_exp_ln為觀察期內得到的結果,可以作為分析中的因變量,剩余字段為分析窗口(觀察期之前)的自變量取值。
creditcard_exp_out_of_sample.csv保存了本期分析窗口內的自變量,其因變量需要通過模型輸出。
本數據集可用于預測觀察期內用戶是否會開卡,并預測用戶開卡后的信用卡支出(客戶價值的體現)。
1.數據探索
引入常用的包,為了方便學習,后續根據需要逐步引入其他包:
import matplotlib.pyplot as plt %matplotlib inline import os import numpy as np import pandas as pd pd.set_option('display.max_columns', 8)
因為數據顯示的問題,使用pd.set_option限制Pandas顯示數據表的列數為8列,然后讀取用于訓練的數據和樣本外的待預測數據:
raw_data = pd.read_csv('creditcard_exp.csv', skipinitialspace=True) out_of_sample_data = pd.read_csv('creditcard_exp_out_of_sample.csv', skipinitial- space=True) raw_data.head()
使用Jupyter Notebook時,每個Cell的最后一行的對象會被自動打印出來,并根據對象類型在輸出結果上進行一些優化,而無須使用print語句進行打印。因此,上述代碼運行后會輸出一個可讀性較好的pandas.DataFrame對象,如圖2-5所示。

圖2-5 pandas.DataFrame對象
其中,Acc為0,表示用戶未開卡,所對應的avg_exp和avg_exp_ln(月均信用卡支出及其對數值)為空值NaN。對應的樣本外數據out_of_sample_data是當前的觀察期數據,缺少Acc和avg_exp等字段,是需要我們預測的。
在raw_data中刪除未開卡用戶,同時因為age2(age的平方)與age是接近完全線性相關的,所以刪除age2字段,然后對數據進行統計量的描述:
train = raw_data[raw_data['avg_exp'].notnull()].copy().iloc[:, 2:]\ .drop('age2',axis=1) oos_data = out_of_sample_data.copy()\ .drop('age2',axis=1) train.describe(include='all')
本數據集樣本容量為70,各變量的均值、中位數等統計量如圖2-6所示。

圖2-6 運行結果
幾個主要的連續變量的相關性計算如下:
train[['Income', 'avg_exp', 'Age', 'dist_home_val']].corr(method='pearson')
得到的pandas.DataFrame對象結果如圖2-7所示。

圖2-7 pandas.DataFrame對象
可以發現,avg_exp與Income的相關性較高。二者的散點圖如圖2-8所示,相關性計算代碼如下:
fig, ax = plt.subplots(figsize=(8, 6)) ax.set_ylabel(..., fontsize=15) ax.set_xlabel(..., fontsize=15) train.plot('Income', 'avg_exp', kind='scatter', ax=ax) plt.show()

圖2-8 散點圖
2.使用statsmodels建立簡單線性回歸模型
statsmodels是一個專業的用于統計分析的框架,包含豐富的統計建模和檢驗功能,使用它進行線性回歸建模十分方便。
import statsmodels.api as sm from statsmodels.formula.api import ols simple_linear_model = ols(formula='avg_exp ~ Income', data=train).fit() print(simple_linear_model.params)
輸出模型參數的估計值如下:
Intercept 258.049498 Income 97.728578 dtype: float64
ols用于進行最小二乘求解,其中傳入的formula參數是一個字符串,表示回歸方程,波浪線前面的部分是因變量,后面部分表示自變量。建立的模型使用fit函數即可自行訓練,訓練完成的對象包含的params屬性中保存了模型的參數估計。本例中,Income字段的系數為97.73,截距項為258.05,因此模型可表示為:

在建立多元線性回歸時,僅需要在formula當中指定多個自變量即可,各個自變量使用加號連接:
multiple_linear_model = ols( formula='avg_exp ~Income + dist_home_val + dist_avg_income', data=train).fit() print(multiple_linear_model.params)
輸出的模型參數如下:
Intercept 2.350664 Income -164.437844 dist_home_val 1.539601 dist_avg_income 260.752162 dtype: float64
該多元線性回歸方程為:
avg_exp = 2.35 – 164.44×Income + 1.54×dist_home_val + 260.75×dist_avg_income
statsmodels提供了豐富的可對模型進行檢驗的統計量,要輸出這些統計量和檢驗結果,僅需要調用模型的summary方法即可。以簡單線性回歸為例:
summary = simple_linear_model.summary()
3.summary
模型的summary對象包含兩個屬性:tables屬性包含模型統計檢驗結果,extra_txt屬性用于解釋說明。其中,tables屬性會給出一個列表,包括模型概況與檢驗、參數檢驗、其他檢驗,我們可以使用循環將這三個對象打印出來,在Jupyter Notebook中,僅需在Cell的最后一行將summary對象輸出,即能自動打印(就如上述代碼所示)。其輸出結果如下:


我們在后續章節會逐步介紹這些統計檢驗結果。
4.模型的解釋
線性回歸模型具有良好的可解釋性。對于簡單線性回歸來說,線性回歸模型可直觀地解釋為:當X增加1個單位時,因變量Y會增加
個單位。例如上述通過收入預測信用卡支出的案例中,我們可以認為當年收入增加1萬元時,信用卡月均支出增加97.73元。
多元線性回歸模型的解釋與此類似,可被解釋為:當控制其他自變量之后,選定的自變量變化會導致因變量產生固定比例的變化。例如上述多元線性回歸案例中,當控制地區房價與地區平均收入這兩個變量后,年收入每增加1萬元,信用卡月均支出反而下降164.44元。這個結論是否可靠呢?一方面需要通過業務經驗來判斷,另一方面需要檢驗模型本身。關于模型優化,我們會在后續章節中詳細說明。
另外,線性回歸模型可以有多種形式,即在線性方程中對Y或X做任何簡單的初等函數變換,我們僅需要將變換后的結果看作是一個新變量,最終形式仍然是線性回歸,例如:

這幾個方程對變量做了簡單的初等函數變換,但它們仍然屬于線性回歸,其業務解釋也與一般形式的模型類似。特別需要說明的是取對數后的方程,以因變量取對數為例,對于i和j兩條記錄,考慮到:

其中,可視作j相較于i增長的倍數,減1后相當于j相較于i增長的百分比。因此,我們可以認為當X增加1個單位
時,Y會增加一個固定的倍數或百分比(具體來說是
)。
類似地,對于X取對數的線性回歸,可解釋為:X增加固定的倍數或百分比,會導致Y增加固定的值;對于X和Y均取對數的線性回歸,可解釋為:當增加一個倍數或百分比,會導致增加一個固定的倍數和百分比,這在經濟學中被稱為Y相對X的彈性。
我們在案例中建立了信用卡支出的對數與收入的線性回歸模型,并求解其參數:
Print(ols('avg_exp_ln ~ Income', train).fit().params)
結果如下:
Intercept 6.181076 Income 0.086557 dtype: float64
這說明當收入增加1萬元時,信用卡支出會增長9.04%。
再建立一個信用卡支出的對數與收入的對數的線性回歸模型,并求解其參數:
train['Income_ln'] = np.log(train['Income']) #樣本外數據做同樣變換 oos_data['Income_ln'] = np.log(oos_data['Income']) print(ols('avg_exp_ln ~ Income_ln', train).fit().params)
結果如下:
Intercept 5.312341 Income_ln 0.780397 dtype: float64
這說明,當收入增加10%時,信用卡支出增加7.72%。顯然,這個解釋更符合業務直覺。(你能想象年入千萬的富豪,因為收入增加了1萬元,而導致信用卡支出增加97.73元,或者信用卡支出增加9.04%嗎?)
從上例可以看到,取對數后的線性回歸模型仍然具有良好的可解釋性,這也是統計學家們偏愛對數變換的原因之一。
5.模型預測
模型預測是指僅需要將X的值代入回歸方程即可獲取Y的預測值。需要注意的是,如果在建模時對做了函數變換,那么預測后需要對結果做逆變換,以獲取正確估計。仍然以最早建立的未做對數變換的模型為例:
print(simple_linear_model.predict(oos_data)[:5])
結果如下:
0 982.218260 1 749.624245 2 649.941095 3 631.372665 4 661.668525 dtype: float64
也可以在訓練集上進行預測,并觀察預測與真實值的殘差:
train_prediction = simple_linear_model.predict(train) train_resid = simple_linear_model.resid pd.DataFrame( [train_predict, train_resid], index=['Pred_avg_exp', 'resid'] ).T.head()
結果如下:
