Python模型診斷

2022-01-05 在成長的風一

儘管眼下十分艱難、可日後這段經歷說不定就會開花結果.

「碎碎念念」:大家好、我是風一;數據建模時、依據不同的場景、數據結構等等;往往會需要構建不同的數據模型、因此,就需要做模型對比,而比較模型時,評估性能是最重要的一環。在挑選最佳模型時, ANOVA(線性模型)、偏差觀察法(GLM) 和 交叉驗證法都是測量模型誤差和衡量模型性能的常用方法、下面開始模型診斷的學習。

一、簡介創建模型是持續性活動。當向模型中添加或刪除變量時,需要設法比較模型,並需要統一的方法來衡量模型的性能。二、殘差(單個模型)模型的殘差指實際觀測值與模型估計值之差。
import pandas as pd
housing = pd.read_csv("housing_renamed.csv")

housing.head()


neighborhoodtypeunitsyear_builtsq_ftincomeincome_per_sq_ftexpenseexpense_per_sq_ftnet_incomevaluevalue_per_sq_ftboro0FINANCIALR9-CONDOMINIUM421920.036500133261536.513420059.379906107300000200.00Manhattan1FINANCIALR4-CONDOMINIUM781985.0126420663325752.47176229513.94487096230690000242.76Manhattan2FINANCIALRR-CONDOMINIUM500NaN5541741731000031.2435430006.391376700090970000164.15Manhattan3FINANCIALR4-CONDOMINIUM2821930.02490761177631347.28278467011.18899164367556006271.23Manhattan4TRIBECAR4-CONDOMINIUM2391985.02194951000458245.58278319712.68722138554320996247.48Manhattan首先擬合一個多元線性回歸模型(含三個協變量、也就是自變量)
import statsmodels
import statsmodels.api as sm
import statsmodels.formula.api as smf

# 因變量在 ~ 左邊、 自變量在 ~ 右邊
house1 = smf.glm('value_per_sq_ft ~ units + sq_ft + boro',
                 data = housing).fit()

house1.summary()

Generalized Linear Model Regression ResultsDep. Variable:value_per_sq_ftNo. Observations:2626Model:GLMDf Residuals:2619Model Family:GaussianDf Model:6Link Function:identityScale:1879.5Method:IRLSLog-Likelihood:-13621.Date:Sun, 18 Jul 2021Deviance:4.9224e+06Time:06:19:39Pearson chi2:4.92e+06No. Iterations:3

Covariance Type:nonrobust


coefstd errzP>|z|[0.0250.975]Intercept43.29095.3308.1220.00032.84553.737boro[T.Brooklyn]34.56215.5356.2440.00023.71445.411boro[T.Manhattan]130.99245.38524.3270.000120.439141.546boro[T.Queens]32.99375.6635.8270.00021.89544.092boro[T.Staten Island]-3.63039.993-0.3630.716-23.21615.956units-0.18810.022-8.5110.000-0.231-0.145sq_ft0.00022.09e-0510.0790.0000.0000.000繪製模型的殘差圖
import seaborn as sns
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
# 繪製數據和線性回歸模型擬合 (官方文檔:https://www.cntofu.com/book/172/docs/28.md)
ax = sns.regplot(x = house1.fittedvalues,  # 擬合值
                 y = house1.resid_deviance, # 殘留偏差
                 fit_reg = False) # 如果為 True,則估計並繪製與 x 和 y 變量相關的回歸模型

plt.show()

該殘差圖效果不佳,因為其中包含了明顯的群集和組。下面通過 boro 變量為圖著色,以不同顏色表示紐約各個區
res_df = pd.DataFrame({
    'fittedvalues': house1.fittedvalues,
    'resid_deviance': house1.resid_deviance,
    'boro': housing['boro']
})

# 在FacetGrid對象上繪製數據和回歸模型(官方文檔:https://www.bookstack.cn/read/seaborn-0.9/docs-27.md)
fig = sns.lmplot(x = 'fittedvalues', y = 'resid_deviance',
                 data = res_df, hue = 'boro', # hue: 定義數據子集的變量,將在網格中的不同構面上繪製
                 fit_reg = False)

plt.show()

Q-Q 圖Q-Q 圖用於判斷數據是否符合某個參考分布。許多模型都是假設數據是正態分布的,因此 Q-Q 圖常用於檢驗數據是否來自正態分布
from scipy import stats

resid = house1.resid_deviance.copy()
resid_std = stats.zscore(resid) # 計算樣本中每個值的 z 分數,相對於樣本平均值和標準偏差

fig = statsmodels.graphics.gofplots.qqplot(resid, line = 'r')
plt.show()

繪製殘存直方圖,觀察數據是否呈正態分布
# fig, ax = plt.subplots()
ax = sns.displot(resid_std)

plt.show()


三、比較多個模型前面介紹了如何評估單個模型,有時需要比較多個模型,以便從中選出 "最佳" 模型。3.1.比較線性模型有些模型使用 "+" 運算符向模型中添加協變量,而有些模型則使用 "" 運算符 進行添加。當在模型中指定交互時應使用 "" 操作符。這意味著交互變量的行為不是彼此獨立的,它們的值相互影響,而不是簡單地相加。
# 擬合五個模型
f1 = 'value_per_sq_ft ~ units + sq_ft + boro'
f2 = 'value_per_sq_ft ~ units * sq_ft + boro'
f3 = 'value_per_sq_ft ~ units + sq_ft * boro + type'
f4 = 'value_per_sq_ft ~ units + sq_ft * boro + sq_ft * type'
f5 = 'value_per_sq_ft ~ boro + type'

house1 = smf.ols(f1, data = housing).fit()
house2 = smf.ols(f2, data = housing).fit()
house3 = smf.ols(f3, data = housing).fit()
house4 = smf.ols(f4, data = housing).fit()
house5 = smf.ols(f5, data = housing).fit()

針對所有模型、獲取所有係數和相關模型
house1.params

Intercept                 43.290863
boro[T.Brooklyn] 34.562150
boro[T.Manhattan] 130.992363
boro[T.Queens] 32.993674
boro[T.Staten Island] -3.630251
units -0.188115
sq_ft 0.000210
dtype: float64

mod_results = pd.concat([house1.params, house2.params, house3.params, house4.params, house5.params],
axis = 1).rename(columns = lambda x: 'house' + str(x + 1)).reset_index().rename(columns = {'index': 'param'})

mod_results.head(5)


paramhouse1house2house3house4house50Intercept43.29086344.45183840.23269242.92515838.3558791boro[T.Brooklyn]34.56215032.31498728.43926927.59763928.2309042boro[T.Manhattan]130.992363127.098918115.711927114.434920126.8014463boro[T.Queens]32.99367429.79931828.55323327.06885225.1621084boro[T.Staten Island]-3.630251-7.542656-15.640961-15.941330-16.950990
'''
'寬數據'轉換為 '長數據'
melt函數有如下幾個參數:
id_vars: 該參數是一個容器(列表、元組或ndarray),所表示的變量會保持原樣。
value_vars: 指定想"融合"(或轉換為行)的列。它默認會"融合"未在 id_vars 參數指定的所有列。
var_name: 該字符串用於指定 value_vars 融合後的新列名。默認為 variable。
value_name: 該字符串為新列名,代表 var_name 的值。默認為 value。
'''
mod_results = mod_results.melt(
    id_vars = 'param',
    var_name = 'model'
)

mod_results.head()


parammodelvalue0Intercepthouse143.2908631boro[T.Brooklyn]house134.5621502boro[T.Manhattan]house1130.9923633boro[T.Queens]house132.9936744boro[T.Staten Island]house1-3.630251

係數圖形化、直觀展現模型是如何評估彼此相關參數的
fig, ax = plt.subplots()

ax = sns.pointplot(
    x = 'value', y = 'param', hue = 'model',
    data = mod_results,
    dodge = True, join = False
)

plt.tight_layout()
plt.show()

這樣就得到了線性模型。下面可以使用方差分析(ANOVA)方法來比較它們。方差分析會給出殘差平方和(RSS), 可以通過它來評估模型的性能(殘差平方和越小,模型的擬合效果越好)。
方差分析(Analysis of Variance,簡稱ANOVA),又稱「變異數分析」,為數據分析中常見的統計模型,主要為探討連續型(Continuous)因變量(Dependent variable)與類別型自變量(Independent variable)的關係。當自變量的因子等於或超過三個類別時,檢驗各類別平均值是否相等,採用方差分析。
model_names = ['house1', 'house2', 'house3', 'house4', 'house5']
house_anova = statsmodels.stats.anova.anova_lm(house1, house2, house3, house4, house5)
house_anova.index = model_names

house_anova.reset_index()


indexdf_residssrdf_diffss_diffFPr(>F)0house12619.04.922389e+060.0NaNNaNNaN1house22618.04.884872e+061.037517.43760520.0390497.912333e-062house32612.04.619926e+066.0264945.53999423.5857282.754431e-273house42609.04.576671e+063.043255.4411927.7012894.025581e-054house52618.04.901463e+06-9.0-324791.84790719.275539NaN評估模型的另一種方法是使用赤池信息量準則(AIC) 和 貝葉斯信息準則 (BIC)。這些方法均引入了與模型參數個數相關的懲罰項。因此,應儘量在模型的性能和簡潔性之間做好平衡(簡單優於複雜)。3.2.比較 GLM可以採用同樣的方法評估和診斷GLM。不過,方差分析只評估模型的偏差。
def anova_deviance_table(*models):
    return pd.DataFrame({
        'df_residuals': [i.df_resid for i in models],
        'resid_stddev': [i.deviance for i in models],
        'df': [i.df_model for i in models],
        'deviance': [i.deviance for i in models]
    })

f1 = 'value_per_sq_ft ~ units + sq_ft + boro'
f2 = 'value_per_sq_ft ~ units * sq_ft + boro'
f3 = 'value_per_sq_ft ~ units + sq_ft * boro + type'
f4 = 'value_per_sq_ft ~ units + sq_ft * boro + sq_ft * type'
f5 = 'value_per_sq_ft ~ boro + type'

glm1 = smf.glm(f1, data = housing).fit()
glm2 = smf.glm(f2, data = housing).fit()
glm3 = smf.glm(f3, data = housing).fit()
glm4 = smf.glm(f4, data = housing).fit()
glm5 = smf.glm(f5, data = housing).fit()

glm_anova = anova_deviance_table(glm1, glm2, glm3, glm4, glm5)

glm_anova


df_residualsresid_stddevdfdeviance026194.922389e+0664.922389e+06126184.884872e+0674.884872e+06226124.619926e+06134.619926e+06326094.576671e+06164.576671e+06426184.901463e+0674.901463e+06四、k 折交叉驗證交叉驗證是另外一種模型比較方法。它可以解釋模型在新數據上的表現。這種方法會把數據分成 k 個部分,把其中一個部分用作測試集,把其餘部分用作訓練集來擬合模型(往往是測 2 訓 8)。模型擬合好之後,使用測試集進行測試,並計算誤差。不斷重複這個過程, 直到 k 個部分都測試過。模型的最終誤差是所有模型的平均值。進行交叉驗證有多種方法。剛才介紹的方法稱為 "k 折交叉驗證"。而 "留一交叉驗證"方法每次只留下一個樣本用作測試集,其他樣本都用作訓練集。
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

housing.columns

Index(['neighborhood', 'type', 'units', 'year_built', 'sq_ft', 'income',
'income_per_sq_ft', 'expense', 'expense_per_sq_ft', 'net_income',
'value', 'value_per_sq_ft', 'boro'],
dtype='object')

# 獲取訓練數據和測試數據
X_train, X_test, y_train, y_test = train_test_split(
    pd.get_dummies(housing[['units', 'sq_ft', 'boro']], drop_first = True),  #  刪除 k 個分類級別中的 k-1 個虛擬變量第一級
                   housing['value_per_sq_ft'],
                   test_size = 0.20,
                   random_state = 42
)

lr = LinearRegression().fit(X_train, y_train)
# 算出一個分數,衡量模型在測試數據上的表現
lr.score(X_test, y_test)

0.6137125285030869

由於 sklearn 高度依賴於 NumPy ndarray,所以 patsy 庫允許指定一個公式,比如 statsmodels 中的公式 API, 並且會返回合適的 NumPy 數組,以便在 sklearn 中使用。
from patsy import dmatrices

y, X = dmatrices('value_per_sq_ft ~ units + sq_ft + boro', housing, return_type = "dataframe")

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size = 0.20, random_state = 42
)

lr = LinearRegression().fit(X_train, y_train)
lr.score(X_test, y_test)

0.613712528503469

為了執行 k 折交叉驗證,需要先從 sklearn 庫導入該函數
from sklearn.model_selection import KFold, cross_val_score

# 重新獲取住房數據集
housing = pd.read_csv("housing_renamed.csv")

依據數據的行數,指定需要多少折;如果數據中包含的觀測值不太多,可以選擇一個較小的 k (例如 2)。k 值通常介於 5 到 10 之間。但請注意, k 值越大,所需要的計算時間就越長,需根據實際情況選擇合適的 k。
kf = KFold(n_splits = 5)

y, X = dmatrices('value_per_sq_ft ~ units + sq_ft + boro', housing)

# 每一折上訓練並測試模型
coefs = []
scores = []

for train, test in kf.split(X):
    X_train, X_test = X[train], X[test]
    y_train, y_test = y[train],y[test]
    lr = LinearRegression().fit(X_train, y_train)
    coefs.append(pd.DataFrame(lr.coef_))
    scores.append(lr.score(X_test, y_test))

coefs_df = pd.concat(coefs)
coefs_df.columns = X.design_info.column_names
coefs_df


Interceptboro[T.Brooklyn]boro[T.Manhattan]boro[T.Queens]boro[T.Staten Island]unitssq_ft00.033.369037129.90401132.103100-4.381085-0.2058900.00022000.032.889925116.95738531.295956-4.919232-0.1461800.00015500.030.975560141.85932732.043449-4.379916-0.1796710.00019400.041.449196130.77901333.050968-3.430209-0.2079040.00023200.0-38.51191556.069855-17.5579390.000000-0.1458290.000202
# 使用 apply 和 np.mean 函數查看所有折的平均係數
import numpy as np
coefs_df.apply(np.mean)

Intercept                  0.000000
boro[T.Brooklyn] 20.034361
boro[T.Manhattan] 115.113918
boro[T.Queens] 22.187107
boro[T.Staten Island] -3.422088
units -0.177095
sq_ft 0.000201
dtype: float64

查看每個模型的分數。每個模型都有默認的計分方法。例如 LinearRegression 使用 R^2(決定係數)回歸評分函數。
scores

[0.027314162909376938,
-0.553836221218619,
-0.15636371688031647,
-0.3234202061860394,
-1.6929655586236945]

# 使用 cross_val_scores(交叉驗證分數) 計算分數
model = LinearRegression()
scores = cross_val_score(model, X, y, cv = 5)
scores

array([ 0.02731416, -0.55383622, -0.15636372, -0.32342021, -1.69296556])

    綜上可見、模型4:模型4:f4 = 'value_per_sq_ft ~ units + sq_ft * boro + sq_ft * type' 性能比較好。

特此申明:以上文章來源於書籍《Python 數據分析活用 Pandas 庫》的閱讀理解以及練習筆記。

往期文章:

Python數據建模:簡單線性回歸

Python數據建模:廣義線性模型

相關焦點

  • python金融風控評分卡模型和數據分析
    (原創課程,版權所有,項目合作QQ:231469242,微信公眾號:pythonEducation) 課程介紹python金融風控評分卡模型和數據分析微專業課包含《python信用評分卡建模(附代碼)》,《python風控建模實戰lendingClub》,《金融現金貸用戶數據分析和畫像》三套課程系列
  • MetDig 用Python打造天氣診斷分析利器
    宮宇所在的天氣學診斷分析技術研發團隊看到了一個業務痛點——以前,每次重要天氣過程過後,預報員想要復盤分析研究時,就會各自去編寫代碼、搜集數據,這種分散勞動很大程度上造成了重複,浪費了寶貴的時間和精力。解決這一痛點成為他們確立的第一個目標。  一年過去了,一個等待更多天氣預報員和氣象愛好者「檢驗」的通用型天氣學診斷分析工具包(MetDig)登陸GitHub,供用戶下載使用。
  • Python文本挖掘——LDA模型實現
    人類生成文檔是基於概率選取主題及其對應的詞彙的方式,即一篇文章的每個詞都是通過「以一定概率選擇了某個主題,並從這個主題中以一定概率選擇某個詞語」這樣一個過程得到。那麼LDA要做的就是通過文檔反推主題。文檔到主題服從多項式分布,主題到詞服從多項式分布。每一篇文檔代表了一些主題所構成的一個概率分布,而每一個主題又代表了很多單詞所構成的一個概率分布。
  • 大數據分析python自回歸模型
    因此,在大數據分析python自回歸模型中,我們將討論一個反映這種相關性的模型。–自回歸模型。 自回歸模型或簡稱為AR模型,僅依靠過去的時間值來預測當前值。這是一個線性模型,其中當前期間的值是過去結果的總和乘以數字因子。我們將其表示為AR(p),其中「 p」稱為模型的階數,表示我們要包括的滯後值的數量。
  • 第196講 Python——線性模型|邏輯回歸|算法
    們在講機器學習模型之前,首先要了解兩個最簡單的機器學習或統計學習模型,那就是線性模型和邏輯回歸
  • 手把手:用Python搭建機器學習模型預測黃金價格
    新年第一天,讓我們嘗試用python搭建一個機器學習線性回歸模型,預測金價!自古以來,黃金一直作為貨幣而存在,就是在今天,黃金也具有非常高的儲藏價值,那麼有沒有可能預測出黃金價格的變化趨勢呢?(詳見:http://www.etf.com/GLD)在python的開發環境下用機器學習預測黃金價格的步驟:導入Python庫並讀取黃金ETF 的數據
  • Python 線性分類模型簡介
    參數學習和線性分類的優點利用參數學習有兩個主要的優點,正如我上面詳述的方法:一旦我們訓練完了模型,就可以丟掉輸入數據而只保留權重矩陣W和偏置向量b。這大大減少了模型的大小,因為我們只需要存儲兩個向量集合(而非整個訓練集)。對新的測試數據分類很快。為了執行分類,我們要做的只是點乘W和xi,然後再加上偏置b。
  • Python模型完美切換SAS,還能這麼玩..
    但是,最近東哥逛技術論壇剛好發現了一個騷操作,藉助Python的三方庫m2cgen和Python腳本即可完成Python模型到SAS的轉換。m2cgen是什麼?m2cgen是一個Python的第三方庫,主要功能就是將Python訓練過的模型轉換為其它語言,比如 R 和 VBA。
  • 《Python語言數據分析》----8.2.4 向量模型_3)LDA模型
    ###############8.2.4  向量模型_3)LDA模型import nltk
  • Stacking 模型融合詳解(附python代碼)
    ,clf1,我們使用kfold交叉驗證,那麼可以得到k個clf1模型,模型的類型是一樣的,但是模型裡面學到的參數不一樣,因為他們的訓練集是不一樣的,對與每一折的訓練,我們還有一個驗證集啊,那麼我們用訓練得到的模型在驗證集合上做一次預測,你想,因為這個時候我們的驗證集是不是只有1分,也就是只有train_set_number/k個樣本(train_set_number表示訓練樣本的個數),但是這只是一折啊
  • python回歸分析總結--回歸模型及調優
    回歸分析及模型優化1、回歸分析概括目標值(因變量)是連續型數據,通過某種函數關係找到因變量和自變量之間的關係,進而預測目標。通過不斷擬合縮小預測值與真實值的差距:最終使得這個差距(誤差項)成為一組均值為0,方差為1的隨機數。
  • AI化身診斷胃癌小能手,模型敏感性高達近100%
    AI病理診斷模型根據論文,深度學習模型被應用於臨床之前,應該通過三項「考驗」。其次,AI系統應當能夠協助病理學家提升診斷準確性,同時不會拉低常規報告程序的效率。為了進一步提升病理學家對AI輔助系統的信任,人們應該對模型的預測結果進行研究,以確定模型的優缺點。
  • 使用單行代碼評估回歸模型的Python包
    對此的一個內聯嘗試是python包「 regressormetricgraphplot」的開發,該軟體包旨在幫助用戶使用單行代碼繪製評估指標圖,以針對不同的廣泛使用的回歸模型指標進行一目了然的比較。使用該實用程序包,還可以通過將其應用於日常的預測回歸問題,顯著降低從業人員以業餘方式評估不同機器學習算法的障礙。
  • 高斯混合模型(GMM):理念、數學、EM算法和python實現
    這就要用到高斯混合模型了!GMM假設生成數據的是一種混合的高斯分布。與將數據點硬分配到聚類的K-means方法(假設圍繞質心的數據呈圓形分布)相比,它使用了將數據點軟分配到聚類的方法(即概率性,因此更好)。
  • 基於財經新聞的LDA主題模型實現:Python
    LDA主題模型雖然有時候結果難以解釋,但由於其無監督屬性還是廣泛被用來初步窺看大規模語料(如財經新聞)的主題分布。
  • 如何應用漏鬥模型輔助數據診斷與決策?
    漏鬥模型基本上是做所有分析時都或多或少會用到的工具,本文結合一些簡化的虛擬案例,來跟大家說說如何利用漏鬥模型輔助數據診斷與決策?當然,這是一個很簡化的虛擬案例,但是我們仍然可以從中看出他們是如何應用數據發現和診斷問題的,在這裡面用到的很重要的一個工具就是「漏鬥模型」。漏鬥模型及常用應用模型所以,什麼是漏鬥模型?漏鬥模型,aka漏鬥分析、轉化率分析,基本上是做所有分析時都或多或少會用到的工具。
  • 論文中的統計報告建議:診斷試驗和臨床預測模型
    生存分析8. 貝葉斯統計方法9. 缺失數據10. 相關數據11. 協變量調整和傾向性評分12.選擇患者樣本以確定內部變異和外部變異,必須由樣本量計算來進行解釋和支持。應該描述正常值的取值範圍,以及異常值的水平。根據用於研究測量的數據類型,變異的測量可以選擇包括κ統計量,單因素方差分析的類內相關係數ICC,以及標準誤。Bland-Altman分析圖通常有助於顯示兩種方法或評級者之間的一致性。
  • 黃宏濤等:基於近似子圖的實時教學認知診斷模型設計與應用
    文章針對日常教學中的小規模實時認知診斷問題(魏雪峰等,2016),提出基於近似子圖的教學認知診斷模型,分析了模型特點及原理,並給出了應用實例及驗證結果。一、相關研究近年來,研究人員提出了多種教學診斷模型來支持個性化教學。Tsai提出兩層診斷測試模型(Tsai,2001)來評價學生對知識點的掌握情況。
  • R筆記:多重線性回歸(三)_模型評估與診斷
    ,需要我們做進一步的評估與診斷。(1)模型擬合優度評估在模型擬合完畢通過summary()函數可以獲得參數估計表,同時函數也給出了模型的決定係數、校正的決定係數。本例多重線性回歸模型的決定係數R^2=0.2352,即結局變量的總變異中可由回歸模型中解釋變量解釋的部分僅佔23.52%,參見《多重線性回歸(一):模型擬合》。
  • 10分鐘用python進行人工智慧建立預測模型
    這篇文章會用最容易的方式引導你更快地構建第一個預測模型。出乎意料的簡單!10分鐘用python進行人工智慧建立預測模型揭秘預測建模的過程我一直專注於在模型構建的初始階段投入質量時間,如假設生成/腦力激蕩會議/討論或理解領域。所有這些活動都幫助我解決問題,最終導致我設計出更強大的業務解決方案。有充分理由說明你應該事先花時間:1.