fc2ブログ

RからPythonへの道(12)

 今回は「11. 回帰分析(リッジ、ラッソ回帰)」について、PythonとRで計算していきたいと思います。教材は今回も『東京大学のデータサイエンティスト育成講座』を参考にしました。リッジ回帰、ラッソ回帰は以下の式の第一項(目的変数と予測値の二乗誤差)に第二項(過学習を抑える正則項)を加えた値を最小にする分析手法で、q=1の時はラッソ回帰、q=2の時はリッジ回帰と呼びます。Mは変数の数、wは重み付け係数、λは「正則化パラメータ」です。Ridge_Lasso_Equation_200223.png まずは、Pythonのコードです。前半(38行目まで)は、以前の重回帰分析のコードをそのまま利用しており、ネット上のデータファイルをダウンロードし、前処理(欠損データの削除、説明変数選択)と相関係数を算出しました。後半部分でデータを半数ずつ学習データ・評価データに分けて、scikit-learnを使って重回帰、リッジ回帰、ラッソ回帰モデル作成と分析・予測を実施しました。
import requests, zipfile
import io
import numpy as np
import pandas as pd

#--------------------
# data preprocessing
#--------------------

# data file download
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data'
res = requests.get(url).content # bytes type data

# data read
auto = pd.read_csv(io.StringIO(res.decode('utf-8')),header=None)

# data label
auto.columns = ['symboling', 'normalized-losses', 'make', 'fuel-type', 'aspiration', 'num-of-doors', 'body-stype', 'drive-wheels', 'engine-location', 'wheel-base', 'length', 'width', 'height', 'curb-weight', 'engine-type', 'num-of-cylinders', 'engine-size', 'fuel-system', 'bore', 'stroke', 'compression-ratio', 'horsepower', 'peak-rpm', 'city-mpg', 'highway-mpg', 'price']
print('car data format:{}'.format(auto.shape))
print(auto.head())

# count ?-data
auto = auto[['price', 'horsepower', 'width', 'height']]
print(auto.isin(['?']).sum())

# replace ?-data with NaN and delete NaN
auto = auto.replace('?', np.nan).dropna()

# data type check
print('data type check(before)\n{}\n'.format(auto.dtypes))

# data type conversion
auto = auto.assign(price=pd.to_numeric(auto.price))
auto = auto.assign(horsepower=pd.to_numeric(auto.horsepower))
print('data type check(after)\n{}\n'.format(auto.dtypes))

# Correlation
print(auto.corr())

#------------------------------
# data modeling and evaluation
#------------------------------
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.linear_model import LassoCV
from sklearn.linear_model import RidgeCV

X = auto.drop('price',axis=1)
y = auto['price']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

# modeling
linear = LinearRegression()
lasso = Lasso(random_state=0)
ridge = Ridge(random_state=0)
lasso_cv = LassoCV(random_state=0)
ridge_cv = RidgeCV()

for model in [linear, lasso, ridge, lasso_cv, ridge_cv]:
model.fit(X_train, y_train)
print('{}(train):{:.6f}'.format(model.__class__.__name__, model.score(X_train, y_train)))
print('{}(test):{:.6f}'.format(model.__class__.__name__, model.score(X_test, y_test)))
print('{}(intercept):'.format(model.__class__.__name__), model.intercept_)
print('{}(slope):'.format(model.__class__.__name__), model.coef_)
 リッジ、ラッソ回帰を行う際は、クロスバリデーション(CV)を行い、前式の値が最小になるλを求めてモデリングするのが一般的ですが、書籍ではクロスバリデーションの記載がなかったので、追記しました。ただし、設定はデフォルトなので、正常に機能していないようです(ユーザの試行錯誤が必要?)。後ほどのRのコードではうまく計算してくれました。

 Pythonコードの実行結果は以下の通りです。前回の重回帰分析の結果部分は省略します。
LinearRegression(train):0.733358
LinearRegression(test):0.737069
LinearRegression(intercept): -128409.04630338575
LinearRegression(slope): [ 81.6510781 1829.17450553 229.51007731]

Lasso(train):0.733358
Lasso(test):0.737107
Lasso(intercept): -128383.27846080146
Lasso(slope): [ 81.66816264 1828.79749583 229.45963922]

Ridge(train):0.733355
Ridge(test):0.737768
Ridge(intercept): -127977.72972868057
Ridge(slope): [ 82.05219555 1820.23362733 231.67489868]

LassoCV(train):0.733108
LassoCV(test):0.742949
LassoCV(intercept): -123801.85160600257
LassoCV(slope): [ 84.37307241 1764.39408866 217.89863746]

RidgeCV(train):0.733100
RidgeCV(test):0.743506
RidgeCV(intercept): -124272.13077537864
RidgeCV(slope): [ 85.47424186 1743.93061057 249.69193454]
分かりにくいので、一覧表にすると以下の通り。Python_result_200223.pngCVをしていない重回帰(Linear)、ラッソ、リッジは違いがあまり分かりませんが、CVを行うとTestデータの決定係数が若干上がる結果でした。ただし、元のTrain/Testのデータ抽出のパターンが変わると結果も当然変わるので、分析モデルの最終判断はさらに精査する必要がありますね。

 次にRのコードです。Rのリッジ回帰、ラッソ回帰分析は、glmnetパッケージのglmnet関数を使って行いました。glmnet関数を使う時、パラメータalphaを0に指定するとリッジ回帰、1に指定するとラッソ回帰、0<α<1の時はリッジとラッソの混合形態である「Elastic Net」になります。前半(37行目まで)は、以前の重回帰分析のコードと同じです。
#--------------------
# data preprocessing
#--------------------

# data read
url = "http://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data"
auto = read.csv(url, header = FALSE)

# data label
colnames(auto) = c("symboling","normalized-losses","make","fuel-type","aspiration","num-of-doors","body-style","drive-wheels","engine-location","wheel-base","length","width","height","curb-weight","engine-type","num-of-cylinders","engine-size","fuel-system","bore","stroke","compression-ratio","horsepower","peak-rpm","city-mpg","highway-mpg","price")
dim(auto)
head(auto)

# count ?-data
auto = auto[, c("price","horsepower","width","height")]
length(auto$price[which(auto$price=="?")])
length(auto$horsepower[which(auto$horsepower=="?")])
length(auto$width[which(auto$width=="?")])
length(auto$height[which(auto$height=="?")])

# replace ?-data with NaN and delete NaN
# data type check(before)
sapply(auto, class)
auto$price[which(auto$price=="?")] = NA
auto$horsepower[which(auto$horsepower=="?")] = NA
auto$width[which(auto$width=="?")] = NA
auto$height[which(auto$height=="?")] = NA
auto = na.omit(auto)

# data type conversion
auto$price = as.numeric(as.character(auto$price))
auto$horsepower = as.numeric(as.character(auto$horsepower))
# data type check(after)
sapply(auto, class)

# Correlation
cor(auto)

#------------------------------
# data modeling and evaluation
#------------------------------
library(caret)
library(glmnet)

X = auto[, c("horsepower","width","height")]
y = auto[, c("price")]

set.seed(0)
inTrain <- createDataPartition(y, p = 0.5,list = F)
df_Train <- auto[inTrain,]
df_Test <- auto[-inTrain,]

# modeling (Multi-regression)
auto.lm<-train(price ~ horsepower + width + height, data = df_Train, method = 'lm')
print(summary(auto.lm))

# prediction
auto.pred = predict(auto.lm, newdata= df_Test)

# Coefficient of determination
# Train data
a = sum((df_Train$price - predict(auto.lm, newdata = df_Train))^2)
b = sum((df_Train$price - mean(df_Train$price))^2)
print(paste("Multi-Regression(train): ", 1 - a/b))

# Test data
a = sum((df_Test$price - predict(auto.lm, newdata = df_Test))^2)
b = sum((df_Test$price - mean(df_Test$price))^2)
print(paste("Multi-Regression(test): ", 1 - a/b))

#--------------------------
# Ridge & Lasso Regression
#--------------------------
xx = as.matrix(df_Train[,2:4])
yy = as.matrix(df_Train[,1])
xx1 = as.matrix(df_Test[,2:4])
yy1 = as.matrix(df_Test[,1])

# Ridge Regression
Ridge.fit = glmnet(x=xx, y=yy, family = "gaussian", alpha = 0)
plot(Ridge.fit, xvar = "lambda", label=TRUE)

Ridge.fit.CV1 = cv.glmnet(x=xx, y=yy, family="gaussian", alpha=0) # cross validation
plot(Ridge.fit.CV1)

print(paste("lambda Min: ", Ridge.fit.CV1$lambda.min, "log lambda Min: ", log(Ridge.fit.CV1$lambda.min)))
abline(v=log(Ridge.fit.CV1$lambda.min),lty=3)
print(coef(Ridge.fit.CV1, s="lambda.min"))

# Coefficient of determination
# Train data
Ridge.fit.CV1.train = predict(Ridge.fit.CV1, s="lambda.min", newx = xx)
a = sum((yy- Ridge.fit.CV1.train)^2)
b = sum((yy - mean(yy))^2)
print(paste("Ridge-Regression(train): ", 1 - a/b))

# Test data
Ridge.fit.CV1.pred = predict(Ridge.fit.CV1, s="lambda.min", newx = xx1)
a = sum((yy1 - Ridge.fit.CV1.pred)^2)
b = sum((yy1 - mean(yy1))^2)
print(paste("Ridge-Regression(test): ", 1 - a/b))

# Lasso Regression
Lasso.fit = glmnet(x=xx, y=yy, family = "gaussian", alpha = 1)
plot(Lasso.fit, xvar = "lambda", label=TRUE)

Lasso.fit.CV1 = cv.glmnet(x=xx, y=yy, family="gaussian", alpha=1) # cross validation
plot(Lasso.fit.CV1)

print(paste("lambda Min: ", Lasso.fit.CV1$lambda.min, "log lambda Min: ", log(Lasso.fit.CV1$lambda.min)))
abline(v=log(Lasso.fit.CV1$lambda.min),lty=3)
print(coef(Lasso.fit.CV1, s="lambda.min"))

# Coefficient of determination
# Train data
Lasso.fit.CV1.train = predict(Lasso.fit.CV1, s="lambda.min", newx = xx)
a = sum((yy- Lasso.fit.CV1.train)^2)
b = sum((yy - mean(yy))^2)
print(paste("Lasso-Regression(train): ", 1 - a/b))

# Test data
Lasso.fit.CV1.pred = predict(Lasso.fit.CV1, s="lambda.min", newx = xx1)
a = sum((yy1 - Lasso.fit.CV1.pred)^2)
b = sum((yy1 - mean(yy1))^2)
print(paste("Lasso-Regression(test): ", 1 - a/b))
 Rの結果は以下の通りです。リッジ、ラッソについてはCVを行い、誤差を最小化するλと回帰係数を求めました。
Call:
lm(formula = .outcome ~ ., data = dat)

Residuals:
Min 1Q Median 3Q Max
-6772 -2542 -220 1686 15489

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -119751.97 16976.10 -7.054 2.58e-10 ***
horsepower 116.34 15.69 7.417 4.56e-11 ***
width 1705.94 303.95 5.613 1.89e-07 ***
height 159.60 186.17 0.857 0.393
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4077 on 97 degrees of freedom
Multiple R-squared: 0.7541, Adjusted R-squared: 0.7465
F-statistic: 99.17 on 3 and 97 DF, p-value: < 2.2e-16

[1] "Multi-Regression(train): 0.75411846216974"
[1] "Multi-Regression(test): 0.771159651819088"


[1] "lambda Min: 643.869960222362 log lambda Min: 6.46749678059418"
4 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -115873.9444
horsepower 109.5919
width 1650.6246
height 168.2076
[1] "Ridge-Regression(train): 0.752515077280814"
[1] "Ridge-Regression(test): 0.773514153053235"


[1] "lambda Min: 35.1699620177062 log lambda Min: 3.56019236652245"
4 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -118887.4435
horsepower 115.4275
width 1705.2886
height 146.0971
[1] "Lasso-Regression(train): 0.754082093937949"
[1] "Lasso-Regression(test): 0.771449632230262"
これも分かりにくいので一覧表にすると以下の通り。R_result_200223.png学習に使っているデータがPythonとRとで全く同じでないので、比較はできませんが、Rには以下の通り、λを変化させた時の解パス図や平均二乗誤差(MSE:Mean Squared Error)のプロットも簡単に出力できます。これは便利です。Pythonにもこのような機能があるのか否かは調べられていません・・。Ridgeの解パス図、MSEプロットは以下の通り。Ridge1_200223.pngRidge2_200223.pngLassoの解パス図、MSEプロットは以下の通り。Lasso1_200223.pngLasso2_200223.png 今回、リッジ、ラッソ回帰を初めて触ってみました。十分理解できていない部分は他のデータセットを利用して再度トライしてみようと思います。

『RからPythonへの道』バックナンバー
(1) はじめに
(2) 0. 実行環境(作業環境)
(3) 1. PythonからRを使う方法 2. RからPythonを使う方法
(4) 3. データフレーム
(5) 4. ggplot
(6) 5.行列
(7) 6.基本統計量
(8) 7. 回帰分析(単回帰)
(9) 8. 回帰分析(重回帰)
(10) 9. 回帰分析(ロジスティック回帰1)
(11) 10. 回帰分析(ロジスティック回帰2)
スポンサーサイト



RからPythonへの道(11)

 今回も前回に引き続き「10. 回帰分析(ロジスティック回帰2)」について、PythonとRで計算していきたいと思います。教材は『東京大学のデータサイエンティスト育成講座』を参考にしました。分析に用いるデータセットの中から参考書籍の通り、
 age(年齢)
 fnlwgt(final weight? 最終体重?)
 education-num(教育年数)
 capital-gain(資産益)
 capital-loss(資産損)
の個人データの5つの説明変数を用いて、その人の収入が50k(5万)ドルを超えるか否か(目的変数: 0 or 1)を予測しました。モデルの説明変数が5個あるので、以下の式で表されます。LogisticRegressionEquation.png まずは、Pythonのコードです。コードは前半で前処理(ネット上のデータファイルをダウンロード、欠損データ確認、目的変数(カテゴリ変数)の数値化)を行い、後半でデータを半数ずつ学習データ・評価データに分けて、scikit-learnを使ってロジスティック回帰モデル作成と分析・予測を実施しました。回帰係数、オッズ比、クロス集計と正解率を求めました。
# Logistic-regression
import requests,zipfile
import io
import pandas as pd
import numpy as np

#--------------------
# data preprocessing
#--------------------

# data load
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data'
res = requests.get(url).content
adult = pd.read_csv(io.StringIO(res.decode('utf-8')),header=None)
print(adult.head())

# data label
adult.columns = ['age', 'workclass', 'fnlwgt', 'education', 'education-num', 'material-status', 'occupation', 'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week', 'native-country', 'flg-50K']
print('data style:{}'.format(adult.shape))
print('number of lack data:{}'.format(adult.isnull().sum().sum()))
print(adult.head())

print(adult.groupby('flg-50K').size())
adult['fin_flg']=adult['flg-50K'].map(lambda x: 1 if x == ' >50K' else 0)
print(adult.groupby('fin_flg').size())

#------------------------------
# data modeling and evaluation
#------------------------------
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

X = adult[['age', 'fnlwgt', 'education-num', 'capital-gain', 'capital-loss']]
y = adult['fin_flg']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

# modeling
model = LogisticRegression()
model.fit(X_train, y_train)

# evaluation
# coefficients of regression
print('Coefficients of regression')
print(model.coef_)
print('Intercept')
print(model.intercept_)
print('Odds ratio')
print(np.exp(model.coef_))

print(pd.crosstab(y_train, model.predict(X_train),rownames=['fin'], colnames=['train']))
print('Accuracy rate(train):{:.3f}'.format(model.score(X_train, y_train)))

print(pd.crosstab(y_test, model.predict(X_test),rownames=['fin'], colnames=['pred']))
print('Accuracy rate(test) :{:.3f}'.format(model.score(X_test, y_test)))
 Pythonコードの出力結果は以下の通りです。

# 15行目(列項目名なし)
0 1 2 3 4 5 ... 9 10 11 12 13 14
0 39 State-gov 77516 Bachelors 13 Never-married ... Male 2174 0 40 United-States <=50K
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse ... Male 0 0 13 United-States <=50K
2 38 Private 215646 HS-grad 9 Divorced ... Male 0 0 40 United-States <=50K
3 53 Private 234721 11th 7 Married-civ-spouse ... Male 0 0 40 United-States <=50K
4 28 Private 338409 Bachelors 13 Married-civ-spouse ... Female 0 0 40 Cuba <=50K

[5 rows x 15 columns]


# 19−20行目(データサイズ、欠損数)
data style:(32561, 15)
number of lack data:0


# 21行目(列項目名入力)
age workclass fnlwgt education education-num ... capital-gain capital-loss hours-per-week native-country flg-50K
0 39 State-gov 77516 Bachelors 13 ... 2174 0 40 United-States <=50K
1 50 Self-emp-not-inc 83311 Bachelors 13 ... 0 0 13 United-States <=50K
2 38 Private 215646 HS-grad 9 ... 0 0 40 United-States <=50K
3 53 Private 234721 11th 7 ... 0 0 40 United-States <=50K
4 28 Private 338409 Bachelors 13 ... 0 0 40 Cuba <=50K

[5 rows x 15 columns]


# 23行目(要素が「<=50K」と「>50K」の2種類)
flg-50K
<=50K 24720
>50K 7841
dtype: int64


# 25行目(要素を数値「0」と「1」に変換後)
fin_flg
0 24720
1 7841
dtype: int64


# 44-49行目(回帰係数、傾き、オッズ比)
Coefficients of regression
[[-1.18545968e-02 -4.37932054e-06 -2.77432658e-03 3.27384955e-04
7.53237842e-04]]
Intercept
[-0.00058136]
Odds ratio
[[0.98821539 0.99999562 0.99722952 1.00032744 1.00075352]]


# 51ー55行目(クロス集計と正解率ーTrain数:16280、Test数:16281)
train 0 1
fin
0 12002 395
1 2908 975
Accuracy rate(train):0.797

pred 0 1
fin
0 11937 386
1 2903 1055
Accuracy rate(test) :0.798

 次にRのコードです。
# Logistic-regression

#--------------------
# data preprocessing
#--------------------

# data read
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data'
adult = read.csv(url, header = FALSE)
print(head(adult))

# data label
colnames(adult) = c('age', 'workclass', 'fnlwgt', 'education', 'education.num', 'material.status', 'occupation', 'relationship', 'race', 'sex', 'capital.gain', 'capital.loss', 'hours.per.week', 'native.country', 'flg.50K')
print(paste("data style: ", dim(adult)[1], ",", dim(adult)[2]))
print(paste("number of lack data: ", sum(is.na(adult))))
print(head(adult))

print(table(adult$'flg.50K'))
print(class(adult$'flg.50K'))
fin_flg = as.numeric(adult$'flg.50K') - 1
print(fin_flg)
adult=transform(adult, fin_flg = fin_flg)
print(table(adult$fin_flg))

#------------------------------
# data modeling and evaluation
#------------------------------
library(caret)

X = adult[,c('age', 'fnlwgt', 'education.num', 'capital.gain', 'capital.loss')]
y = adult[,c('fin_flg')]
df = cbind(X, y)
colnames(df) = c('age', 'fnlwgt', 'education.num', 'capital.gain', 'capital.loss', 'fin_flg')

set.seed(0)
inTrain = createDataPartition(y, p = 0.5,list = F)
df_Train = df[inTrain,]
df_Test = df[-inTrain,]

# modeling
adult.glm = train(fin_flg ~ age + fnlwgt + education.num + capital.gain + capital.loss, data = df_Train, method = "glm", family = binomial())

# evaluation
print(summary(adult.glm))
print(adult.glm$finalModel$coefficients[2:6])
print(paste("Odds ratio: ",exp(adult.glm$finalModel$coefficients[2:6]))) # odds ratio

# prediction
adult.pred = predict(adult.glm, newdata= df_Test)

# for comparison (Training data)
adult.train = predict(adult.glm, newdata= df_Train)

tb_train = table(fin=df_Train$fin_flg, train=round(adult.train))
print(tb_train)
print(paste("Accuracy rate(train): ", sum(diag(tb_train))/sum(tb_train)))

tb_pred = table(fin=df_Test$fin_flg, pred=round(adult.pred))
print(tb_pred)
print(paste("Accuracy rate(test) : ",sum(diag(tb_pred))/sum(tb_pred)))
 Rの結果は以下の通りです。

# 10行目(列項目名なし)
V1 V2 V3 V4 V5 V6
1 39 State-gov 77516 Bachelors 13 Never-married
2 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse
3 38 Private 215646 HS-grad 9 Divorced
4 53 Private 234721 11th 7 Married-civ-spouse
5 28 Private 338409 Bachelors 13 Married-civ-spouse
6 37 Private 284582 Masters 14 Married-civ-spouse
V7 V8 V9 V10 V11 V12 V13
1 Adm-clerical Not-in-family White Male 2174 0 40
2 Exec-managerial Husband White Male 0 0 13
3 Handlers-cleaners Not-in-family White Male 0 0 40
4 Handlers-cleaners Husband Black Male 0 0 40
5 Prof-specialty Wife Black Female 0 0 40
6 Exec-managerial Wife White Female 0 0 40
V14 V15
1 United-States <=50K
2 United-States <=50K
3 United-States <=50K
4 United-States <=50K
5 Cuba <=50K
6 United-States <=50K


# 14−15行目(データサイズ、欠損数)
[1] "data style: 32561 , 15"
[1] "number of lack data: 0"


# 16行目(列項目名入力後)
age workclass fnlwgt education education.num material.status
1 39 State-gov 77516 Bachelors 13 Never-married
2 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse
3 38 Private 215646 HS-grad 9 Divorced
4 53 Private 234721 11th 7 Married-civ-spouse
5 28 Private 338409 Bachelors 13 Married-civ-spouse
6 37 Private 284582 Masters 14 Married-civ-spouse
occupation relationship race sex capital.gain capital.loss
1 Adm-clerical Not-in-family White Male 2174 0
2 Exec-managerial Husband White Male 0 0
3 Handlers-cleaners Not-in-family White Male 0 0
4 Handlers-cleaners Husband Black Male 0 0
5 Prof-specialty Wife Black Female 0 0
6 Exec-managerial Wife White Female 0 0
hours.per.week native.country flg.50K
1 40 United-States <=50K
2 13 United-States <=50K
3 40 United-States <=50K
4 40 United-States <=50K
5 40 Cuba <=50K
6 40 United-States <=50K


# 18行目(要素が「<=50K」と「>50K」の2種類)
<=50K >50K
24720 7841


# 19行目(「flg.50K」列の型確認)
[1] "factor"


# 20-23行目(要素を数値「0」と「1」に変換、データ確認)
[1] 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0
[36] 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0
 ・・(略)・・
[946] 0 0 1 0 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 0 0
[981] 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
[ reached getOption("max.print") -- omitted 31561 entries ]

0 1
24720 7841


# 44行目(回帰係数)

Call:
NULL

Deviance Residuals:
Min 1Q Median 3Q Max
-5.3259 -0.6569 -0.4322 -0.1784 2.9836

Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -6.759e+00 1.400e-01 -48.286 < 2e-16 ***
age 4.068e-02 1.630e-03 24.953 < 2e-16 ***
fnlwgt 6.322e-07 2.050e-07 3.083 0.00205 **
education.num 3.355e-01 9.564e-03 35.084 < 2e-16 ***
capital.gain 3.267e-04 1.353e-05 24.157 < 2e-16 ***
capital.loss 7.612e-04 4.493e-05 16.943 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

Null deviance: 17941 on 16280 degrees of freedom
Residual deviance: 13680 on 16275 degrees of freedom
AIC: 13692

Number of Fisher Scoring iterations: 7


# 45行目(傾き)
age fnlwgt education.num capital.gain capital.loss
4.067699e-02 6.322373e-07 3.355424e-01 3.267485e-04 7.612493e-04


# 46行目(オッズ比)
[1] "Odds ratio: 1.04151562922535" "Odds ratio: 1.0000006322375"
[3] "Odds ratio: 1.39869886200281" "Odds ratio: 1.00032680190891"
[5] "Odds ratio: 1.00076153913444"


# 54-60行目(クロス集計と正解率ーTrain数:16281、Test数:16280)
train
fin 0 1
0 11837 538
1 2507 1399
[1] "Accuracy rate(train): 0.812972176156256"

pred
fin 0 1
0 11754 591
1 2523 1412
[1] "Accuracy rate(test) : 0.808722358722359"
 Python、Rの結果と比較しながら見ていきます。前半の前処理は双方ほぼ同じです。
 後半の分析では、全く同じデータを学習に使っていないので、回帰係数、傾きは双方で異なりました。オッズ比を計算していますが、ある事象の起こる確率をpとして、p/(1−p) の値をオッズといい、異なる2つのデータ群のオッズの比を「オッズ比」といいます。各説明変数が1変化した場合を考えると、オッズ比は各回帰係数のexpを取った値です。プログラムでもこの計算を行いました。オッズ比の結果が1近傍なので、対象とする条件あるいは事象の起こりやすさが両群で同じであることが分かります。
 最後に、Train/Test時の双方について、正解率をクロス集計表を用いて計算しました。(予想, 実際)の組み合わせは、(0,0)、(0,1)、(1,0)、(1,1)の4ケースありますが、正解率は、予想と実際が同じケース(0,0)と(1,1)の数の和を全4ケースの数の和で割った値です。PythonとRで比較すると、正解率はほぼ同じ値になりました。

 ロジスティック回帰を2回に分けてお話しました。何か実務で使えるシチュエーションがあれば、今回の勉強を役に立てたいと思います。

『RからPythonへの道』バックナンバー
(1) はじめに
(2) 0. 実行環境(作業環境)
(3) 1. PythonからRを使う方法 2. RからPythonを使う方法
(4) 3. データフレーム
(5) 4. ggplot
(6) 5.行列
(7) 6.基本統計量
(8) 7. 回帰分析(単回帰)
(9) 8. 回帰分析(重回帰)
(10) 9. 回帰分析(ロジスティック回帰1)

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: