fc2ブログ

RからPythonへの道(10)

 前回の重回帰分析に続き、今回は「9. 回帰分析(ロジスティック回帰1)」について、RとPythonで計算して行きたいと思います。今回は書籍『Rによるデータマイニング入門』を教材に利用しました。 ロジスティック回帰は非線形回帰の一つで以下の式で表されます。R_LogisticRegressionEquation_200126_.pngデータはUCI Machine Learning RepositoryからSpambaseデータをダウンロードして使いました。メールの特徴からスパムメールか否かの二値判断をするものです。

 まずは、Rのコードです。データをプロットして比較のための単回帰分析を行い、フィッティングの悪いことを確認した上で、ロジスティック回帰を行います。
# Logistic Regression
library(ggplot2)
library(dplyr)

# datafile download
DLfile = tempfile()
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/spambase/spambase.zip"
download.file(url, DLfile)
unzip(DLfile)

# data read
spambase = read.csv("spambase.data", header = FALSE)
colnames(spambase) = read.table("spambase.names", skip = 33, sep=":", comment.char = "")[,1]
colnames(spambase)[ncol(spambase)]="spam"
dim(spambase)

# basic statistics
spambase %>% group_by(spam) %>% summarise(count=n(), med=median(word_freq_your), mean=mean(word_freq_your), sd=sd(word_freq_your))

# graph plot(Raw data)
qplot(word_freq_your, spam, data=spambase, alpha=I(0.03))

# single regression
spam.your.lm = lm(spam~word_freq_your, data=spambase)
summary(spam.your.lm)
qplot(word_freq_your, spam, data = spambase, alpha=I(0.03), xlim = c(0, 10), ylim = c(0,1.5))+geom_smooth(method = "lm")

# logistic regression
spam.your.lst = glm(spam~word_freq_your, data=spambase, family="binomial")
summary(spam.your.lst)

a = coef(spam.your.lst)[2]
b = coef(spam.your.lst)[1]
lst.fun=function(x){
1/(1+exp(-(a*x+b)))
}
qplot(word_freq_your, spam, data = spambase, alpha=I(0.03), xlim = c(-5, 15))+stat_function(fun = lst.fun, geom="line",color="blue")
生データのみ、単回帰フィッティング、ロジスティック回帰フィッティングのグラフは以下の通りです。R_RawDataPlot_200126.pngR_SingleRegressionPlot_200126.pngR_LogisticRegressionPlot_200126.pngまた、数値出力結果は以下の通りです。
> dim(spambase)
[1] 4601 58
>
> # basic statistics
> spambase %>% group_by(spam) %>% summarise(count=n(), med=median(word_freq_your), mean=mean(word_freq_your), sd=sd(word_freq_your))
# A tibble: 2 x 5
spam count med mean sd
<int> <int> <dbl> <dbl> <dbl>
1 0 2788 0 0.439 1.03
2 1 1813 1.19 1.38 1.23

> # single regression
> summary(spam.your.lm)

Call:
lm(formula = spam ~ word_freq_your, data = spambase)

Residuals:
Min 1Q Median 3Q Max
-1.9382 -0.2677 -0.2677 0.4999 0.7322

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.267750 0.008027 33.35 <2e-16 ***
word_freq_your 0.155966 0.005543 28.14 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4514 on 4599 degrees of freedom
Multiple R-squared: 0.1469, Adjusted R-squared: 0.1467
F-statistic: 791.7 on 1 and 4599 DF, p-value: < 2.2e-16

> # logistic regression
> summary(spam.your.lst)

Call:
glm(formula = spam ~ word_freq_your, family = "binomial", data = spambase)

Deviance Residuals:
Min 1Q Median 3Q Max
-4.0211 -0.7549 -0.7549 1.1064 1.6701

Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.10971 0.04235 -26.20 <2e-16 ***
word_freq_your 0.85845 0.03682 23.32 <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: 6170.2 on 4600 degrees of freedom
Residual deviance: 5407.3 on 4599 degrees of freedom
AIC: 5411.3

Number of Fisher Scoring iterations: 4
単回帰分析の調整済み決定係数が0.1467でフィッティングが良くないことが分かります。

 次に、Pythonのコードです。
# Logistic Regression

import requests, zipfile
from io import StringIO
import io
import pandas as pd
from sklearn import linear_model
import matplotlib.pyplot as plt
import numpy as np
import math

# data file download
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/spambase/spambase.zip'
r = requests.get(url, stream = True)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall()

# data read
spambase = pd.read_csv("spambase.data", header=None)
spambase_colnames = []
line_temp = []
with open("spambase.names","r") as f:
line_temp = f.readlines()
for i in range(33,len(line_temp)):
spambase_colnames.append(line_temp[i].split(':')[0])

spambase_colnames.append("spam")
spambase.columns = spambase_colnames
print(spambase.shape)

# basic statistics
print("count")
print(spambase.groupby('spam')['word_freq_your'].count())
print("median")
print(spambase.groupby('spam')['word_freq_your'].median())
print("mean")
print(spambase.groupby('spam')['word_freq_your'].mean())
print("std")
print(spambase.groupby('spam')['word_freq_your'].std())

# data plot
X = spambase.loc[:,['word_freq_your']].values
Y = spambase.loc[:,['spam']].values
plt.scatter(X, Y, alpha=0.03)
plt.show()

# Linear Regression (for comparison)
reg = linear_model.LinearRegression()
reg.fit(X, Y)

print('Slope: ', reg.coef_)
print('Intercept:', reg.intercept_)
print('Coefficient of determination: ',reg.score(X, Y))

plt.xlim(0.0, 10.0)
plt.ylim(0.00, 1.50)
plt.scatter(X, Y, alpha=0.03)
plt.xlabel('word_freq_your')
plt.ylabel('spam')
plt.plot(X, reg.predict(X), color= 'red') # fitting line
plt.show()

# Logistic Regression
reg1 = linear_model.LogisticRegression()
reg1.fit(X, Y)

print('Slope: ', reg1.coef_)
print('Intercept:', reg1.intercept_)

a = float(reg1.coef_)
b = float(reg1.intercept_)

def LogisticRegressionPredict(x):
return 1.0 /(1 + math.exp(-(a*x+b)))

XX = np.linspace(-5, 15,1001)
YY = np.array([LogisticRegressionPredict(i) for i in XX])

plt.xlim(-5.0, 15.0)
plt.ylim(0.00, 1.00)
plt.scatter(X, Y, alpha=0.03)
plt.xlabel('word_freq_your')
plt.ylabel('spam')
plt.plot(XX, YY, linestyle = 'None', marker=".", color= 'red') # fitting line
plt.show()
生データのみ、単回帰フィッティング、ロジスティック回帰フィッティングのグラフは以下の通りです。当然ですが、Rの結果と同じグラフが得られました。Python_RawdataPlot_200126.pngPython_SingleRegressionPlot_200126.pngPython_LogisticRegressionPlot_200126.pngまた、数値出力結果は以下の通りです。
#data size
(4601, 58)
count
spam
0 2788
1 1813
Name: word_freq_your, dtype: int64
median
spam
0 0.00
1 1.19
Name: word_freq_your, dtype: float64
mean
spam
0 0.438702
1 1.380370
Name: word_freq_your, dtype: float64
std
spam
0 1.025167
1 1.227385
Name: word_freq_your, dtype: float64

# Linear Regression (for comparison) 
Slope: [[0.15596597]]
Intercept: [0.26774962]
Coefficient of determination: 0.14686816024270333

# Logistic Regression
Slope: [[0.85729313]]
Intercept: [-1.10887145]
これも、Rの結果と同じです。ロジスティック回帰は今まで使ったことがなかったので、大変勉強になりました。RでもPythonでもやり方を理解すればすぐにでも使えそうですね。

『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. 回帰分析(重回帰)

スポンサーサイト



Mac、UbuntuのDocker環境でMySQLを使う

 最近のブログネタはまとまりがなく転々としています。新しいことや昔やったことをもう一度、等々。今回はDockerネタです。2年ほど前にWindows10 HomeでDocker Toolboxを使ってUbuntuを利用したり、magentaでAI作曲の遊びをしたのを思い出します。今回はまたいつもの?ふとした思いつきでMac、UbuntuにDocker環境を作って、MySQLを使ってみる試みです。

 まず、MacへのDocker環境構築ですが、「Docker Desktop for Mac」をサイトからダウンロードして、簡単にセットアップできました。UbuntuへのDocker環境構築も、「Docker CE for Ubuntu」をサイトの指示に従ってターミナルからコマンドを入力するだけで簡単にセットアップできました。

 次に、Docker環境からMySQLを実行しますが、Mac、Ubuntuともに同じコマンドで(Ubuntuではsudoを付けて)実行できました。以下、Ubuntuでの実行例です。

 まず、mysqltestというMySQLの最新版のコンテナを作成しました。
$ sudo docker run --name mysqltest -e MYSQL_ROOT_PASSWORD=(password) -p 33306:3306 -d mysql:latest
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b9cec3f210a mysql:latest "docker-entrypoint.s…" 2 hours ago Exited (0) 54 minutes ago mysqltest
コンテナIDは「2b9cec3f210a」で、Docker側のIPアドレスは以下の通りでした。
$ sudo docker inspect mysqltest | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
 準備ができ、以下のコマンドで実行すると、無事にMySQLが立ち上がりました。
$ sudo docker start 2b9cec3f210a
$ sudo docker exec -it mysqltest mysql -p

 MySQLの参考書として、今回は『おうちで学べるデータベースのきほん』を使いました。
この書籍のSQL文の実行例で「world」というデータベースを使うのですが、Docker環境で起動したMySQLにはそのデータベースがありませんでした。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
一旦MySQLを終了させ、ネットでそのデータベースを探すと、すぐに見つかりました。ダウンロードし、以下のコマンドでDocker環境のルートフォルダにコピーしました。
$ sudo docker cp ~/world.sql 2b9cec3f210a:/world.sql
再度、MySQLを起動させ、以下のコマンドでファイルから実行させました。
mysql> SOURCE world.sql
データベースを確認すると、新規に登録されていました。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| world |
+--------------------+
5 rows in set (0.02 sec)
worldデータベースを使い、SQL文を触ってみました。
mysql> use world;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city |
| country |
| countrylanguage |
+-----------------+
3 rows in set (0.00 sec)

mysql> select * from city;
+------+-----------------------------------+-------------+----------------------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------------------------------+-------------+----------------------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 2 | Qandahar | AFG | Qandahar | 237500 |
| 3 | Herat | AFG | Herat | 186800 |
 ・・・・・
| 1532 | Tokyo | JPN | Tokyo-to | 7980230 |
| 1533 | Jokohama [Yokohama] | JPN | Kanagawa | 3339594 |
| 1534 | Osaka | JPN | Osaka | 2595674 |
 ・・・・・
| 4077 | Jabaliya | PSE | North Gaza | 113901 |
| 4078 | Nablus | PSE | Nablus | 100231 |
| 4079 | Rafah | PSE | Rafah | 92020 |
+------+-----------------------------------+-------------+----------------------+------------+
4079 rows in set (0.00 sec)

mysql> select * from city where countrycode='JPN';
+------+---------------------+-------------+-----------+------------+
| ID | Name | CountryCode | District | Population |
+------+---------------------+-------------+-----------+------------+
| 1532 | Tokyo | JPN | Tokyo-to | 7980230 |
| 1533 | Jokohama [Yokohama] | JPN | Kanagawa | 3339594 |
| 1534 | Osaka | JPN | Osaka | 2595674 |
 ・・・・・
| 1777 | Narita | JPN | Chiba | 91470 |
| 1778 | Kashiwazaki | JPN | Niigata | 91229 |
| 1779 | Tsuyama | JPN | Okayama | 91170 |
+------+---------------------+-------------+-----------+------------+
248 rows in set (0.00 sec)

mysql>
いい感じで実行できました。MySQLの実行環境がDocker環境で構築できました。SQL文の勉強やデータ解析に利用できそうです。

振動データを解析する(1)

 加速度センサを用いた「振動データ解析」に以前から興味がありました。設備の駆動系(モータ)の異常検知に一般的に利用されている解析手法で、加速度センサの生データにFFT処理を行い、周波数特性の経時変化を見て異常を判断するものです。あまりこの分野は詳しくないので勉強も兼ねて試行錯誤で行いました。
 データはNASA bearing datasetというネット上にあったものを使いました。このデータは以下のテスト測定系で採取されたものです。Measurement_setup_200124.pngまた、データ採取の実験条件は以下の通りです。
 ・モータは2,000rpmで回転
 ・シャフトにBearingが4個
 ・各Bearingに加速度センサが2個(x,y軸) ⇒ 合計8個
 ・20kHz(0.05msec)でサンプリング
 ・データファイルは1min毎に作成され、20,480レコード/ファイル
  (20,480×0.05 = 1,024 msec ⇒ 1sec)

 テストは大きく3つに分かれ、今回はその中の1つ目をテストデータを使いました。このテストでは最後に、Bearing3で内輪欠陥が発生、Bearing4でローラエレメントの欠陥が発生したとのこと。今回はBearing3について解析を行いました。Setup_Result1_200124.pngデータファイルは以下の通りで、8つのフィールドがあり、順に、Bearing1(x軸)、Bearing1(y軸)、Bearing2(x軸)、・・・・、Bearing4(y軸)の加速度データです。RawdataFormat_200124.png
 実際に処理したPythonプログラムは以下の通りです。準備として、プログラムファイルのあるフォルダにサブフォルダ「1st_test」を作成し、生データを入れておきます。プログラムを実行すると、サブフォルダ内のファイル全数について、FFT解析(22行目)とOctave解析(26-28行目)を実施し、結果出力します。
 Octave解析については、FFT解析の結果からの特徴量を決めるために行い、低周波数帯(10〜100Hz)、中周波数帯(100Hz〜1kHz)、高周波数帯(1kHz〜10kHz)の3つの帯域に分け、その積算強度を求めました。
import os
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Datafile List
datafolder = './1st_test/'
filelist = os.listdir(datafolder)
filelist.sort()
filenum = len(filelist)

sampintv = 0.05/1000 # Sampling interval[sec]:20kHz
targetsensor = 4 # 0,1:Sensor1 x,y, 2,3:Sensor2 x,y, 4,5::Sensor3 x,y, 6,7:Sensor4 x,y

# FFT-analysis
for i in range(0,filenum):
filename = datafolder + filelist[i]
x = np.loadtxt(filename) #Load data
datanum = len(x) #data number
funfreq = 1/(datanum * sampintv) #fundamantal frequency

res = np.fft.fft(x[:,targetsensor]) #FFT results
spec = abs(res) #FFT spectra

# Octave analysis
low_freq = sum(spec[10:100])
mid_freq = sum(spec[100:1000])
high_freq = sum(spec[1000:10000])

# Graph output
# Raw data
#plt.plot(x[:,targetsensor])
#plt.show()
#plt.clf()

# FFT data
#plt.xlim(1, datanum/2)
#plt.ylim(0,500)
#plt.plot(spec)
#plt.show()
#plt.clf()

#File output
with open("Octave_res.csv", "a") as f:
np.savetxt(f, np.c_[i, low_freq, mid_freq, high_freq],delimiter=',')

print("Process: " + str(i+1)+'/'+str(filenum))
 解析結果です。テストスタート時の加速度センサのデータは以下の通りです。全部で1分間分のデータです。Rawdata(before)_200124.pngこのデータに対し、FFT処理すると、以下の通りです。FFT(before)_200124.pngOctave解析の結果を時系列にプロットすると、以下の通りで、テストの最後にFFTスペクトルの積算値が急激に大きくなっていることが分かりました。また、急激に変化する手前に緩やかに変化する所がありました。このあたりを利用すれば、異常が発生する前に予兆を捉えることができそうです。Bearing3x_200124.pngBearing3y_200124.png最後の異常時の加速度センサのデータは以下の通りで、振幅が増大していることが分かります。Rawdata(after)_200124.pngFFT処理すると、様々な周波数のピークが出て、強度も大きくなっていることが分かりました。FFT(after)_200124.png
 今回は、手探りで振動データの解析を行いました。処理した内容で異常は可視化できましたが、スマートな手法なのかは良く分かりません。もう少し、勉強を継続しようと思います・・。

RからPythonへの道(9)

 前回の単回帰分析に続き、今回は「8. 回帰分析(重回帰)」について、RとPythonで計算して行きたいと思います。今回も書籍『東京大学のデータサイエンティスト育成講座』を教材に利用しました。 まずは、Pythonのコードです。ネット上のデータファイルをダウンロードし、重回帰分析するコードです。コードを大きく2つに分けて、前半で前処理(欠損データの削除、説明変数選択)と相関係数算出、後半でデータを半数ずつ学習データ・評価データに分けて、scikit-learnを使って重回帰モデル作成と分析・予測を実施しました。
# Multi Regression
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

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=1)

# modeling
model = LinearRegression()
model.fit(x_train, y_train)

# coefficient of regression
print('\nCoefficient of regression\n{}'.format(pd.Series(model.coef_,index=x.columns)))
print('Intercept:{:.3f}'.format(model.intercept_))

# coefficient of determination
print('Coefficient of determination(train):{:.3f}'.format(model.score(x_train, y_train)))
print('Coefficient of determination(test):{:.3f}'.format(model.score(x_test, y_test)))

 Pythonコードの実行結果は以下の通りです。
# line 20
car data format:(205, 26)
# line 21
symboling normalized-losses make fuel-type aspiration ... horsepower peak-rpm city-mpg highway-mpg price
0 3 ? alfa-romero gas std ... 111 5000 21 27 13495
1 3 ? alfa-romero gas std ... 111 5000 21 27 16500
2 1 ? alfa-romero gas std ... 154 5000 19 26 16500
3 2 164 audi gas std ... 102 5500 24 30 13950
4 2 164 audi gas std ... 115 5500 18 22 17450

[5 rows x 26 columns]

# line 25
price 4
horsepower 2
width 0
height 0
dtype: int64

# line 31
data type check(before)
price object
horsepower object
width float64
height float64
dtype: object

# line 36
data type check(after)
price int64
horsepower int64
width float64
height float64
dtype: object

# line 39
price horsepower width height
price 1.000000 0.810533 0.753871 0.134990
horsepower 0.810533 1.000000 0.615315 -0.087407
width 0.753871 0.615315 1.000000 0.309223
height 0.134990 -0.087407 0.309223 1.000000

# line 57-58
Coefficient of regression
horsepower 128.498793
width 1316.385831
height 328.304406
dtype: float64
Intercept:-104616.439

# line 61-62
Coefficient of determination(train):0.764
Coefficient of determination(test):0.765

 次にRのコードです。コードはPythonと同じ流れで、重回帰分析はcaretライブラリを使いました。
# Multi-regression
#--------------------
# 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)

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

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

# modeling
auto.lm<-train(price ~ horsepower + width + height, data = df_Train, method = 'lm')
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)
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)
1 - a/b

 Rコードの実行結果は以下の通りです。
# line 12
> dim(auto)
[1] 205 26

# line 13
> head(auto)
symboling normalized-losses make fuel-type aspiration num-of-doors
1 3 ? alfa-romero gas std two
2 3 ? alfa-romero gas std two
3 1 ? alfa-romero gas std two
4 2 164 audi gas std four
5 2 164 audi gas std four
6 2 ? audi gas std two
body-style drive-wheels engine-location wheel-base length width height curb-weight
1 convertible rwd front 88.6 168.8 64.1 48.8 2548
2 convertible rwd front 88.6 168.8 64.1 48.8 2548
3 hatchback rwd front 94.5 171.2 65.5 52.4 2823
4 sedan fwd front 99.8 176.6 66.2 54.3 2337
5 sedan 4wd front 99.4 176.6 66.4 54.3 2824
6 sedan fwd front 99.8 177.3 66.3 53.1 2507
engine-type num-of-cylinders engine-size fuel-system bore stroke compression-ratio
1 dohc four 130 mpfi 3.47 2.68 9.0
2 dohc four 130 mpfi 3.47 2.68 9.0
3 ohcv six 152 mpfi 2.68 3.47 9.0
4 ohc four 109 mpfi 3.19 3.40 10.0
5 ohc five 136 mpfi 3.19 3.40 8.0
6 ohc five 136 mpfi 3.19 3.40 8.5
horsepower peak-rpm city-mpg highway-mpg price
1 111 5000 21 27 13495
2 111 5000 21 27 16500
3 154 5000 19 26 16500
4 102 5500 24 30 13950
5 115 5500 18 22 17450
6 110 5500 19 25 15250

# line 17-20
> length(auto$price[which(auto$price=="?")])
[1] 4
> length(auto$horsepower[which(auto$horsepower=="?")])
[1] 2
> length(auto$width[which(auto$width=="?")])
[1] 0
> length(auto$height[which(auto$height=="?")])
[1] 0

# line 23-24
> # data type check(before)
> sapply(auto, class)
price horsepower width height
"factor" "factor" "numeric" "numeric"

# line 34-35
> # data type check(after)
> sapply(auto, class)
price horsepower width height
"numeric" "numeric" "numeric" "numeric"

# line 37-38
> # Correlation
> cor(auto)
price horsepower width height
price 1.0000000 0.81053308 0.7538711 0.13499023
horsepower 0.8105331 1.00000000 0.6153152 -0.08740662
width 0.7538711 0.61531524 1.0000000 0.30922320
height 0.1349902 -0.08740662 0.3092232 1.00000000

# line 53-55
> # modeling
> auto.lm<-train(price ~ horsepower + width + height, data = df_Train, method = 'lm')
> summary(auto.lm)

Call:
lm(formula = .outcome ~ ., data = dat)

Residuals:
Min 1Q Median 3Q Max
-8848.8 -2579.1 -187.3 2121.5 15529.4

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -113811.60 15184.80 -7.495 3.12e-11 ***
horsepower 122.05 14.39 8.480 2.54e-13 ***
width 1536.90 277.07 5.547 2.51e-07 ***
height 242.62 180.82 1.342 0.183
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3970 on 97 degrees of freedom
Multiple R-squared: 0.769, Adjusted R-squared: 0.7619
F-statistic: 107.6 on 3 and 97 DF, p-value: < 2.2e-16

# line 59-68
> # 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)
> 1 - a/b
[1] 0.7689992
> # Test data
> a = sum((df_Test$price - predict(auto.lm, newdata = df_Test))^2)
> b = sum((df_Test$price - mean(df_Test$price))^2)
> 1 - a/b
[1] 0.7594818
最後の決定係数は定義式から計算しました。Trainデータの決定係数は、summary関数で出力されたMultiple R-squaredの値と同じです。PythonとRの結果が微妙に異なるのは、学習(Train)データで抽出されたデータ要素が異なるからです。同じにする方法をネットで探していましたが、見つかりませんでした・・。
 重回帰分析も、Python、Rに関わらず、どちらでも簡単にできますね。次回はその他の回帰分析にチャレンジしようと思います。

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

マンモス展を見に行く

 九州に帰省した後、暖かい年末年始を過ごしています。実家にゴロゴロしているのも時間がもったいないので、今日も外出しました。
 博多に帰省してラーメンを食べていなかったので、今日こそは食べようと意気込み強く博多駅へ。というのも、博多駅の「博多めん街道」を覗いて見ると、11時前でも中国人や私のような帰省した客が多く、人、人、人だらけで通路まで長蛇の列で身動き取れず、進めない状態だったからです。
 今日は10時過ぎに「二男坊」に入り、ラーメン+替え玉をいただきました。Jinanbo_Ramen.png毎度のことながら、美味しかったですね。最近、味覚が変わったのか、豚骨ラーメン(の脂)が体に合わなくなりつつあります。一蘭を卒業したのもそのような体調の変化からです・・。

 早い昼食の後は、福岡市科学館に「マンモス展」を見に行きました。以前、日本科学未来館で展示されていたものが地方巡業に来ているものですね。日本科学未来館で実施されていた時のポスターもインパクトがありますね。 Mammoth-exhibition 昨日(1/1)の九博の「三国志展」と違って、なかなかインパクトがあり、大変満足しました。三国志は2〜3世紀、マンモスは数万年前で時間スケールが違いますが、生のマンモスの展示物がリアルだったから良かったのでしょうね。
 目玉は、2005年に開催された「愛・地球博」で展示されていた「ユカギルマンモス」(頭部冷凍標本)です。 Mammoth1実を言うと、15年前の「愛・地球博」でこの「冷凍マンモス」を見たのですが、長蛇の列で遠目に眺めた記憶があります。それが目の前で見ることができ、大変興奮しました。その他、いろいろな冷凍標本の展示があり、見応え十分です。
仔ウマ「フジ」とケナガマンモスの皮膚SmallHorse.pngユカギルバイソン、仔イヌ、ライチョウBison.pngケナガマンモスの鼻 Mammoths noseレプリカも迫力満点です。Mammoth2Mammoth3はじめ人間ギャートルズ」でおなじみのマンモスですが、マンモスは筋肉質で肉はおいしくないとのこと(余談)。古代の動物がロシアの永久凍土の中で当時と同じ状態(血液採取も可能)で眠っているのは驚きですね。ロマンを感じます。

九博に「三国志」特別展を見に行く

 実家の博多に12/30から家族全員で帰省しています。あっという間に年も変わって2020年になりました。元日恒例の太宰府天満宮への初詣を終え、時間もあったので、これまた恒例?の九州国立博物館へ行きました。
 特別展「三国志」が開催されていました。以前、東京国立博物館で開催されていたもので、見に行きたいなと思っていた展示でした。Sangokushi-Exhibition.png 三国志は、吉川英治著の全8巻を中学生の頃に読んで、ごく最近(2年前)にも青空文庫で読み直していたので、大体の歴史の流れ、登場人物の人物像や関係は理解していました。

 展示物は主に中国国内の博物館の三国志に関係する展示物をピックアップしたもので、当時(2〜3世紀)の武器や青銅器、陶器が中心でした。曹操の墓をイメージした展示もあり、墓からの出土品等盛り沢山でした。おまけ?なのか、横山光輝の漫画の三国志の原画やNHK人形劇の三国志の人形の展示もありました。

 期待が大きかった反面、全体的に大きな目玉のような展示がなかった感がありました(あくまでも主観です)。
 ただ、考えてみれば、三国志の時代って、日本では卑弥呼の時代なんですよね。それを思うと、当時の中国は日本よりはるかに文明が進んでいたんですね。最近もICT、AI分野で中国は日本に比べて先に行っていることを思うと、昔に逆戻りした感がありますね。歴史は繰り返す・・。今後、遣唐使ならぬ、遣中使?が必要になるのかも・・。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

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

月別アーカイブ

メールフォーム

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