第 9 章 類別資料下的panel data



本章是類別資料下的panel data,對於這個議題,筆者建議的作法是走多層次模型(multilevel model, MLM)的路,而不是panel glm。主要是因為pglm是計量經濟學的套件,因此注重的是係數估計和顯著性檢定,因此只有係數表,沒有提供預測。panel data的處理過程有很多參數須要還原才能計算期望值,如個別效果,這一個缺失會讓研究人員浪費太多時間在寫無意義的程式。本章最後一節會介紹這個問題,也會簡單展示MLM的作法。

9.1 類別資料基礎原理

本章用範例資料檔 vote.csv說明廣義線性模式(GLM: generalized linear models),這是2000位美國公民投票行為的資料。資料分析人員,想要知道哪些因素影響了投票行為。這個檔案說明如圖 9.1

vote.csv 資料格式

圖 9.1: vote.csv 資料格式


 vote =1,有去投票;=0沒有去投票
 race =種族別:white=白人;others=其他
 age=年齡煙
 educate=受教育年數
 income=年所得(萬美元)


稱為線性模式的被解釋變數(或Y),數據是連續資料,也就是實數:正、負和小數都可以。和線性模式不同,上面這筆數據的Y是{0, 1}兩個分類別,所以一般也稱為分類問題。這是研究決策科學常遇到的數據, {0, 1} 分別代表解釋變數的二元化行為。研究人員,就會想知道什麼因素決定了特定行為的發生。也因為{0, 1}區間的特性,期望值解讀為機率。


因此,在進入panel data之前,本節簡單解說廣義線性模型(GLM: generalized linear models) 的概念。廣義線性模式應用極多,依照被解釋變數的類別屬性,廣義線性模型可以分為4類:
  二元:{0,1},好比 {成功,失敗} 或 {選A,選B}
  計數:{50, 100, 199…..},好比在一定時間,餐廳有多少人在用餐
  多元:{1,2,3},好比{景氣衰退,景氣反轉,景氣擴張}
  有序多元:{1,2,3,4,5},好比{非常不滿意,不滿意,普通,滿意,非常滿意}

二元{0, 1}一般也稱為選擇問題,這是研究決策科學常遇到的數據,{0, 1} 分別代表決策者二分的行為。研究人員會想知道什麼因素決定了特定選擇行為或狀態的發生,例如,有沒有去投票,減重的成功或失敗。也因為{0, 1}區間的特性,期望值解讀為機率。

和線性模式不同,稱為線性模式的被解釋變數(或Y),數據是連續資料,也就是實數:正、負和小數都可以。線性模式不適宜配適Y是 {0, 1}的資料,因為線性配適線是一條直線, 直線的延長會超過{0,1}這個界,如圖9.2:向右方看,要預測高所得的行為機率,就會大於1;往左方看,低所得的機率就會是負的。雖然,線性機率模型預測大體上還可以,但是對於雙尾極端狀況,就會出現預測問題。

線性機率模型

圖 9.2: 線性機率模型


鑑於這種問題,用機率分佈的累積機率密度去配適這樣的資料,應該比較好。也就是圖 9.3

機率分佈的累積機率密度

圖 9.3: 機率分佈的累積機率密度


Probit 迴歸利用標準常態分佈的累積機率密度函數 \(\Phi(z)\),估計Y=1 這個事件:也就是,\(z = b_0 + b_1X\)。如下,
\[ Prob(Y=1|X) = \Phi(b_0 + b_1X) \]
\(\Phi\)是常態分佈的累積密度函數,\(z = b_0 + b_1X\) 稱為 Probit模型的 「z-值」或 「z-指標」。
範例:假設\(b_0 = -2\), \(b_1= 3\), \(X = 0.4\), 所以

\[ Prob(Y=1|X=0.4) = \Phi(-2 + 3 \times 0.4)= \Phi(-0.8) \]


Prob(Y = 1|X=0.4) = 標準常態分佈圖,z = -0.8左邊的面積。如圖 9.4,查表就可以知道機率是多少。當然電腦直接就會幫我們計算。

標準常態分佈機率

圖 9.4: 標準常態分佈機率


對於二元選擇的Y,Pobit還有一個雙胞胎logit,兩者產生的期望機率大體上是一樣的。Logit函數不連結常態分佈,定義機率生成函數如下:

\[ \tag{9.1} Prob(Y=1|X) =F(b_0+b_1{X})=\frac{1}{1+e^{-(b_0+b_1{X})}} \]


因為Probit 配適一個機率密度函數,在以前計算很慢,所以開發了logit函數。這個時代計算機的演算能力,都沒問題。我們其實不必太嚴格區分兩者。如這裡所介紹的,GLM的估計原理,須要一個連結函數(linking function)來完成,把z和機率函數連結。要連結哪一個機率密度函數,就要看Y的型態是如何。當Y是測量程度,例如,{不滿意,普通,滿意,很滿意} 這樣的行為時,就不是二元選擇(Binary choice),而是多元排序(Ordered Choice),就要編成{0, 1, 2, 3} ,我們就須要用ordered probit/logit;如果Y是「計數」型,好比某時某地的旅遊人數,連結函數就是將這種「隨機變數的條件期望值」和「機率密度函數」連結的函數,一般「計數」型是布阿松函數,所以就是和布阿松函數連結。
因為機率函數是非線性,所以,這一部份也稱為非線性模型。然而,廣義線性的線性,指的是線性連結函數。綜合來說,GLM有三個重要特徵:殘差結構、線性關係、連接函數。

  首先,殘差結構,在線性模式往往用常態去處理。但是,這一章的資料則不是常態,被解釋變數的特徵,會出現高度的偏態,峰態,上下界被限制住一定的區間,以及期望值不可為負。所以,殘差結構往往用隨機變數的家族(family)一詞表示。例如,二項式、布阿松、GAMMA等等。

  其次,解釋變數和被解釋變數之間,是一個線性關係。

  最後,連結函數就是將線性關係產生Y的期望值,與真正的Y觀察值連結起來的函數。基本上,就是一個轉換。線性期望值可能是一個負的值,但是,真正的觀察值卻必須在0和1之間,因此,就需要再轉換一次,讓它更接近Y所描述的現象。這就是連結函數的功能。

式(9.1)的機率函數,一個測量方法是假設log-odds函數: \(log(\frac{p}{1-p})\) ,因此,機率的推導如下:

\[ log(\frac{p}{1-p})=b_0+b_1{X}\\ \frac{p}{1-p}=e^{b_0+b_1X}\\ \frac{1-p}{p}=\frac{1}{e^{b_0+b_1X}}\\ \frac{1}{p}-1=\frac{1}{e^{b_0+b_1X}}\\ \frac{1}{p}=1+\frac{1}{e^{b_0+b_1X}}\\ \frac{1}{p}=\frac{1+e^{b_0+b_1X}}{e^{b_0+b_1X}}\\ p=\frac{e^{b_0+b_1X}}{1+e^{b_0+b_1X}} \]


上式最後可以寫成式(9.1)

\[ \tag{9.2} p=\frac{e^{b_0+b_1X}}{1+e^{b_0+b_1X}}=\frac{1}{1+e^{-(b_0+b_1{X})}} \]


最後,我們必需知道式(9.1)是機率生成函數,不是迴歸方程式,log-odds不是資料。

接下來,我們實做

9.1.1 二元變數之Probit/Logit GLM


範例資料檔沿用 vote.csv。 我們先研究投票和所得與教育水準的關係。 也就說,我們配適GLM於以下三變數方程式
\[ vote=a+b_1{Age} +b_2{Income}+b_3{Education} \]
我們先繪製投票與否和所得的線性關係。圖 9.5 指出很明顯的線性問題,而且這筆資料的線性配適還蠻嚴重的。

投票行為與所得的線性機率模型

圖 9.5: 投票行為與所得的線性機率模型


R的GLM估計如下。

dat=read.csv("data/vote.csv")
dat$vote=as.factor(dat$vote)
output.logit=glm(vote ~., data=dat,family=binomial(link="logit"))
summary(output.logit)
## 
## Call:
## glm(formula = vote ~ ., family = binomial(link = "logit"), data = dat)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -3.034261   0.325959  -9.309  < 2e-16 ***
## racewhite    0.250798   0.146466   1.712   0.0868 .  
## age          0.028354   0.003461   8.193 2.54e-16 ***
## educate      0.175634   0.020333   8.638  < 2e-16 ***
## income       0.177112   0.027158   6.521 6.96e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 2266.7  on 1999  degrees of freedom
## Residual deviance: 2024.0  on 1995  degrees of freedom
## AIC: 2034
## 
## Number of Fisher Scoring iterations: 5

以上,依照三個編號解說:

 A. Call 就是執行估計的函數,R的函數是glm(),這樣就一目了然。
 B. 係數估計值, 這個結果,只能由符號正負作機率增減的解讀,不能解釋成機率增減幅度。例如,三個參數的p-value都很顯著,所以,以Income為例,我們可以從正相關解釋:所得越高,投票的機率越高。不能 解釋成:所得增加一單位,投票機率增加0.177。
 C. 配適檢定。線性模型的配適度,有一個\(R^2\);glm 的配適度使用McFadden   \(R^2\),定義如下:

McFadden \(R^2\) =1-(residual.deviance/null.deviance)

根據上面output下方兩個值,計算得:\(R^2\) = 0.1070993。

另外,估計結果也回傳一個AIC=2034,這個指標越小越好。例如,-200比-150好;但是AIC是比較模型用的,無法用在解讀模型對資料的解釋能力。

接下來,和lm的殘差診斷圖一樣,我們也檢視glm的殘差診斷,如下圖 9.6

glm的殘差診斷

圖 9.6: glm的殘差診斷


〔練習〕估計上述模型,選用Probit看看結果如何。
〔練習〕這筆資料有一個類別變數race:白人與非白人。請增加這個變數,看看種族類別是否與投票行為有關?


再來就是 over-dispersion 和參數變異數修正。理論上,glm 架構的殘差最適表現是卡方分佈。但是,實際上會出現較大的殘差變異,這就稱為over-dispersion。所以,是否須要修正,處理的方法就是先計算dispersion數值,就是殘差平方和除以自由度,也就是模型的變異數。如果dispersion= 1 ,就沒有over-dispersion,也沒有變異數修正問題。如果大於1,就要用這個數值去修正原來的估計結果。分步驟解釋如下:

 步驟1。計算dispersion 的經驗值。

估計物件名稱是output.logit,分子是sum(residuals(output.logit)^2),分母自由度是output.logit$df.res,dispersion參數計算公式如下

Disp=sum(residuals(output.logit)^2)/output.logit$df.residual


執行如下

Disp=sum(residuals(output.logit)^2)/output.logit$df.residual
Disp
## [1] 1.014527

1.014527這個數字很接近1,所以修正的效果應該不太大。

 步驟2。如果須要修正,計算完畢後,我們執行下列指令修正標準誤。

summary(output.logit, dispersion=Disp)



如下:

summary(output.logit, dispersion=Disp)
## 
## Call:
## glm(formula = vote ~ ., family = binomial(link = "logit"), data = dat)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -3.034261   0.328318  -9.242  < 2e-16 ***
## racewhite    0.250798   0.147526   1.700   0.0891 .  
## age          0.028354   0.003486   8.135 4.13e-16 ***
## educate      0.175634   0.020480   8.576  < 2e-16 ***
## income       0.177112   0.027355   6.475 9.50e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1.014527)
## 
##     Null deviance: 2266.7  on 1999  degrees of freedom
## Residual deviance: 2024.0  on 1995  degrees of freedom
## AIC: 2034
## 
## Number of Fisher Scoring iterations: 5

對於dispersion值是否須要修正,另外有卡方檢定 dispersion=1.014527,是否顯著大於1。如下:

pchisq(Disp*output.logit$df.residual, 
               output.logit$df.residual, lower = FALSE) 
## [1] 0.3201975

這個p-value 接近 0.5,接受無over-dispersion的虛無假設。

另外,套件msme內的函數P__disp(),提供依照pearson方法,如下

msme::P__disp(output.logit)
## pearson.chi2   dispersion 
##  2001.013995     1.003015


pearson.chi2就是依pearson方法計算的殘差平方和,等同以下:

sum(residuals(output.logit, type = “pearson”)^2)


sum(residuals(output.logit, type = "pearson")^2)
## [1] 2001.014
sum(residuals(output.logit, type = "pearson")^2)/output.logit$df.residual
## [1] 1.003015


所以,也不須要使用msme這個套件。最後,顯著性檢定的p-value計算如下:

pchisq(sum(residuals(output.logit, type = "pearson")^2),
       output.logit$df.residual, lower = FALSE)
## [1] 0.4579241


從結果看,兩個p-value 的數值略有差距,結果不變。其實,這個檢定對Disp的數字是很敏感的。讀者可以把Disp手動改成1.2,看看pchisq()計算的p-value變成多少。

基本上,如果我們模型的解釋變數都是正確的,但是出現over-dispersion狀況時,可能的原因是數值刻度沒有適當轉換,或者函數的結構形式不正確。

二元glm的期望值就是機率,R 的計算方法是式(9.2)的logit prob function,我們看R內部計算的預測機率,如下:

prob.logit.pred=predict(output.logit,type="response")

head(prob.logit.pred)
##         1         2         3         4         5         6 
## 0.8775302 0.6786731 0.5290410 0.5755400 0.6286173 0.8384276

如果把資料集分成樣本內和樣本外,預測時可以用newdata指定資料集,就可以參數套用的指定的新資料,例如:

predict(obj, newdata=dat2,type=“response”)



這個機率可以用來產生二元預測,例如,以0.5為分界點,大於等於0.5的,預測為1,其他為0。

head(ifelse(prob.logit.pred>=0.5,1,0))
## 1 2 3 4 5 6 
## 1 1 1 1 1 1


這個預測結果,可以和真實資料製作混淆矩陣來評估預測能力,不在此說。

最後,我們用人工方法,依照式(9.2)整理資料,計算預測機率

dat.tmp=dat
dat.tmp$race=as.integer(as.factor(dat$race))-1
dat.tmp=cbind(1,dat.tmp[,-1])
colnames(dat.tmp)=names(output.logit$coef)
score.logit=as.matrix(dat.tmp) %*% as.matrix(output.logit$coef)
prob.logit.formula=c(exp(score.logit)/(1+exp(score.logit))) #用式(9.2)計算機率
head(prob.logit.formula)
## [1] 0.8775302 0.6786731 0.5290410 0.5755400 0.6286173 0.8384276

可以用以下方式檢測,可知兩個方法完全相等。

identical(as.numeric(prob.logit.formula),as.numeric(prob.logit.pred))
## [1] TRUE

最後,如果使用”probit”,如下,就是配適常態機率密度,而不是(9.2),我們可以用類似方法檢驗。

output.probit=glm(vote ~., data=dat,family=binomial(link="probit"))
prob.probit.pred=predict(output.probit,type="response")
head(prob.probit.pred)
##         1         2         3         4         5         6 
## 0.8793837 0.6784155 0.5430547 0.5757100 0.6301197 0.8380967
score.probit=as.matrix(dat.tmp) %*% as.matrix(output.probit$coef)
prob.probit.pnorm=pnorm(score.probit) #用常態分佈計算機率
head(prob.probit.pnorm)
##           [,1]
## [1,] 0.8793837
## [2,] 0.6784155
## [3,] 0.5430547
## [4,] 0.5757100
## [5,] 0.6301197
## [6,] 0.8380967

可以用以下方式檢測是否相等

identical(as.numeric(prob.probit.pnorm),as.numeric(prob.probit.pred))
## [1] TRUE

9.1.2 計數型變數之布阿松迴歸– Poisson GLM


什麼是布阿松迴歸?布阿松迴歸適合用於對結果為計數的事件或列聯表進行建模的統計方法。或者,更具體地說,計數數據:具有非負整數值的離散數據,用於計數某些內容,例如在給定時間範圍內事件發生的次數或在雜貨店排隊的人數。計數數據也可以表示為速率數據,因為事件在時間範圍內發生的次數可以表示為原始計數(即“一天中,步行30公里”)或平均速率(“我們以平均每小時1.25公里的速度步行”)。計數型的被解釋變數在現實生活中還不少,例如,特定時間的:政治倒閣次數,車禍次數,排隊結帳的人數,以及社群媒體按讚人數。

布阿松迴歸允許我們確定哪些解釋變數X對給定的被解釋變數Y(計數或速率)有影響,從而幫助我們分析計數數據和速率數據。例如,銀行可以應用布阿松迴歸來更好地瞭解和預測排隊等待服務的人數。

如前一節的二元分佈須要logistic或常態分佈的機率函數為MLE的基礎,布阿松迴歸須要布阿松分佈。布阿松分佈是一種以法國數學家Siméon Denis Poisson命名的統計理論。它對事件或事件y 在特定時間範圍內發生的概率進行建模,假設 y 的發生不受 y 的先前出現時間的影響。機率密度函數定義如下:

\[ p(y)=\frac{{\lambda}^{y}{e^{-{\lambda}}}}{y!} \]

在這裡,\(\lambda\) 就是期望值,也就是說:\(\lambda=\mu\),也就是是每單位暴露事件可能發生的平均次數。暴露可以是時間、空間、人口規模、距離或面積,但通常是時間,用 t 表示。如果未給出曝光值,則假定它等於 1。布阿松隨機變數的一個性質是期望值和變異數都是\(\lambda\),我們可以通過為不同的 \(\lambda\) 值,創建機率分布圖來視覺化這一個性質,有興趣的讀者,可以透過機率教科書,試著做做看。

布阿松迴歸模型是一種廣義線性模型 (GLM),用於對計數數據和列聯表進行建模。輸出 Y(計數)是遵循布阿松分佈的值。它假設期望值(平均值)的對數,可以通過一些未知參數建模為線性形式。

注意:在統計學中,列聯表(示例)是取決於多個變數的頻率矩陣。

為了將非線性關係轉換為線性形式,使用了連結函數,該函數是泊松回歸的對數。因此,布阿松迴歸模型也稱為對數線性(log-linear)模型。布阿松迴歸模型的一般數學形式為:

\[ log(y)=a+b_{1}x_{1}+...+b_{k}x_{k}+\epsilon \] 故,

\[ y=e^{a+b_{1}x_{1}+...+b_{k}x_{k}+\epsilon} \] 用矩陣表示條件期望值,\(E[y|X]=e^{\beta X}\),因為分佈函數的性質:\(E[y|X]=\lambda\),我們可以將之代入機率密度函數,如下:

\[ p(y|x;\beta)=\frac{{(E[y|X])}^{y}{e^{-{(E[y|X])}}}}{y!}=\frac{e^{y{\beta}X}{e^{-{(\beta}X)}}}{y!} \]

承上,就可以用MLE求解概似函數。最大概似函數估計\(\beta\)的核心想法是,去找到能使得基於當前觀測值的聯合概率儘可能達到最大的\(\beta\)。(可理解為:變量的取值當前觀測值,與取值為其他任何數值相比,是發生機率最高的事件)。既然目標是尋找到最優的\(\beta\),可以先將上式的等號左邊簡單表達為關於\(\beta\)的表達式。這些技術細節,有興趣的讀者可以去看相關書籍,本書大致簡介到這邊。接下來實做:

本節的範例檔用 countStrikes.csv,這筆資料欲研究罷工次數的影響因素。這筆資料表的形式如下。

dat.pois=read.csv("data/countStrikes.csv")
head(dat.pois)
##   NUMB_strike FEB    IP
## 1           5   0 1.517
## 2           4   1 0.997
## 3           6   0 0.117
## 4          16   0 0.473
## 5           5   0 1.277
## 6           8   0 1.138

變數解釋如下:

 NUMB_strike: 罷工次數
 FEB: =1, 發生在二月;0=其他月份
 IP:以工業生產指數變動率計算的經濟成長,%

我們的被解釋變數是Numb_strike,估計這種隨機變數,機率分佈模型是布阿松。連結函數只是轉換成機率時用的函數,如果用線性,數值結果會有些許差異,但是增減方向不變。說明範例如下:
發生罷工次數的時間,二月比其他月份的平均次數要少;經濟成長率較高,平均罷工次數也較高。

output.pois=glm(NUMB_strike ~., data=dat.pois,family=poisson(link="log"))
summary(output.pois)
## 
## Call:
## glm(formula = NUMB_strike ~ ., family = poisson(link = "log"), 
##     data = dat.pois)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  1.725630   0.043656  39.528  < 2e-16 ***
## FEB         -0.377407   0.174520  -2.163 0.030577 *  
## IP           0.027753   0.008191   3.388 0.000703 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for poisson family taken to be 1)
## 
##     Null deviance: 241.71  on 102  degrees of freedom
## Residual deviance: 224.86  on 100  degrees of freedom
## AIC: 575.09
## 
## Number of Fisher Scoring iterations: 5

接下來,和二元glm一樣,我們也檢視glm-poisson的殘差診斷,如下圖 9.7

glm-poisson的殘差診斷

圖 9.7: glm-poisson的殘差診斷

剩下的實做問題,和二元差不多,我們設計成練習問題,讓有趣的讀者練習。

〔練習〕用fitted() 比較三個連結函數預測的平均罷工次數,差異如何。
〔練習〕請計算Over-dispersion,並修正原估計結果。
〔練習〕解讀圖 9.7的意義

9.1.3 多元選擇 GLM— Multinomial Probit/Logit


二元選擇的問題,行為者的選擇是二選一。一個更普遍的情況是行為者是從多個選項中選擇一個,如下健康保險資料mlogit.csv的欄位變數。

dat.mlogit=read.csv("data/mlogit.csv")
head(dat.mlogit)
##   patient_ID    insure age    sex white ppd0 ppd1 ppd2 ppd site noinsur0
## 1       3292 Indemnity  74 Female   Yes    0    0    0   0    2        0
## 2       3685   Prepaid  28 Female   Yes    1    1    1   1    2       NA
## 3       5097 Indemnity  38 Female   Yes    0    0    0   0    1        0
## 4       6369   Prepaid  24 Female    No    1    1    1   1    3       NA
## 5       9194   Prepaid  30 Female   Yes    1    1    1   1    2       NA
## 6      11492   Prepaid  39 Female   Yes    1    1    1   1    2       NA
##   noinsur1 noinsur2
## 1        0        0
## 2       NA       NA
## 3        0        0
## 4       NA       NA
## 5       NA       NA
## 6       NA       NA


Insure 是我們的被解釋變數,有三項:
  indemnity: 保險損害賠償。
  prepaid: 預付計畫,如HMO(health maintenance organization 維護健康組織)的計畫。預付一筆費用,就可以無限使用。
  Uninsure: 沒有保險
其他欄位代表:
 Sex: 性別
 White: 是否為白人
 ppd0: prepaid at baseline
 ppd1: prepaid at year 1
 ppd2: prepaid at year 2

這筆資料用來研究病人對於方案的選擇和人口因素的關連。類似資料研究的問題,教育方面有大學生畢業後的選擇:碩士、就業、留學。載入資料後,以insure為被解釋變數,解釋變數配適年齡(age)、性別(sex)和種族(White)三個變數。

output.mlogit=nnet::multinom(insure~age+sex+white, data=dat.mlogit,maxit=1000,trace=FALSE)
summary(output.mlogit)
## Call:
## nnet::multinom(formula = insure ~ age + sex + white, data = dat.mlogit, 
##     maxit = 1000, trace = FALSE)
## 
## Coefficients:
##          (Intercept)          age   sexMale   whiteYes
## Prepaid    0.8874833 -0.011179932 0.5745660 -0.7312471
## Uninsure  -1.3739253 -0.005927721 0.5109524 -0.4335456
## 
## Std. Errors:
##          (Intercept)         age   sexMale  whiteYes
## Prepaid    0.3400588 0.006101655 0.2005740 0.2189813
## Uninsure   0.6372029 0.011433969 0.3640691 0.4106268
## 
## Residual Deviance: 1091.184 
## AIC: 1107.184

估計結果中會將被解釋變數的3個類別視為base,R裡面是自動依字母排序,排在前面的就是indemnity。base的項目,就是和其他兩個比較的。所以,這結果的解讀,必須小心。下半部估計結果,R對結果的輸出,是依照估計項目去分2部份:Coefficients(係數)和Std.

以係數為例的解讀如下:

 第1. 截距代表了三個變數的觀察值是0時的機率,可執行兩行語法計算

    cc=c(0, 0.8874, -1.3739)
    exp(cc)/sum(exp(cc))

cc=c(0, 0.8874, -1.3739)
exp(cc)/sum(exp(cc))
## [1] 0.27159710 0.65965682 0.06874608


三者機率差異很大,意思是說:當三個變數的觀察值是0時(女性且非白人),個人選擇indemnity的機率是0.2715971,選擇prepaid的機率是0.65965682,選擇不保險的機率是0.06874608。

 第2. 斜率代表了log-odds機率,測量了1個人從選擇baseline(=indemnity),過渡到選擇prepaid或選擇uninsured的機率。例如,age斜率是-0.011和-0.0059

   cc=c(0, -0.0112, -0.0059)
   exp(cc)/sum(exp(cc))

cc2=c(0, -0.0112, -0.0059)
exp(cc2)/sum(exp(cc2))
## [1] 0.3352353 0.3315016 0.3332632


三者機率類似,意思是說:年齡增加1歲,從「選擇baseline」(=indemnity)」,過渡到「選擇prepaid」的機率是0.3315016,過渡到「選擇 uninsured」的機率是0.3332632。

其餘關於over-dispersion計算與問題,皆與上同。有趣讀者可以試試看。

9.2 Panel Data的類別資料– panel GLM

9.2.1 原理淺說

panel GLM 的理論問題說難也很難,說簡單也很簡單。基於 第二章起的panel data和前一節類別資料GLM的理解,panel GLM似乎也就沒那麼難。我想先淺談一些理論問題。

在線性模型時,固定效果的概念就是被解釋變數的de-mean,移除平均數。如果Y是連續的,這個LSDV的動作沒有問題,但是Y是二元類別數據時,這個動作就沒有意義了。何況,更多的二元資料是用文字表示的因子,例如,{成功,失敗}或{No, Yes},這樣,就不能用LSDV去計算固定效果,因此,基本的情況就是使用隨機效果或pooling方法。不少商業經濟計量軟體是採用pooling來處理二元panel data,例如,Eviews。

然後,理論上, Chamberlain (1980) 指出通過條件概似函數(conditional likelihood),搜索最小的充分統計量(sufficient statistic), Chamberlain (1980) 證明,對於個別效果,\(y_{it}\)的總和是一個最小的充分統計量。 因此,最大化條件概似函數, 下面的函數可以生成conditional logit的參數估計式,且避免了擾攘參數的問題:

\[ {{L}_{c}}=\prod\limits_{\text{i}=\text{1}}^{\text{N}}{\text{Prob}\left( {{\text{y}}_{\text{i1}}}\text{,}{{\text{y}}_{\text{i2}}}\text{,}\cdots {{\text{y}}_{\text{iT}}}|\sum\limits_{t=1}^{T}{{{y}_{it}}} \right)} \]


並且,根據充分統計的定義,在特定統計量之下的分佈,將不依賴於個別效果 \(\mu_{i}\)。也就是說,藉著conditioning on \(y_{it}\) 可以移除個別效果的影響(incidental parameter problem)。這個意思就是說,在「非嚴格的實證需求」意義下,二元類別變數涉及panel data時,我們或許可以不必顧慮固定效果和隨效果的選擇問題,也就是Hausman test。

所謂「非嚴格的實證需求」這個實務思路,類似線性panel data時,如果解釋變數出現類別時,例如,性別,工作類別,居住地區等等;而且我們研究的目的事要知道些類別解釋變數的影響,就無法使用固定效果,因為LSDV (or de-mean) 會將之全數移除。因為研究目的需要,只能使用隨機效果才能檢視這些變數。

經濟計量方法關於二元類別變數的討論多半是相當理論,例如,Chamberlain (2010) 在的論文。如果涉及動態,請參考 Honoré and Kyriazidou (2000) ,都是 Econometrica 的論文,相當艱澀。

9.2.2 R 實做– 二元資料

我們使用的套件是 plm 的姊妹作品 pglm,資料是內建的 UnionWage,如果是由外部載入,必需宣告panel data.frame才能繼續使用。我們先介紹一個和內建的 UnionWage 完全一樣的 UnionWage.csv,之後,都使用內建資料。

先 library(pglm) 載入套件

UnionWage.tmp=read.csv("data/UnionWage.csv")
UnionWage=pdata.frame(UnionWage.tmp,index = c("id", "year"))
head(UnionWage,10)
##         id year exper health hours married rural school union       wage
## 13-1980 13 1980     1     no  2672       0    no     14    no  1.1975402
## 13-1981 13 1981     2     no  2320       0    no     14   yes  1.8530600
## 13-1982 13 1982     3     no  2940       0    no     14    no  1.3444617
## 13-1983 13 1983     4     no  2960       0    no     14    no  1.4332133
## 13-1984 13 1984     5     no  3071       0    no     14    no  1.5681251
## 13-1985 13 1985     6     no  2864       0    no     14    no  1.6998909
## 13-1986 13 1986     7     no  2994       0    no     14    no -0.7202626
## 13-1987 13 1987     8     no  2640       0    no     14    no  1.6691879
## 17-1980 17 1980     4     no  2484       0    no     13    no  1.6759624
## 17-1981 17 1981     5     no  2804       0    no     13    no  1.5183982
##                  sector       occ   com    region
## 13-1980  businessrepair   service white NorthEast
## 13-1981 personalservice   service white NorthEast
## 13-1982  businessrepair   service white NorthEast
## 13-1983  businessrepair   service white NorthEast
## 13-1984 personalservice  craftfor white NorthEast
## 13-1985  businessrepair manoffpro white NorthEast
## 13-1986  businessrepair manoffpro white NorthEast
## 13-1987  businessrepair manoffpro white NorthEast
## 17-1980           trade manoffpro white NorthEast
## 17-1981           trade manoffpro white NorthEast


變數說明:
  id = the cross-section individual index
  year= the time index
  exper= the experience, computed as age - 6 - schooling
  health= does the individual has health disability ?
  hours= the number of hours worked
  married= is the individual married ?
  rural= does the individual lives in a rural area ?
  school= years of schooling
  union= does the wage is set by collective bargaining
  wage= hourly wage in US dollars
  sector= one of agricultural, mining, construction, trade, transportation, finance, businessrepair, personalservice, entertainment, manufacturing, pro.rel.service, pub.admin
  occ = one of proftech, manoffpro, sales, clerical, craftfor, operative, laborfarm, farmlabor, service
  com = one of black, hisp and other
  region= the region, one of NorthEast, NothernCentral, South and other

首先,使用pooling 資料結構估計二元資料

pglm.pooling <- pglm(union ~ wage + exper + rural, data=UnionWage, family = binomial(‘logit’), model = “pooling”, method = “bfgs”, print.level = 3, R = 5)

其次,檢視估計係數。

coef(summary(pglm.pooling))
##                Estimate Std. error     t value      Pr(> t)
## (Intercept) -2.28446068 0.15068399 -15.1606066 6.447112e-52
## wage         0.72411012 0.07588823   9.5417977 1.403775e-21
## exper       -0.01410725 0.01308915  -1.0777819 2.811311e-01
## ruralyes     0.08068956 0.08999071   0.8966432 3.699093e-01

pooling方法沒有任何橫斷面處理,就是一般的glm。我們可以檢視glm的結果,如下:

datz=UnionWage.tmp[,-c(1,2)]
datz$union=as.integer(as.factor(datz$union))-1
summary(glm(union ~ wage + exper + rural, data=datz, family = binomial('logit')))
## 
## Call:
## glm(formula = union ~ wage + exper + rural, family = binomial("logit"), 
##     data = datz)
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -2.28446    0.15068 -15.161   <2e-16 ***
## wage         0.72411    0.07589   9.542   <2e-16 ***
## exper       -0.01411    0.01309  -1.078    0.281    
## ruralyes     0.08069    0.08999   0.897    0.370    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 4845.6  on 4359  degrees of freedom
## Residual deviance: 4746.3  on 4356  degrees of freedom
## AIC: 4754.3
## 
## Number of Fisher Scoring iterations: 4

我們可以發現兩者完全一樣。也就是說,如果您想使用pooling 估計類別panel data,那個用glm這個方法更好,因為所有的檢測都可以做,包括用predict()執行機率預測。在套件pglm,只提供了估計。

再來,使用random effect 設定估計二元資料

pglm.RE <- pglm(union ~ wage + exper + rural, data=UnionWage, family = binomial(‘logit’), model = “random”, method = “nr”, print.level = 3, R = 5)



其次,檢視估計係數。

coef(summary(pglm.RE))
##                Estimate Std. error     t value       Pr(> t)
## (Intercept) -3.18669099 0.25818524 -12.3426537  5.336747e-35
## wage         0.74243612 0.14032956   5.2906611  1.218750e-07
## exper       -0.04532529 0.02194934  -2.0649957  3.892341e-02
## ruralyes     0.07931936 0.21513642   0.3686933  7.123563e-01
## sigma        2.32635513 0.08005005  29.0612591 1.109018e-185

隨機效果多了一個底列的變異數估計,其餘參數和pooling 的結果都很接近。pglm沒有提供預測函數,也沒有dispersion值;所以,用pglm只能估計,其餘如預測,都必需自己來。這也是為什麼在本章前面,要詳細解釋標準glm的機率計算方法。

9.2.3 some count data models

接下來,我們用內建的專利資料,執行布阿松的panel GLM。資料如下:

data("PatentsRDUS", package="pglm")
head(PatentsRDUS)
##   cusip year ardssic scisect  capital72 sumpat         rd patents
## 1   800 1970      15      no 438.605335    354  2.7097056      30
## 2  1030 1970      14     yes   7.206043     13  0.6324526       3
## 3  2824 1970       4     yes 284.004476    493 29.6819762      48
## 4  4644 1970      13      no   1.981333      2  1.7218512       1
## 5  7842 1970      16      no   7.880017     12  1.4845475       2
## 6 10202 1970       3      no 396.533291    393  7.8366387      32

變數說明:
  cusip= compustat’s identifying number for the firm
  year= year
  ardssic= a two-digit code for the applied R&D industrial classification
  scisect= is the firm in the scientific sector ?
  capital72= book value of capital in 1972
  sumpat= the sum of patents applied for between 1972-1979
  rd = R&D spending during the year (in 1972 dollars)
  patents= the number of patents applied for during the year that were eventually granted

很明顯地,被解釋變數是專利數patents。計數型資料,固定效果,隨機效果皆可

首先,使用固定效果。布阿松的family有兩個宣告可以用:“negbin” 和 “poisson”。

output.pois.FE <- pglm(patents ~ lag(log(rd), 0:5) + scisect + log(capital72) + factor(year), PatentsRDUS,family = negbin, model = “within”, print.level = 3, method = “nr”, index = c(‘cusip’, ‘year’))

檢視係數。

coef(summary(output.pois.FE))
##                        Estimate Std. error     t value      Pr(> t)
## (Intercept)         1.661391906 0.34355211  4.83592411 1.325285e-06
## lag(log(rd), 0:5)0  0.272678998 0.07078382  3.85227868 1.170237e-04
## lag(log(rd), 0:5)1 -0.097886613 0.07679202 -1.27469765 2.024163e-01
## lag(log(rd), 0:5)2  0.032076216 0.07086391  0.45264529 6.508042e-01
## lag(log(rd), 0:5)3 -0.020392326 0.06577085 -0.31005112 7.565221e-01
## lag(log(rd), 0:5)4  0.016221420 0.06288501  0.25795369 7.964426e-01
## lag(log(rd), 0:5)5 -0.009727993 0.05328640 -0.18256051 8.551429e-01
## scisectyes          0.017639777 0.19807352  0.08905672 9.290368e-01
## log(capital72)      0.207148837 0.07796793  2.65684680 7.887528e-03
## factor(year)1976   -0.038392668 0.02447217 -1.56882972 1.166876e-01
## factor(year)1977   -0.039940327 0.02522746 -1.58320824 1.133740e-01
## factor(year)1978   -0.144327802 0.02645968 -5.45463173 4.907444e-08
## factor(year)1979   -0.195751826 0.02716372 -7.20637068 5.746284e-13

其次,使用pooling估計。

output.pois.pool <- pglm(patents ~ lag(log(rd), 0:5) + scisect + log(capital72) + factor(year), PatentsRDUS, family = “poisson”, model = “pooling”, index = c(“cusip”, “year”), print.level = 0, method=“nr”)



檢視係數。

coef(summary(output.pois.pool))
##                        Estimate  Std. error     t value      Pr(> t)
## (Intercept)         0.809909894 0.021188565  38.2239147 0.000000e+00
## lag(log(rd), 0:5)0  0.134524577 0.030718260   4.3793033 1.190594e-05
## lag(log(rd), 0:5)1 -0.052944368 0.042797205  -1.2370987 2.160504e-01
## lag(log(rd), 0:5)2  0.008229465 0.039784462   0.2068512 8.361261e-01
## lag(log(rd), 0:5)3  0.066096918 0.036968573   1.7879218 7.378862e-02
## lag(log(rd), 0:5)4  0.090181342 0.033336156   2.7052112 6.826098e-03
## lag(log(rd), 0:5)5  0.239538388 0.022459775  10.6652175 1.480523e-26
## scisectyes          0.454309575 0.009242341  49.1552483 0.000000e+00
## log(capital72)      0.252862548 0.004414258  57.2831414 0.000000e+00
## factor(year)1976   -0.043515208 0.013120942  -3.3164698 9.116243e-04
## factor(year)1977   -0.052441295 0.013287569  -3.9466433 7.925451e-05
## factor(year)1978   -0.170242204 0.013529768 -12.5827878 2.625965e-36
## factor(year)1979   -0.201878694 0.013533502 -14.9169594 2.556605e-50

最後,使用隨機效果估計。

output.pois.RE <- pglm(patents ~ lag(log(rd), 0:5) + scisect + log(capital72) + factor(year), PatentsRDUS, family = poisson, model = “random”, index = c(“cusip”, “year”), print.level = 0, method=“nr”)

檢視係數。

coef(summary(output.pois.RE))
##                       Estimate Std. error     t value      Pr(> t)
## (Intercept)         0.41078760 0.14674431   2.7993425 5.120679e-03
## lag(log(rd), 0:5)0  0.40345381 0.04350220   9.2743314 1.787365e-20
## lag(log(rd), 0:5)1 -0.04617658 0.04822236  -0.9575761 3.382765e-01
## lag(log(rd), 0:5)2  0.10792359 0.04471154   2.4137749 1.578822e-02
## lag(log(rd), 0:5)3  0.02977315 0.04132353   0.7204890 4.712239e-01
## lag(log(rd), 0:5)4  0.01069573 0.03770738   0.2836508 7.766780e-01
## lag(log(rd), 0:5)5  0.04061105 0.03157378   1.2862271 1.983638e-01
## scisectyes          0.25700007 0.11227165   2.2890914 2.207404e-02
## log(capital72)      0.29169335 0.03933681   7.4152772 1.213707e-13
## factor(year)1976   -0.04496242 0.01312912  -3.4246327 6.156312e-04
## factor(year)1977   -0.04838634 0.01340178  -3.6104417 3.056760e-04
## factor(year)1978   -0.17416192 0.01397018 -12.4666875 1.134445e-35
## factor(year)1979   -0.22589767 0.01466453 -15.4043572 1.530031e-53
## sigma               1.16968955 0.09471381  12.3497258 4.887775e-35

雖然,pglm是glm的姊妹作品,但是多數plm的檢定,都不適用。畢竟很多 lm 可以作的檢定,在 glm 也不能做,反之亦然;panel data的狀況也是這樣。但是,透過混淆矩陣,可以分析比較模型的好壞,和分類演算法完全一樣。這一部份,晚一點再補進來。

9.3 從多層次模型的角度看panel GLM


本書第6章談序列相關修正問題時,曾介紹過使用MLM架構來處理。從資料結構的角度,panel data只是多層次資料(multilevel data)的一個特例。其實 multilevel data 比 panel data 更為一般化,也可處理nested panel,例如  \(y_{ijk,t}\)  這樣的層次結構。除非讀者須要執著在計量經濟學的胡同做研究,不然多層次模型(multilevel linear model,MLM)會是更好的選擇,給予我們更為彈性的架構來分析資料。

我在這裡解說panel glm 的一些問題,也利用這節叮嚀研究人員如果遇到 categorical panel data,首選是MLM的 lme4,而不是 pglm。原因在於pglm 有一些套件功能性缺失,讓我們利用預測評估多個模型相當困難。

基本上,在類別資料時,如果用pooling方式,則 glm就可以完善處理;其餘,如固定效果,隨機效果,乃至 two-way 設定,MLM都可以處理。這一節,我們用混淆矩陣來說明預測問題。其餘模型,讀者熟悉語法後,自然可以在MLM架構下處理。

9.3.1 預測

第1步:我們取用前面 UnionWage 二元資料與 pglm 的隨機效果物件 pglm.RE,重看一次係數。

coef(summary(pglm.RE))
##                Estimate Std. error     t value       Pr(> t)
## (Intercept) -3.18669099 0.25818524 -12.3426537  5.336747e-35
## wage         0.74243612 0.14032956   5.2906611  1.218750e-07
## exper       -0.04532529 0.02194934  -2.0649957  3.892341e-02
## ruralyes     0.07931936 0.21513642   0.3686933  7.123563e-01
## sigma        2.32635513 0.08005005  29.0612591 1.109018e-185


第2步:預測。因為pglm沒有提供預測函數,然而在panel 演算中,有許多處理必需還原,例如隨機效果值必需還原加回去才可以計算期望值。這些需求,plm都有,但是pglm都沒有;所以,如果利用標準glm算法,會出現計算失敗的結果,如下展示:

data.pglm.re=UnionWage
data.pglm.re$union=as.integer(as.factor(UnionWage$union))-1
data.pglm.re$rural=as.integer(as.factor(UnionWage$rural))-1
data.pglm.re0=cbind(1,data.pglm.re[,colnames(pglm.RE$model)[-1]])
score.pglm.re=as.matrix(data.pglm.re0)%*% as.matrix(coef(pglm.RE)[1:4])
prob.pglm.re=c(exp(score.pglm.re)/(1+exp(score.pglm.re)))
prediction.pglm.re=ifelse(prob.pglm.re>=0.5,1,0)
table(prediction.pglm.re)
## prediction.pglm.re
##    0 
## 4360

我們利用table()發現所有的預測都是0,這樣就沒有用了。畢竟我們的資料有3296個0(no),1064個1(yes)。這不是pglm計算錯,而是回傳物件太少,讓我們必需花很大精神還原。接下來,我們看看MLM是否就沒有這問題。

首先,估計MLM隨機效果模型,如下:(1|id)宣告個別效果id以隨機效果方式處理。此處和第6章不同的地方在於使用了glmer()函數,而不是lmer()函數。

library(lme4)
## 載入需要的套件:Matrix
dat.mlm=UnionWage.tmp
dat.mlm$union=as.integer(as.factor(UnionWage.tmp$union))-1
mlm.RE <- glmer(union ~ (1|id) + wage + exper + rural , data=dat.mlm, family =binomial(link="logit"))

估計完後,我們取出如下係數

coef(summary(mlm.RE))
##                Estimate Std. Error     z value     Pr(>|z|)
## (Intercept) -3.56146283 0.31553439 -11.2870830 1.519977e-29
## wage         0.84099466 0.15672045   5.3662087 8.040888e-08
## exper       -0.06689668 0.02346379  -2.8510600 4.357375e-03
## ruralyes     0.12337240 0.23604472   0.5226654 6.012071e-01

MLM係數和pglm係數,只有些微差距,因此,MLM的預測結果,應該很接近。我們先看MLM的預測,如下語法:

prob.mlm.re=predict(mlm.RE,type="response")
prediction.mlm.re=ifelse(prob.mlm.re>=0.5,1,0)
table(prediction.mlm.re)
## prediction.mlm.re
##    0    1 
## 3460  900


我們發現預測還不錯,但是正確程度與否要和原始值配對。類別資料採用混淆矩陣,最簡單的就是套件caret的confusionMatrix函數,如下

CF.mlm.re=table(prediction=as.numeric(prediction.mlm.re),actual=dat.mlm$union)
caret::confusionMatrix(CF.mlm.re)
## Confusion Matrix and Statistics
## 
##           actual
## prediction    0    1
##          0 3141  319
##          1  155  745
##                                           
##                Accuracy : 0.8913          
##                  95% CI : (0.8817, 0.9004)
##     No Information Rate : 0.756           
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6891          
##                                           
##  Mcnemar's Test P-Value : 7.055e-14       
##                                           
##             Sensitivity : 0.9530          
##             Specificity : 0.7002          
##          Pos Pred Value : 0.9078          
##          Neg Pred Value : 0.8278          
##              Prevalence : 0.7560          
##          Detection Rate : 0.7204          
##    Detection Prevalence : 0.7936          
##       Balanced Accuracy : 0.8266          
##                                           
##        'Positive' Class : 0               
## 

若以0為positive,根據混淆矩陣的績效計算,我們發現正確度(Accuracy)達到0.89,精確度(precision 或 Pos Pred Value)達到0.9078,召回率(Recall 或Neg Pred Value)達到0.8278;校正觀察與機率符合度的 kappa 則是 0.6891,算是相當好(kappa>0.4可以算是有參考價值的結果)。

如果研究者只須要係數,那麼 pglm 完全沒問題。如果須要處理訓練集和測試集的問題,則樣本外預測就會是一個重要架構,pglm目前是完全無法妥善處理。

9.3.2 序列相關修正

panel data的類別資料,因為有時間序列,所以,不可避免的會出現序列相關問題,因此,如第6章,序列相關的影響會導致估計解果出現bias。因此,就須要校正序列相關的影響。這類問題,較容易出現在布阿松,例如,之前使用的專利。例如,一個產業的專利,會和前一年有關。pglm如果添加落後期來處理序列相關,會導致動態問題,在類別資料很不容易處理。本節介紹在布阿松分佈時,序列相關校正的作法。

R套件有數個處理AR(1)的套件,主要有兩個發佈在CRAN: glmmPQR 和 glmmTMB。glmmPQR 是MASS的函數,glmmTMB則完全屬於glmmTMB套件。很可惜地,兩個套件的結果差距很大,這一點,我要謝謝UT Austin的林澤民教授,沒有他指出,我都不知道有這麼大差異。所以,我們先用simulation看看兩個套件,哪一個才是我們應該用的。

9.3.2.1 poisson 型

  第1步。我們先用模擬數據產生具AR(1)的布阿松數據,如下:

sim.AR1 <- function(ar1=0.7,sdGroup=2,sdres=1,
                    nperGroup=50,nGroup=200,seed=NULL,
                    linkinv="identity",simfun="identity",
                    dist=c("mvrnorm","rmvt")) {
  
  if (!is.null(seed)) set.seed(seed)
  cmat <- sdres*ar1^abs(outer(0:(nperGroup-1),0:(nperGroup-1),"-"))
  
  if (dist=="rmvt") {
    errs <- LaplacesDemon::rmvt(n=nGroup, mu=runif(nperGroup), S=cmat, df=Inf)
    } else {
    errs <- MASS::mvrnorm(nGroup,mu=runif(nperGroup),Sigma=cmat)
    }
  
  ranef <- rnorm(nGroup,mean=sample(0:10,1),sd=sdGroup)
  df <- data.frame(ID=rep(1:nGroup,each=nperGroup))
  eta <- ranef[as.numeric(df$ID)] + c(t(errs)) ## unpack errors by row
  mu <- linkinv(eta)
  df$y <- simfun(mu)
  df$year <- factor(rep(1:nperGroup,nGroup))
  return(df)
} 

sim.AR1是模擬程式,允許多變量的常態分佈和student t分佈。

  第2步。DGP,令AR(1)係數為0.8,t=20, N=250,先用常態分佈。 因為我們要比較序列相關的校正,所以DGP就不生成解釋變數。

sim.pois <- sim.AR1(ar1=0.8,nperGroup=20,nGroup=250,dist=c("mvrnorm","rmvt")[1],
              linkinv=exp,simfun=function(x) rpois(length(x),lambda=x))
out.pglm.RE=plm::plm(y~lag(y,1),data=sim.pois, model = "random",index="ID")
coef(summary(out.pglm.RE))
##              Estimate   Std. Error   z-value     Pr(>|z|)
## (Intercept) 90.585661 13.365664031  6.777491 1.222812e-11
## lag(y, 1)    0.738531  0.009403339 78.539228 0.000000e+00
out.plm.FE=plm::plm(y~lag(y,1),data=sim.pois,model = "within",index="ID")
coef(summary(out.plm.FE))
##            Estimate Std. Error  t-value      Pr(>|t|)
## lag(y, 1) 0.4660618 0.01270094 36.69505 4.059389e-258


我們發現這筆資料套用 plm 檢視線性一階自我相關,隨機效果的話,可以確認AR(1)較接近0.8,bias 較低;固定效果時,AR(1)係數=0.378,bias較高。這樣也給我們提供一種檢視資料序列相關程度的方法

  第3步。配適MASS::glmmPQR

out.PQL=MASS::glmmPQL(y ~ 1,random= ~1|ID, data=sim.pois,family="poisson",
                      correlation=nlme:::Initialize(nlme:::corAR1(0.5, form = ~ 1|ID), sim.pois),
                      verbose=FALSE, niter = 150)
print(out.PQL)
## Linear mixed-effects model fit by maximum likelihood
##   Data: sim.pois 
##   Log-likelihood: NA
##   Fixed: y ~ 1 
## (Intercept) 
##    4.595846 
## 
## Random effects:
##  Formula: ~1 | ID
##         (Intercept) Residual
## StdDev:     1.47934 18.44052
## 
## Correlation Structure: AR(1)
##  Formula: ~1 | ID 
##  Parameter estimate(s):
##       Phi 
## 0.5287646 
## Variance function:
##  Structure: fixed weights
##  Formula: ~invwt 
## Number of Observations: 5000
## Number of Groups: 250

我們發現估出來的AR(1)係數 \(\phi \sim 0.5\),和模擬假設的0.8差距甚遠, 接下來,我們看殘差的序列相關降低多少,如下:

dat.PQL=data.frame(id=sim.pois$ID,year=sim.pois$year, e=residuals(out.PQL))
plm::plm(e~lag(e,1),data=dat.PQL,index="id", method="within") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## lag(e, 1) 
##   0.43012

降低約不到一半,0.366。

  第4步。配適 glmmTMB

library(glmmTMB)
out.TMB=glmmTMB::glmmTMB(y ~ 1 + (1|ID) + ar1(year-1|ID), data=sim.pois, family="poisson",
                         control=glmmTMBControl(optCtrl =list(iter.max=1000, eval.max=800)))
print(out.TMB)
## Formula:          y ~ 1 + (1 | ID) + ar1(year - 1 | ID)
## Data: sim.pois
##       AIC       BIC    logLik  df.resid 
##  48615.90  48641.97 -24303.95      4996 
## Random-effects (co)variances:
## 
## Conditional model:
##  Groups Name        Std.Dev. Corr      
##  ID     (Intercept) 2.044              
##  ID.1   year1       0.986    0.70 (ar1)
## 
## Number of obs: 5000 / Conditional model: ID, 250
## 
## Fixed Effects:
## 
## Conditional model:
## (Intercept)  
##       3.521

glmmTMB 估計的AR(1)係數是0.72,略接近0.8。然後修正後的殘差序列相關表現如何呢?如下:

dat.TMB=cbind(id=sim.pois$ID,year=sim.pois$year, e=residuals(out.TMB,"pearson"))
plm::plm(e~lag(e,1),data=dat.TMB,index="id") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## lag(e, 1) 
##  -0.28901

修正後的殘差,序列相關程度降為-0.2859,且變成負的。從這樣的結果來看,或許當類別資料遇到panel data時,且又有序列相關問題的時候,使用glmmTMB處理,應該是可以的。

最後一個方法是使用套件lme4ord,因為這個套件是lme4作者時多年前開發的,但後來沒有發佈在CRAN,我們可以找到github,所以可以 “devtools::install_git(”https://github.com/stevencarlislewalker/lme4ord“)” 這樣裝。

corObj <- nlme:::Initialize(nlme:::corAR1(0.5, form = ~ 1|ID), sim.pois)
out.lme4ord=lme4ord::strucGlmer(y ~ 1 + (1|ID) + nlmeCorStruct(1, corObj = corObj, sig = 1),
                    family="poisson", data=sim.pois)
print(out.lme4ord)
## Structured GLMM fit by maximum likelihood (Laplace Approx)   ['strucGlmer']
##  Family: poisson  ( log )
## Formula: y ~ 1 + (1 | ID) + nlmeCorStruct(1, corObj = corObj, sig = 1)
##    Data: sim.pois
##        AIC        BIC     logLik   deviance   df.resid 
##  48615.913  48641.982 -24303.957   1020.251       4996 
## Random effects term (class: unstruc): 
##   covariance parameter:   2.04394 
##   variance-correlation:   
##  Groups Name        Std.Dev.
##  ID     (Intercept) 2.0439  
## Random effects term (class: nlmeCorStruct): 
## Correlation structure of class corAR1 representing
##       Phi 
## 0.6967021 
##   Standard deviation multiplier:  0.9859619 
## Fixed Effects:
## (Intercept)  
##       3.521

估計出來的AR(1)係數是0.7167975,和0.8也是有bias。然後修正後的殘差序列相關表現如下:

dat.lme4ord=cbind(id=sim.pois$ID,year=sim.pois$year, e=residuals(out.lme4ord,"pearson"))
plm::plm(e~lag(e,1)-1,data=dat.lme4ord,index="id",method="random") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1) - 1
## 
## Coefficients:
## lag(e, 1) 
##  -0.23752


由以上結果,用排他法敘述。基本上,如果 panel data 遇到布阿松分佈且殘差須要序列相關修正時,應該可以排除 MASS::glmmPQR。





接下來,我們展示專利的實際數據建模型處理結果。

library(pglm)
data(PatentsRDUS)
coef(summary(plm(patents~lag(patents,1), data = PatentsRDUS, index = c("cusip", "year"), print.level = 0, method = "nr",model="random")))
##                  Estimate  Std. Error    z-value  Pr(>|z|)
## (Intercept)     0.7313954 0.295812521   2.472497 0.0134173
## lag(patents, 1) 0.9562068 0.003530619 270.832631 0.0000000

以隨機效果估計專利一階序列相關AR(1)=0.95,算是很高;但是用固定效果,則AR(1)=0.569。根據前面模擬資料,我們可以認為專利數有高度序列相關。 我們先估計不修正序列相關的結果,先用 panel data glm。

coef(summary(pglm(formula = patents ~ scisect + log(capital72) + 
    factor(year), data = PatentsRDUS, model = "random", family = poisson, 
    index = c("cusip", "year"), print.level = 0, method = "nr")))
##                     Estimate Std. error    t value       Pr(> t)
## (Intercept)      -0.45721675 0.12874702  -3.551280  3.833621e-04
## scisectyes        0.79944027 0.11320572   7.061836  1.643164e-12
## log(capital72)    0.69979217 0.02607325  26.839472 1.119357e-158
## factor(year)1971 -0.04847954 0.01216911  -3.983821  6.781587e-05
## factor(year)1972 -0.09687922 0.01232266  -7.861876  3.784238e-15
## factor(year)1973 -0.07928438 0.01226620  -6.463647  1.022095e-10
## factor(year)1974 -0.06168634 0.01221046  -5.051926  4.373769e-07
## factor(year)1975 -0.08147668 0.01227319  -6.638587  3.167034e-11
## factor(year)1976 -0.10969682 0.01236425  -8.872094  7.178305e-19
## factor(year)1977 -0.09903070 0.01232961  -8.031938  9.594465e-16
## factor(year)1978 -0.19832936 0.01266282 -15.662334  2.736678e-55
## factor(year)1979 -0.22005966 0.01273901 -17.274468  7.324508e-67
## sigma             0.94242491 0.06662247  14.145752  1.983839e-45

然後再用lme4::glmer方法,估計未修正的結果,如下。

library(lme4)
out.glmer.pois=glmer(patents ~ (1|cusip) +scisect + log(capital72) + factor(year), data=PatentsRDUS, family = "poisson")


檢視參數。

coef(summary(out.glmer.pois))
##                     Estimate Std. Error    z value      Pr(>|z|)
## (Intercept)      -1.26783502 0.16046818  -7.900850  2.770081e-15
## scisectyes        1.06208561 0.13632797   7.790665  6.665728e-15
## log(capital72)    0.72962985 0.03236415  22.544384 1.524522e-112
## factor(year)1971 -0.04846584 0.01216133  -3.985241  6.741162e-05
## factor(year)1972 -0.09688136 0.01231484  -7.867040  3.631300e-15
## factor(year)1973 -0.07927945 0.01225840  -6.467359  9.973049e-11
## factor(year)1974 -0.06166626 0.01220264  -5.053517  4.337482e-07
## factor(year)1975 -0.08145748 0.01226534  -6.641273  3.109848e-11
## factor(year)1976 -0.10969185 0.01235639  -8.877341  6.847790e-19
## factor(year)1977 -0.09901838 0.01232174  -8.036068  9.276708e-16
## factor(year)1978 -0.19831459 0.01265473 -15.671181  2.381134e-55
## factor(year)1979 -0.22004339 0.01273086 -17.284245  6.182521e-67


pglm和lme4::glmer的估計結果,變數對應的符號一樣,只是係數值有差異。

再來就是比較三個方法修正一階序列相關的結果。

  方法一:MASS::glmmPQL

先估計不修正序列相關的。

glmmPQL_pois<-MASS::glmmPQL(patents ~ scisect + log(capital72) + factor(year),random = ~1|cusip, data=PatentsRDUS, family=poisson)


再估計修正一階相關的:

corObj <- nlme:::Initialize(nlme:::corAR1(0.5, form = ~ 1|cusip), PatentsRDUS)
glmmPQL_pois_ar1<- MASS::glmmPQL(patents ~ scisect + log(capital72) + factor(year),random = ~1|cusip, data=PatentsRDUS, family=poisson,  correlation=corObj)


檢視結果:

print(glmmPQL_pois_ar1)
## Linear mixed-effects model fit by maximum likelihood
##   Data: PatentsRDUS 
##   Log-likelihood: NA
##   Fixed: patents ~ scisect + log(capital72) + factor(year) 
##      (Intercept)       scisectyes   log(capital72) factor(year)1971 
##      -1.02633729       0.96305433       0.70489029      -0.04805632 
## factor(year)1972 factor(year)1973 factor(year)1974 factor(year)1975 
##      -0.09603172      -0.07957237      -0.06145255      -0.08211267 
## factor(year)1976 factor(year)1977 factor(year)1978 factor(year)1979 
##      -0.11083960      -0.10098091      -0.20169508      -0.22096449 
## 
## Random effects:
##  Formula: ~1 | cusip
##         (Intercept) Residual
## StdDev:    1.085895 1.766658
## 
## Correlation Structure: AR(1)
##  Formula: ~1 | cusip 
##  Parameter estimate(s):
##        Phi 
## 0.01219726 
## Variance function:
##  Structure: fixed weights
##  Formula: ~invwt 
## Number of Observations: 3460
## Number of Groups: 346


我們發現MASS::glmmPQL估計的序列相關係數Phi=0.012,小的不合理。修正後的效果則是越修越大。

dat.PQL=data.frame(id=PatentsRDUS$cusip,year=PatentsRDUS$year, e=residuals(glmmPQL_pois_ar1))
plm::plm(e~lag(e,1),data=dat.PQL,index="id") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## lag(e, 1) 
##  0.040867


我們再檢視係數顯著性:

coef(summary(glmmPQL_pois))
##                        Value  Std.Error   DF   t-value      p-value
## (Intercept)      -1.04943747 0.15043858 3105 -6.975853 3.699969e-12
## scisectyes        0.98881691 0.12380376  343  7.986970 2.115373e-14
## log(capital72)    0.70791864 0.02976853  343 23.780770 1.528699e-74
## factor(year)1971 -0.04847954 0.02155737 3105 -2.248862 2.459112e-02
## factor(year)1972 -0.09687922 0.02182939 3105 -4.438018 9.395037e-06
## factor(year)1973 -0.07928438 0.02172937 3105 -3.648720 2.678866e-04
## factor(year)1974 -0.06168634 0.02163063 3105 -2.851806 4.375891e-03
## factor(year)1975 -0.08147668 0.02174176 3105 -3.747474 1.818756e-04
## factor(year)1976 -0.10969682 0.02190307 3105 -5.008285 5.798425e-07
## factor(year)1977 -0.09903070 0.02184171 3105 -4.534019 6.006044e-06
## factor(year)1978 -0.19832936 0.02243198 3105 -8.841367 1.553101e-18
## factor(year)1979 -0.22005966 0.02256695 3105 -9.751415 3.769261e-22
coef(summary(glmmPQL_pois_ar1))
##                        Value  Std.Error   DF   t-value      p-value
## (Intercept)      -1.02633729 0.14903722 3105 -6.886449 6.894807e-12
## scisectyes        0.96305433 0.12214311  343  7.884639 4.245458e-14
## log(capital72)    0.70489029 0.02948595  343 23.905969 4.961623e-75
## factor(year)1971 -0.04805632 0.02140372 3105 -2.245232 2.482335e-02
## factor(year)1972 -0.09603172 0.02179048 3105 -4.407049 1.083375e-05
## factor(year)1973 -0.07957237 0.02169123 3105 -3.668412 2.481594e-04
## factor(year)1974 -0.06145255 0.02158990 3105 -2.846357 4.451282e-03
## factor(year)1975 -0.08211267 0.02170571 3105 -3.782998 1.578736e-04
## factor(year)1976 -0.11083960 0.02186978 3105 -5.068162 4.251893e-07
## factor(year)1977 -0.10098091 0.02181297 3105 -4.629398 3.817699e-06
## factor(year)1978 -0.20169508 0.02241551 3105 -8.998015 3.910968e-19
## factor(year)1979 -0.22096449 0.02245920 3105 -9.838484 1.634197e-22


承上,glmmPQL修不修正序列相關,對於係數和顯著性,影響不大。



  方法二:glmmTMB

先做不修正的:

glmmTMB_pois <- glmmTMB(patents ~ scisect + (1|cusip) + log(capital72) + factor(year), data=PatentsRDUS, family=poisson)
print(glmmTMB_pois)  
## Formula:          
## patents ~ scisect + (1 | cusip) + log(capital72) + factor(year)
## Data: PatentsRDUS
##       AIC       BIC    logLik  df.resid 
##  24302.11  24382.05 -12138.05      3447 
## Random-effects (co)variances:
## 
## Conditional model:
##  Groups Name        Std.Dev.
##  cusip  (Intercept) 1.23    
## 
## Number of obs: 3460 / Conditional model: cusip, 346
## 
## Fixed Effects:
## 
## Conditional model:
##      (Intercept)        scisectyes    log(capital72)  factor(year)1971  
##         -1.26824           1.06242           0.72969          -0.04848  
## factor(year)1972  factor(year)1973  factor(year)1974  factor(year)1975  
##         -0.09688          -0.07929          -0.06169          -0.08148  
## factor(year)1976  factor(year)1977  factor(year)1978  factor(year)1979  
##         -0.10970          -0.09903          -0.19833          -0.22006


再做一階序列相關修正的

library(glmmTMB)
glmmTMB_pois_ar1 <- glmmTMB(patents ~ scisect + (1|cusip) + log(capital72) + factor(year) +  ar1(year-1|cusip), data=PatentsRDUS, family=poisson)
                    
print(glmmTMB_pois_ar1)  
## Formula:          
## patents ~ scisect + (1 | cusip) + log(capital72) + factor(year) +  
##     ar1(year - 1 | cusip)
## Data: PatentsRDUS
##       AIC       BIC    logLik  df.resid 
## 19919.122 20011.357 -9944.561      3445 
## Random-effects (co)variances:
## 
## Conditional model:
##  Groups  Name        Std.Dev. Corr      
##  cusip   (Intercept) 0.001078           
##  cusip.1 year1970    1.273645 0.99 (ar1)
## 
## Number of obs: 3460 / Conditional model: cusip, 346
## 
## Fixed Effects:
## 
## Conditional model:
##      (Intercept)        scisectyes    log(capital72)  factor(year)1971  
##         -1.25274           1.06858           0.73162          -0.05224  
## factor(year)1972  factor(year)1973  factor(year)1974  factor(year)1975  
##         -0.10709          -0.12544          -0.11346          -0.17501  
## factor(year)1976  factor(year)1977  factor(year)1978  factor(year)1979  
##         -0.22258          -0.22113          -0.32397          -0.37592


我們發glmmTMB估計的序列相關係數高的離譜  ar1=0.99,接近非定態的 1,相當高。雖然有明顯的修正效果。但是,偏誤仍高。

接下來看看殘差的序列相關。

dat.TMB=data.frame(id=PatentsRDUS$cusip,year=PatentsRDUS$year, e=residuals(glmmTMB_pois_ar1))
plm::plm(e~lag(e,1),data=dat.TMB,index="id") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## lag(e, 1) 
##   -0.4146


我們再檢視係數顯著性:

coef(summary(glmmTMB_pois))$cond
##                     Estimate Std. Error    z value      Pr(>|z|)
## (Intercept)      -1.26823890 0.16097444  -7.878511  3.313047e-15
## scisectyes        1.06242179 0.13650580   7.782979  7.083640e-15
## log(capital72)    0.72968532 0.03242367  22.504713 3.732180e-112
## factor(year)1971 -0.04848133 0.01216910  -3.983969  6.777359e-05
## factor(year)1972 -0.09687941 0.01232265  -7.861897  3.783595e-15
## factor(year)1973 -0.07928769 0.01226620  -6.463915  1.020281e-10
## factor(year)1974 -0.06168657 0.01221045  -5.051948  4.373267e-07
## factor(year)1975 -0.08147588 0.01227318  -6.638529  3.168298e-11
## factor(year)1976 -0.10969990 0.01236425  -8.872342  7.162344e-19
## factor(year)1977 -0.09903113 0.01232961  -8.031978  9.591343e-16
## factor(year)1978 -0.19833240 0.01266282 -15.662573  2.726421e-55
## factor(year)1979 -0.22006255 0.01273901 -17.274694  7.295936e-67
coef(summary(glmmTMB_pois_ar1))$cond
##                     Estimate Std. Error   z value      Pr(>|z|)
## (Intercept)      -1.25274204 0.16425543 -7.626792  2.406668e-14
## scisectyes        1.06857780 0.13763168  7.764040  8.226613e-15
## log(capital72)    0.73161772 0.03271157 22.365716 8.491048e-111
## factor(year)1971 -0.05223807 0.02225215 -2.347552  1.889725e-02
## factor(year)1972 -0.10708814 0.02711549 -3.949335  7.836853e-05
## factor(year)1973 -0.12544024 0.03052969 -4.108795  3.977283e-05
## factor(year)1974 -0.11345628 0.03322472 -3.414816  6.382520e-04
## factor(year)1975 -0.17500831 0.03572788 -4.898368  9.663569e-07
## factor(year)1976 -0.22257804 0.03793571 -5.867243  4.431022e-09
## factor(year)1977 -0.22113031 0.03992851 -5.538156  3.056736e-08
## factor(year)1978 -0.32397412 0.04207625 -7.699691  1.363961e-14
## factor(year)1979 -0.37591602 0.04453014 -8.441833  3.123995e-17


承上,glmmTMB修不修正序列相關,對於顯著性沒有太大影響,但是,對於係數數值就有差異。這樣的差異影響多少,我們待會看預測誤差評估。


  方法三:glmer

先做不修正的:

glmer_pois <- glmer(patents ~ (1|cusip) +scisect + log(capital72) + factor(year), data=PatentsRDUS, family = "poisson")


再做修正的

corObj <- nlme:::Initialize(nlme:::corAR1(0.5, form = ~ 1|cusip), PatentsRDUS)
glmer_pois_ar1 <- lme4ord::strucGlmer(patents ~ (1|cusip) +scisect + log(capital72) + factor(year)+nlmeCorStruct(1, corObj = corObj, sig = 1), data=PatentsRDUS, family = "poisson")



print(glmer_pois_ar1)
## Structured GLMM fit by maximum likelihood (Laplace Approx)   ['strucGlmer']
##  Family: poisson  ( log )
## Formula: patents ~ (1 | cusip) + scisect + log(capital72) + factor(year) +  
##     nlmeCorStruct(1, corObj = corObj, sig = 1)
##    Data: PatentsRDUS
##        AIC        BIC     logLik   deviance   df.resid 
##  20680.575  20772.810 -10325.287   2337.017       3445 
## Random effects term (class: unstruc): 
##   covariance parameter:   1.227942 
##   variance-correlation:   
##  Groups Name        Std.Dev.
##  cusip  (Intercept) 1.2279  
## Random effects term (class: nlmeCorStruct): 
## Correlation structure of class corAR1 representing
##        Phi 
## 0.06884345 
##   Standard deviation multiplier:  0.2903567 
## Fixed Effects:
##      (Intercept)        scisectyes    log(capital72)  factor(year)1971  
##         -1.27740           1.06776           0.73210          -0.05690  
## factor(year)1972  factor(year)1973  factor(year)1974  factor(year)1975  
##         -0.09782          -0.12535          -0.08875          -0.15050  
## factor(year)1976  factor(year)1977  factor(year)1978  factor(year)1979  
##         -0.17454          -0.17036          -0.24663          -0.31194


glmer估計的序列相關係數是0.068,感覺有些偏小。



最後則是序列相關修正的效果:

dat.glmer=data.frame(id=PatentsRDUS$cusip,year=PatentsRDUS$year, e=residuals(glmer_pois_ar1,"pearson"))
plm::plm(e~lag(e,1),data=dat.glmer,index="id") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## lag(e, 1) 
##   0.12808


修正後的序列序列相關係數,反而偏高。最後看看係數顯著性。

coef(summary(glmer_pois))
##                     Estimate Std. Error    z value      Pr(>|z|)
## (Intercept)      -1.26783502 0.16046818  -7.900850  2.770081e-15
## scisectyes        1.06208561 0.13632797   7.790665  6.665728e-15
## log(capital72)    0.72962985 0.03236415  22.544384 1.524522e-112
## factor(year)1971 -0.04846584 0.01216133  -3.985241  6.741162e-05
## factor(year)1972 -0.09688136 0.01231484  -7.867040  3.631300e-15
## factor(year)1973 -0.07927945 0.01225840  -6.467359  9.973049e-11
## factor(year)1974 -0.06166626 0.01220264  -5.053517  4.337482e-07
## factor(year)1975 -0.08145748 0.01226534  -6.641273  3.109848e-11
## factor(year)1976 -0.10969185 0.01235639  -8.877341  6.847790e-19
## factor(year)1977 -0.09901838 0.01232174  -8.036068  9.276708e-16
## factor(year)1978 -0.19831459 0.01265473 -15.671181  2.381134e-55
## factor(year)1979 -0.22004339 0.01273086 -17.284245  6.182521e-67


coef(summary(glmer_pois_ar1))
##                     Estimate Std. Error   z value       Pr(>|z)
## (Intercept)      -1.27740244 0.16260754 -7.855739  3.974211e-15
## scisectyes        1.06776064 0.13671012  7.810400  5.700698e-15
## log(capital72)    0.73209689 0.03247271 22.544986 1.503906e-112
## factor(year)1971 -0.05689712 0.03438207 -1.654849  9.795520e-02
## factor(year)1972 -0.09782062 0.03449879 -2.835480  4.575688e-03
## factor(year)1973 -0.12535010 0.03460348 -3.622471  2.918020e-04
## factor(year)1974 -0.08875079 0.03450160 -2.572367  1.010057e-02
## factor(year)1975 -0.15050043 0.03470525 -4.336532  1.447485e-05
## factor(year)1976 -0.17454466 0.03479798 -5.015942  5.277433e-07
## factor(year)1977 -0.17035784 0.03478965 -4.896797  9.741156e-07
## factor(year)1978 -0.24662675 0.03500450 -7.045573  1.846994e-12
## factor(year)1979 -0.31193611 0.03525991 -8.846763  9.009421e-19


採用實證資料,我們發現,如果要看係數顯著性,三個方法都一樣得出顯著的估計結果,但是,要看序列相關問題時,還是 glmmTMB 比較可靠,只是為什麼會估計出這麼大的序列相關係數,模擬的時候也不會出現這種狀況。這些問題,應該和套件預設序列相關模型和校正方式有關,因內容涉及過廣,值得持續追蹤。

接下來我們檢視預測表現,簡單使用RMSE。

  第一組:glmer修正前後的RMSE差異極大

sqrt(mean(sum(residuals(glmer_pois,"pearson")^2)))
## [1] 99.03911


RMSE.glmer=sqrt(mean(sum(residuals(glmer_pois_ar1,"pearson")^2)))
RMSE.glmer
## [1] 48.34259


  第二組:glmmPQL 修正前後的RMSE差異不大

sqrt(mean(sum(residuals(glmmPQL_pois)^2)))
## [1] 41.65341


RMSE.PQL=sqrt(mean(sum(residuals(glmmPQL_pois_ar1)^2)))
RMSE.PQL
## [1] 41.66176


  第三組:glmmTMB 修正前後的RMSE差異極大

sqrt(mean(sum(residuals(glmmTMB_pois,"pearson")^2)))
## [1] 99.03918


RMSE.TMB=sqrt(mean(sum(residuals(glmmTMB_pois_ar1,"pearson")^2)))
RMSE.TMB
## [1] 47.5929


依照上面看起來,MASS::glmmPQL預測表現略好,序列相關不修正即可。然而,套件演算法這部份還有待我們持續深入研究,釐清相關問題。







9.3.2.2 二元資料型


最後,我們看看二元資料。

UnionWage.tmp=read.csv("data/UnionWage.csv")
dat.mlm=UnionWage.tmp
dat.mlm$union=as.integer(as.factor(UnionWage.tmp$union))-1


執行一個沒有修正序列相關的glmer

library(lme4)
glmer.logit_RE <- glmer(union ~ (1|id) + wage + exper + rural , data=dat.mlm, family =binomial(link="logit"))


係數顯著性

coef(summary(glmer.logit_RE))
##                Estimate Std. Error     z value     Pr(>|z|)
## (Intercept) -3.56146283 0.31553439 -11.2870830 1.519977e-29
## wage         0.84099466 0.15672045   5.3662087 8.040888e-08
## exper       -0.06689668 0.02346379  -2.8510600 4.357375e-03
## ruralyes     0.12337240 0.23604472   0.5226654 6.012071e-01

接下來,承前作法,以三個方法修正二元序列相關。

  方法一:MASS::glmmPQL

corObj <- nlme:::Initialize(nlme:::corAR1(0.5, form = ~ 1|id), dat.mlm)
glmmPQL.logit_RE<- MASS::glmmPQL(union ~ 1 + wage + exper + rural,random = ~1|id,  data=dat.mlm, family =binomial(link="logit"),  correlation=corObj)


檢視結果

print(glmmPQL.logit_RE)
## Linear mixed-effects model fit by maximum likelihood
##   Data: dat.mlm 
##   Log-likelihood: NA
##   Fixed: union ~ 1 + wage + exper + rural 
## (Intercept)        wage       exper    ruralyes 
## -2.51085368  0.61653643 -0.04484464  0.08311492 
## 
## Random effects:
##  Formula: ~1 | id
##         (Intercept) Residual
## StdDev:    2.140628 0.726504
## 
## Correlation Structure: AR(1)
##  Formula: ~1 | id 
##  Parameter estimate(s):
##       Phi 
## 0.2342748 
## Variance function:
##  Structure: fixed weights
##  Formula: ~invwt 
## Number of Observations: 4360
## Number of Groups: 545


再來檢視殘差序列相關修正的效果:

dat.PQL.logit=data.frame(id=dat.mlm$id,year=dat.mlm$year, e=residuals(glmmPQL.logit_RE))
plm::plm(e~lag(e,1),data=dat.PQL.logit,index="id",model="random") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## (Intercept)   lag(e, 1) 
##    -0.33220     0.13923


係數顯著性

coef(summary(glmmPQL.logit_RE))
##                   Value  Std.Error   DF     t-value      p-value
## (Intercept) -2.51085368 0.20725830 3812 -12.1146109 3.570509e-33
## wage         0.61653643 0.10231100 3812   6.0261011 1.838948e-09
## exper       -0.04484464 0.01756933 3812  -2.5524379 1.073585e-02
## ruralyes     0.08311492 0.16596225 3812   0.5008062 6.165365e-01


  方法二:glmmTMB

library(glmmTMB)
dat.mlm$year=as.factor(dat.mlm$year)
glmmTMB.logit_RE <- glmmTMB(union ~ (1|id) + wage + exper + rural +  ar1(year-1|id), data=dat.mlm, family=betabinomial(link = "logit"))


檢視一般結果

print(glmmTMB.logit_RE)  
## Formula:          union ~ (1 | id) + wage + exper + rural + ar1(year - 1 | id)
## Data: dat.mlm
##       AIC       BIC    logLik  df.resid 
##  3026.620  3077.662 -1505.310      4352 
## Random-effects (co)variances:
## 
## Conditional model:
##  Groups Name        Std.Dev.  Corr      
##  id     (Intercept)  0.002612           
##  id.1   year1980    20.029965 0.75 (ar1)
## 
## Number of obs: 4360 / Conditional model: id, 545
## 
## Dispersion parameter for betabinomial family ():    1 
## 
## Fixed Effects:
## 
## Conditional model:
## (Intercept)         wage        exper     ruralyes  
##    -16.7066       3.5450      -0.1497       1.1555


dat.TMB.logit=data.frame(id=dat.mlm$id,year=dat.mlm$year, e=residuals(glmmTMB.logit_RE))
plm::plm(e~lag(e,1),data=dat.TMB.logit,index="id",model="random") #Residuals ar(1) check
## 
## Model Formula: e ~ lag(e, 1)
## 
## Coefficients:
## (Intercept)   lag(e, 1) 
##   0.0039666  -0.4691574


檢視係數顯著性

coef(summary(glmmTMB.logit_RE))$cond 
##               Estimate Std. Error   z value     Pr(>|z|)
## (Intercept) -16.706568  1.6963983 -9.848258 6.974231e-23
## wage          3.544969  0.7267367  4.877927 1.072063e-06
## exper        -0.149702  0.1132925 -1.321376 1.863761e-01
## ruralyes      1.155469  0.8271502  1.396927 1.624354e-01


  方法三:lme4ord

這個方法目前估計收斂失敗,所以我們方法三就不列比較。


承上,glmmPQL和glmmTMB的估計係數,有的差異很大,一個最終途徑就是比較預測表現:一個正確的模型參數,會產生較好的預測。

prob.glmer=predict(glmer.logit_RE, type="response")
prob.glmmPQL=predict(glmmPQL.logit_RE, type="response")
prob.glmmTMB=predict(glmmTMB.logit_RE, type="response")
predct.glmer=ifelse(prob.glmer>=0.5,1,0)
predct.PQL=ifelse(prob.glmmPQL>=0.5,1,0)
predct.TMB=ifelse(prob.glmmTMB>=0.5,1,0)


CF.glmer=table(predction=predct.glmer,actual=dat.mlm$union)
CF.PQL=table(predction=predct.PQL,actual=dat.mlm$union)
CF.TMB=table(predction=predct.TMB,actual=dat.mlm$union)


無修正序列相關的混淆矩陣。

caret::confusionMatrix(CF.glmer)
## Confusion Matrix and Statistics
## 
##          actual
## predction    0    1
##         0 3141  319
##         1  155  745
##                                           
##                Accuracy : 0.8913          
##                  95% CI : (0.8817, 0.9004)
##     No Information Rate : 0.756           
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6891          
##                                           
##  Mcnemar's Test P-Value : 7.055e-14       
##                                           
##             Sensitivity : 0.9530          
##             Specificity : 0.7002          
##          Pos Pred Value : 0.9078          
##          Neg Pred Value : 0.8278          
##              Prevalence : 0.7560          
##          Detection Rate : 0.7204          
##    Detection Prevalence : 0.7936          
##       Balanced Accuracy : 0.8266          
##                                           
##        'Positive' Class : 0               
## 


以glmmPQL架構,修正序列相關的混淆矩陣。

caret::confusionMatrix(CF.PQL)
## Confusion Matrix and Statistics
## 
##          actual
## predction    0    1
##         0 3143  317
##         1  153  747
##                                           
##                Accuracy : 0.8922          
##                  95% CI : (0.8826, 0.9013)
##     No Information Rate : 0.756           
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.6917          
##                                           
##  Mcnemar's Test P-Value : 5.535e-14       
##                                           
##             Sensitivity : 0.9536          
##             Specificity : 0.7021          
##          Pos Pred Value : 0.9084          
##          Neg Pred Value : 0.8300          
##              Prevalence : 0.7560          
##          Detection Rate : 0.7209          
##    Detection Prevalence : 0.7936          
##       Balanced Accuracy : 0.8278          
##                                           
##        'Positive' Class : 0               
## 


以glmmTMB架構,修正序列相關的混淆矩陣。

caret::confusionMatrix(CF.TMB)
## Confusion Matrix and Statistics
## 
##          actual
## predction    0    1
##         0 3296    0
##         1    0 1064
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9992, 1)
##     No Information Rate : 0.756      
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.000      
##             Specificity : 1.000      
##          Pos Pred Value : 1.000      
##          Neg Pred Value : 1.000      
##              Prevalence : 0.756      
##          Detection Rate : 0.756      
##    Detection Prevalence : 0.756      
##       Balanced Accuracy : 1.000      
##                                      
##        'Positive' Class : 0          
## 


由混淆矩陣的預測看起來,大致上而言,三個模型都可以使用,而且修不修正序列相關,對預測沒有太大的影響。

glmmTMQ 預測100%超級的好,看起來有 Over-fitting的嫌疑。


9.3.3 結論

panel data 涉及到類別資料時,有不少問題,畢竟在廣義線性模式下,它的核心就是非線性,不是線性,因此,對於AR(1)的問題。往往須要在細節上處理。筆者對此深感無力做出一個周延的結果,但是,依照研究目的看就可以。

首先。如果研究重心是係數符號和顯著性,則修不修正序列相關都要做,各種模型也都要做;透過各種模型產生的預測,比較一下兩者的差異與對估計的影響。如果只有預測差異,顯著性和符號都沒有問題,那意味各種處理方式,都不會改變參數的意義,給予一種穩健robust的結果。

其次。如果目的在預測,那就用預測誤差評估,然後,把樣本隨機分成「樣本內估計」和「樣本外預測」兩段,多抽樣幾次,比較預測表現。

目前為止,在經濟計量方法這面,理論上,categorical panel data 的計量理論偏難,漸進理論都須要嚴格的假設;另一方面,實證上,軟體的 pglm 也沒有給出完善的wrapper。在統計學這面,筆者發現要在 MLM 架構下,處理 categorical panel data 要妥善到定於一尊,也十分困難。MLE的收斂架構,也時有問題。這些問題,期待未來能有所突破。

References

Chamberlain, Gary. 1980. “Analysis of Covariance with Qualitative Data.” Review of Economic Studies 47 (1): 225–38. http://www.jstor.org/stable/2297110.
———. 2010. “Binary Response Models for Panel Data: Identification and Information.” Econometrica 78 (1): 159–68. http://www.jstor.org/stable/25621399.
Honoré, Bo E., and Ekaterini Kyriazidou. 2000. “Panel Data Discrete Choice Models with Lagged Dependent Variables.” Econometrica 68 (4): 839–74. http://www.jstor.org/stable/2999528.