R Linear Regression (線形回帰) (2) 予測モデルの作成と評価

分析の題材はこのデータ:

#SPC:Sales per customer,顧客単価(JPY)
#OpenH:Hours open,営業時間
#NOHWT:Number of households within trade area,商圏内世帯数(世帯)
#NOPWT:Number of people with in trade area,商圏内人口(人)
#IPH:Income per households within trade area,商圏内世帯の平均世帯年収(JPY)
#PPT:Profit per Tubo,坪当たり営業利益(JPY)
#線形回帰で、顧客単価を予測するモデルを作成することが目標

 

SPC OpenH NOHWT NOPWT IPH PPT
32512 8.5 6211 17360 3200000 10125
40122 9 6256 16891 5920000 13574
39213 9 6787 18865 3000000 18215
41211 8.5 6982 18852 5200000 18325
50211 10 4521 12207 5700000 15331
38122 8.5 6781 18309 4920000 15215
37543 11 7325 19778 5220000 17211
34511 8.5 6211 16700 3280000 9253
35223 11 6521 16878 4220000 18222
34322 8.5 5251 14178 3250000 16252
35871 8.5 5293 10292 3000000 10321
36921 8.5 5621 14177 3010000 13221
36211 10 6221 16797 3210000 17522
34841 8.5 5822 13719 3720000 13376
42355 10 6351 17148 4970000 14389
34211 8.5 5651 14296 4660000 13921
36662 9 5721 13447 4750000 15265
42121 8.5 5825 15726 5350000 10321
43212 9 5651 15258 6360000 14796
36672 8.5 5723 15452 3000000 15223
35213 10 5992 16178 5350000 16351
30102 8.5 5825 15728 3250000 13543
38218 8.5 6311 17067 4990000 15531
38225 9 6321 17040 5370000 14762
33421 8.5 6251 16888 3580000 13251
35611 9 5321 18367 4330000 15767
36213 8.5 5651 15367 4790000 12226
37322 10 7321 19767 4820000 17251
36276 10 5632 15206 4820000 14378
45321 8 5571 15042 4920000 12765
30221 8.5 5221 13997 4520000 11311
36337 11 6921 15987 5220000 15225
36452 8.5 6973 18730 4220000 15217
38628 9 5323 15372 4970000 15665

 

#########1.データの取り込み,整形#########
raw <- read.csv("4_Linear Regression.csv") #上記データ
head(raw)

#ヒストグラム
par(mfrow=c(6,1),mar=c(0,3,3,0),ps=10) #レイアウト調整
for (i in 1:ncol(raw)) {
  #ヒストグラムの数が増えると余白の調整が必要。Zoomしてみると良い
  hist(raw[,i],main=names(raw[i]))
}

#欠損値の確認
sum(is.na(raw))

#全て量的変数の場合はplotで傾向を把握
plot(raw) 

#k-meansでplotも可能。クラスター分析の演習参照
par(mfrow=c(1,1),mar=c(3,3,3,3)) #レイアウト調整
cl <- kmeans(scale(raw), 3, 20) #時間があればWSSのグラフも描いてみて下さい。(各自コーディング)
plot(raw, col = cl$cluster)
points(cl$centers, col = 1:3, pch = 8)

#相関係数
cor(raw)

#########2.顧客単価を目的変数として線形回帰#########
lm_a <- lm(SPC~.,data=raw)
summary(lm_a)

#(a)説明変数の選択
lm_b <- step(lm_a) #AICに基づいた変数選択法(デフォルトはbackward)
#変数選択の観点は複数あり、吟味が必要。ここではとりあえずAICを選択。 summary(lm_b) #(b)モデルの評価 #(b-1):残差分析 par(mfrow=c(2,2),mar=c(4,4,4,4),ps=15) plot(lm_b) #残差分析。外れ値の行番号が表示される #外れ値を外して再度回帰分析 raw_rv <- raw[-5,] lm_c <- step(lm(SPC~.,data=raw_rv)) summary(lm_c) plot(lm_c) #残差分析 #Residuals vs Fitted values:SPC:目的変数値に応じた残差の値を縦軸に表示。 #NormalQ-Q:観測値の標準化後残差が正規分布に従う場合の期待値をx軸、 #観測値の標準化後残差をy軸にとったプロット。 #Scale-Location:Residual vs Fitted valuesのy軸について平方根をとったもの。 #Residuals vs Leverage:Leverage(てこ比)とは回帰分析の観察点(サンプル)毎に #説明変数のデータを変えずに目的変数yの値を1だけ変えたときの予測値の変化量 #cook's distanceは検証用に使われる距離 #stepの結果単回帰直線となったので、図示 par(mfrow=c(1,1),mar=c(5,5,5,5)) plot(raw[,1]~raw[,5],data=raw_rv,xlab="商圏内世帯の平均世帯年収(JPY)", ylab="顧客単価(JPY)",main="顧客単価の回帰分析", xlim=c(2800000,6500000),ylim=c(25000,55000)) abline(lm_c) par(new=T)

#(b-2):95%信頼区間 (回帰直線の存在領域) lm_con <- predict(lm_c,interval="confidence") #図示出来るように昇順並び替え con_lwr <- data.frame(raw_rv[,5],lm_con[,2]) con_lwr <- con_lwr[order(con_lwr[,1]),] con_upr <- data.frame(raw_rv[,5],lm_con[,3]) con_upr <- con_upr[order(con_upr[,1]),] par(ps=20) #フォント調整 lines(con_lwr,type="l",xlim=c(2800000,6500000),ylim=c(25000,55000),ylab="",xlab="",col="blue",lty=1) par(new=T) lines(con_upr,type="l",xlim=c(2800000,6500000),ylim=c(25000,55000),ylab="",xlab="",col="blue",lty=1) par(new=T) #(b-3):95%予測区間 (予測値の存在領域) lm_prd <- predict(lm_c,interval="prediction") lm_con <- predict(lm_c,interval="confidence") prd_lwr <- data.frame(raw_rv[,5],lm_prd[,2]) prd_lwr <- prd_lwr[order(prd_lwr[,1]),] prd_upr <- data.frame(raw_rv[,5],lm_prd[,3]) prd_upr <- prd_upr[order(prd_upr[,1]),] lines(prd_lwr,type="l",xlim=c(2800000,6500000),ylim=c(25000,55000),ylab="",xlab="",col="red",lty=1) par(new=T) lines(prd_upr,type="l",xlim=c(2800000,6500000),ylim=c(25000,55000),ylab="",xlab="",col="red",lty=1) par(new=T) par(ps=10) #フォント調整 legend("topleft",legend=c("95%信頼区間","95%予測区間"),col=c("blue","red"),lty=c(1))

f:id:nakhirot:20130630174227p:plain

#########[Additional]3.ブートストラップ法の利用#########
intr <- numeric(10000) coef <- numeric(10000) for(i in 1:10000){ trainNO <- sample(nrow(raw),nrow(raw)*0.67,replace=TRUE) #replace=TRUE:非復元一様分布からの抽出 train_dat <- raw[trainNO,] res <- lm(train_dat[,1]~train_dat[,5]) #train_datで回帰分析 intr[i] <- res$coefficients[1] # 定数項の取り出し coef[i] <- res$coefficients[2] # 係数の取り出し } par(mar=c(3,3,3,3),mfrow=c(1, 2)) #余白幅の調整,グラフ画面の分割 hist(intr) #定数項のヒストグラム #95%の信頼区間の境界値を書き加える abline(v=quantile(intr, c(0.025, 0.975)), col="red") hist(coef) #係数のヒストグラム #95%の信頼区間の境界値を書く abline(v=quantile(coef, c(0.025, 0.975)), col="red")

f:id:nakhirot:20130630174404p:plain

#########[Additional]4.主成分分析#########
raw_s <- scale(raw) #データの標準化 cor(raw_s) #相関行列 PC <- princomp(raw_s) #主成分分析 summary(PC) attributes(PC) PC$loadings #第1,2主成分でプロット(69%を説明) par(mfrow=c(1, 1)) par(ps=15,mar=c(5,3,3,3)) plot (data.matrix(raw_s) %*% unclass(loadings(PC))[,c(1,2)]) biplot(PC)

f:id:nakhirot:20130630174507p:plain