fc2ブログ

また、腰やっちゃいました。

水曜日(1/24)から風邪で頭痛がひどく、会社を休んで1日中寝たきりで療養していました。この数日間、微熱が続いていたのでゆっくり休んで体調を戻そうとしました。

ところが、木曜日(1/25)はさらに病状が悪化してしまい、ふらふらの中、病院に行くことに。当日は大雪で積雪15cm。車の上の雪かきは奥さんにお願いしました(感謝)。インフルエンザの検査もして、陰性でまずは安心。喉の炎症がひどく抗生物質を処方してもらい、症状は徐々に快方へ。しんどくて入れなかったお風呂に1日ぶりに入りました。気分も体もすっきりして明日から頑張ろうと思ったのも束の間、パンツを取ろうとしゃがんだ瞬間に「激痛の火花がビガッ」…。…あぁ、またやってしまった…。2年ぶりです。それも全く同じこの時期で、積雪もあり。何か因縁を感じます。あ~ぁ。

結局、今日(1/26)も「歩くだけで激痛」に見舞われて会社に行ける状態でなく、情けないお休みです。風邪の方は薬でかなり良くなっていただけに、「人生って、そんなに甘くないな…」と思う反面、「もう少し休養を取りなさい」という天の声を聞きながら寝たきりを今も継続中です。

早く、元気になりたいものです。
スポンサーサイト



Excel分析ツールを見直す(5)

 前回の続きです。今回は、Pythonで回帰分析を行います。

3.Python
 Pythonにおける「回帰分析」では、「scikit-learnを用いる方法」と「StatsModelsを用いる方法」の2パターンを試してみました。

まず、scikit-learnを用いる方法です。プログラムは以下の通りです。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model

x = np.array([107,336,233,82,61,378,129,313,142,428,100,350,230,70,50,380,120,300,135,430]).reshape(-1, 1)
y = np.array([286,851,589,389,158,1037,463,563,372,1020,170,845,570,300,160,1050,450,550,380,1030]).reshape(-1, 1)

# Linear Regression (y=ax+b)
lrm = linear_model.LinearRegression()
lrm.fit_intercept = True
lrm.fit(x, y)
print('< y = ax + b >')
print('Slope = ', (lrm.coef_[0])[0] )
print('Intercept = ', lrm.intercept_[0])
print('R-squared = ', lrm.score(x, y))
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(0, 500)
plt.ylim(0, 1200)
plt.plot(x, lrm.predict(x)) # Regression Line
plt.show()

# Linear Regression (y=ax)
lrm.fit_intercept = False
lrm.fit(x, y)
print('< y = ax >')
print('Slope = ', (lrm.coef_[0])[0] )
print('R-squared = ', lrm.score(x, y))
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(0, 500)
plt.ylim(0, 1200)
plt.plot(x, lrm.predict(x)) # Regression Line
plt.show()
5、6行目でデータを入力しますが、reshape(-1, 1)で一次元配列に変換します。8~22行目は「切片≠0」の場合で、24~36行目は「切片=0」の場合のコードです。違いはfit_interceptパラメータをTrue(切片≠0)にするか、False(切片=0)にするかです。11、26行目でそれぞれ直線回帰を行い、グラフを描画しました。

「切片≠0」の結果は以下の通りです。python_sk_Reg1_180108.png
< y = ax + b >
Slope = 2.19202803591
Intercept = 82.2534685472
R-squared = 0.901455294047
結果は、前々回のExcel、前回のRと同じ結果でした。

「切片=0」の結果は以下の通りです。python_sk_Reg2_180108.png
< y = ax >
Slope = 2.46992382474
R-squared = 0.881847019096
 この決定係数は、Rの結果と異なり、怪しい値と言っていたExcelグラフの近似曲線から求めたものと同じ値になりました。いったい何が正しいのでしょうか?謎解きの前に、StatsModelsを用いる方法でも回帰分析を行いました。プログラムは以下の通りです。
import numpy as np
import matplotlib.pyplot as plt
from statsmodels import api as sm
import statsmodels.formula.api as smf

x = np.array([107,336,233,82,61,378,129,313,142,428,100,350,230,70,50,380,120,300,135,430])
y = np.array([286,851,589,389,158,1037,463,563,372,1020,170,845,570,300,160,1050,450,550,380,1030])

model = smf.OLS(y, x) # Intercept = 0
result = model.fit()
print(result.summary())
a = result.params[0]
print('Slope = ', a)
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(0, 500)
plt.ylim(0, 1200)
plt.plot(x, a*x) # Regression Line
plt.show()

XX = sm.add_constant(x)
YY = y
model = smf.OLS(YY, XX)
result2 = model.fit()
print(result2.summary())
a = result2.params[0]
b = result2.params[1]
print('Slope = ', b)
print('Intercept = ', a)
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(0, 500)
plt.ylim(0, 1200)
plt.plot(x, b*x+a) # Regression Line
plt.show()
 StatsModelsでは、データをreshape(-1, 1)で一次元配列にする必要はなく処理できました。10行目で直線回帰をすると、結果は「切片=0」のものでした。切片ありにするには22行目のような「定数付き」のおまじないが必要でした。

先に「切片=0」の結果は以下の通りです。python_stats_Reg1_180108.png

OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.974
Model: OLS Adj. R-squared: 0.972
Method: Least Squares F-statistic: 704.8
Date: Mon, 08 Jan 2018 Prob (F-statistic): 1.75e-16
Time: 17:15:13 Log-Likelihood: -121.11
No. Observations: 20 AIC: 244.2
Df Residuals: 19 BIC: 245.2
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
x1 2.4699 0.093 26.549 0.000 2.275 2.665
==============================================================================
Omnibus: 2.296 Durbin-Watson: 2.224
Prob(Omnibus): 0.317 Jarque-Bera (JB): 1.207
Skew: -0.597 Prob(JB): 0.547
Kurtosis: 3.153 Cond. No. 1.00
==============================================================================
Rの結果のように詳しい結果が表示できました。この決定係数(0.974)はまたまた先ほどと(0.8818)異なるものでした。ますます混乱してきました・・。

「切片≠0」の結果は以下の通りです。python_stats_Reg2_180108.png

OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.901
Model: OLS Adj. R-squared: 0.896
Method: Least Squares F-statistic: 164.7
Date: Mon, 08 Jan 2018 Prob (F-statistic): 1.70e-10
Time: 17:15:13 Log-Likelihood: -119.29
No. Observations: 20 AIC: 242.6
Df Residuals: 18 BIC: 244.6
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 82.2535 43.463 1.893 0.075 -9.058 173.565
x1 2.1920 0.171 12.832 0.000 1.833 2.551
==============================================================================
Omnibus: 1.585 Durbin-Watson: 2.360
Prob(Omnibus): 0.453 Jarque-Bera (JB): 1.022
Skew: -0.547 Prob(JB): 0.600
Kurtosis: 2.832 Cond. No. 498.
==============================================================================
こちらは問題なしです。

 Excel、R、Pythonの順に結果を見てきましたが、まとめると以下の通りになります。RegressionResults_180108.pngy=ax+bの形での回帰分析は三者とも同じ結果で問題なかったのですが、y=axの形の時の決定係数が2パターンに分かれてしまいました。気持ち悪さが残っていますので、時間をかけて調べてみようと思います。

Excel分析ツールを見直す(4)

 前回の続きです。今回は、Rで回帰分析を行います。

2.R
 実行したプログラムは以下の通りです。6~13行目は「切片≠0」の場合で、15~21行目は「切片=0」の場合のコードです。違いはlm関数の中の「y~x」と「y~x-1」です。
# Liner Regression

x<-c(107,336,233,82,61,378,129,313,142,428,100,350,230,70,50,380,120,300,135,430)
y<-c(286,851,589,389,158,1037,463,563,372,1020,170,845,570,300,160,1050,450,550,380,1030)

lmRes <- lm(y~x)
summary(lmRes)

sprintf("Slope = %f",lmRes$coefficients[2])
sprintf("Intercept = %f",lmRes$coefficients[1])
sprintf("R-squared = %f",cor(y, x)**2)
plot(x,y,pch=16,col="blue",xlim = c(0,500),ylim = c(0,1200))
abline(lmRes,col="blue")

lmRes <- lm(y~x-1)
summary(lmRes)

sprintf("Slope = %f",lmRes$coefficients[1])
sprintf("R-squared = %f",cor(y, x)**2)
plot(x,y,pch=16,col="blue",xlim = c(0,500),ylim = c(0,1200))
abline(lmRes,col="blue")
この「切片≠0」の結果は以下の通りです。R_Reg1_180108.png
Call:
lm(formula = y ~ x)

Residuals:
Min 1Q Median 3Q Max
-205.358 -31.064 -2.219 72.722 134.776

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 82.2535 43.4625 1.893 0.0746 .
x 2.1920 0.1708 12.832 1.7e-10 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 99.32 on 18 degrees of freedom
Multiple R-squared: 0.9015, Adjusted R-squared: 0.896
F-statistic: 164.7 on 1 and 18 DF, p-value: 1.703e-10

[1] "Slope = 2.192028"
[1] "Intercept = 82.253469"
[1] "R-squared = 0.901455"
 Coefficients:の傾き、切片、標準誤差、t値、p値、およびMultiple R-squared:の結果は、前回Excelの解析結果と同じでした。

 また、「切片=0」の結果は以下の通りです。R_Reg2_180108.png
Call:
lm(formula = y ~ x - 1)

Residuals:
Min 1Q Median 3Q Max
-210.09 -22.62 21.19 105.38 186.47

Coefficients:
Estimate Std. Error t value Pr(>|t|)
x 2.46992 0.09303 26.55 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 105.9 on 19 degrees of freedom
Multiple R-squared: 0.9738, Adjusted R-squared: 0.9724
F-statistic: 704.8 on 1 and 19 DF, p-value: < 2.2e-16

[1] "Slope = 2.469924"
[1] "R-squared = 0.901455"
 Coefficients:の傾き、標準誤差、t値、p値、およびMultiple R-squared:の結果は、前回のExcelの解析結果(概要)と同じでした。前回、グラフ描画して、近似曲線を書かせた際の決定係数R2が0.8818であったことを考えると、このグラフの値が怪しいということになります。

 長くなりましたので、このぐらいにして、次回は、Pythonで回帰分析を行いたいと思います。

Excel分析ツールを見直す(3)

 Excel分析ツールの第二弾の「回帰分析」です。

1.Excel
 まず、x, yのデータを20組準備しました。メニューの「データ」ー「データ分析」を選択します。Excel_Reg1_180108.png分析ツールの中から「回帰分析」を選択し、OKボタンを押します。Excel_Reg2_180108.pngyデータ(赤枠)、xデータ(青枠)と結果の出力先のセル(緑枠)を設定し、OKボタンを押します。この時「定数に0を使用」にチェックをすれば「y = ax」、チェックを外しておけば「y = ax + b」の形で回帰分析を行います。結果の違いは後ほどお話しします。Excel_Reg3_180108.png 結果をじっくり見る前に、散布図を作成し、回帰直線を引きます。データ範囲(ここでは、B2:C21)を選択し、「挿入」ー「グラフ」で散布図を作成します。プロット点を選択し、右クリックするとメニューが表示されるので、「近似曲線の追加」を選択します。Excel_Reg4_180108.png「線形近似」になっていることを確認し、「グラフに数式を表示する」、「グラフにR-2乗値を表示する」にチェックを入れます。ここで「切片」にチェックを入れると、固定値(例えば切片=0)を入れることができます。Excel_Reg5_180108.png
 それでは、結果を詳しく見て行きます。まずは、「切片≠0」の時です。傾き2.192、切片82.253、決定係数R2=0.9015の回帰直線が引かれました。Excel_Reg6_180108.png出力された結果も、同じ結果が得られました。Excel_Reg7_180108.png
 次に「切片=0」の時の結果です。傾き2.4699、決定係数R2=0.8818の直線ですが、Excel_Reg8_180108.png出力された結果のR2の値とは異なっていることが分かりました。これについては、ネット上でいろいろ議論されているので、この場では言及しません。Excel_Reg9_180108.png
 次回は、RとPythonで回帰分析を行いたいと思います。

Windows10 時刻異常の怪

 今朝、久々に家族兼用PC(DELL XPS 8500, Windows10 Pro)の電源を入れて、自分の環境を立ち上げると、表示時刻が何か変・・?。今まで正常だったのに・・。
 9時間ずれている(9:56 JSTなのに、0:56になっていた)。おかしいなと思い、UTCが表示されているのだなと思い、設定を確認するも、インターネット時刻設定も含めて問題なし。余計、理由が分からない。時刻異常180107
 訳が分からないまま、「時刻を自動に設定する」を一旦オフにして、オンにすると、時刻が正常に戻った。結局、理由は分からずじまい。

 しばらく私自身使っていなかったので、気付かなかったのですが、1週間以上前からずれていた模様(奥さん談:ぉぃぉぃ)。
 軽微なバグなんでしょうか?また同じことが起こりそうです。しばらく要ウォッチです。さすが、マイ〇ソソフトですね。新年早々いい加減にしてもらいたいです。

Excel分析ツールを見直す(2)

 前回の続きです。今回は、RPythonでヒストグラムを作成しようと思います。

2.R
 以下の数行のプログラムで作成できます。ヒストグラムは「R標準のグラフ表示」と「ggplot2を用いた表示」の2種類試しました。
library(ggplot2)
# data
xdata <- c(2535,1743,1348,2890,1610,783,1246,2047,2363,2163,751,3041,1575,687,1104,737,1680,1785,1702,792,1910,1150,2643,1328,859,1921,1828,1102,2444,1334,1282,3241,1730,3241,1244,1602,1833,1807,3150,2814,1478,808,1584,3266,2417,3057,1922,2764,1480,2082)
# Histgram
hist(xdata, breaks=c(500,1000,1500,2000,2500,3000,3500),col='blue',labels = TRUE)

# Histgram (ggplot)
xdata <- data.frame(xdata)
m <- ggplot(xdata, aes(x = xdata))+labs(y="Frequency")
m + geom_histogram(breaks=c(500,1000,1500,2000,2500,3000,3500), colour="blue",fill="blue")
 5行目のbreaksであえてデータ区切りを指定していますが、breaksの指定がない場合は、スタージェスの公式「breaks = "Sturges"」がデフォルトで設定され、適切な区分数を判断してくれるようです。
 また、ヒストグラムの各区間の度数を表示させるために、「labels = TRUE」を設定しました。結果はこんな感じです。R_plot_180103.png また、Rできれいなグラフを描くツールとしてggplot2がよく使われていますので、そちらでも試しました。ただし、入力データはdata.frameにする必要がありますので、8行目で変換しました。元々は「numeric」型です。結果はこんな感じです。ggplot2に十分慣れていないので、グラフ上への度数表示はできていません・・。R_ggplot_180103.png
3.Python
 PythonもRと同様に数行程度のプログラムで作成できました。
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
xdata = np.array([2535,1743,1348,2890,1610,783,1246,2047,2363,2163,751,3041,1575,687,1104,737,1680,1785,1702,792,1910,1150,2643,1328,859,1921,1828,1102,2444,1334,1282,3241,1730,3241,1244,1602,1833,1807,3150,2814,1478,808,1584,3266,2417,3057,1922,2764,1480,2082])
plt.hist(xdata)
plt.hist(xdata,bins=6)
plt.hist(xdata,range=(500,3500),bins=6)
jupyter notebookで実行した結果は以下の通りです。
5行目で何も条件設定せずに、実行するとRとは異なった区分数での表示結果でした。
python_prog1_180103.pngRの方では、何も条件設定しなくても、スタージェスの公式を考慮した結果が表示されましたので、大変、筋が良いと思いました。

試行錯誤で、ExcelやRと同じヒストグラムにするために設定を変更します。6行目で、区分数を6個に指定しました。区間が異なるのでしょうね、形がまだ違います。python_prog2_180103.png7行目で追加で区間範囲を設定しました。これでようやく完成です。python_prog3_180103.png

前回と今回でExcel、R、Pythonでヒストグラムを見てきましたが、知識が何もない状態でヒストグラムを書きたい場合、手間と完成度から判断して、「R」が一番「万人受け?する」ような結果を出しているような気がしました。あくまで主観ですが・・。勉強になりました。

Excel分析ツールを見直す(1)

 年末から風邪気味で体調がいまいちだったためか、昨日は1日中寝込んでいました。毎年、この時期によく体調を崩します・・。気が緩んでいるせいかもしれません。今日から仕事で、体も本調子でないながらも、年明け初めてのブログをアップします。

 仕事柄、「データ解析」を行うことがあり、Rをよく使うのですが、Rは初心者に取っ付きにくいと言われていますね。気軽にデータ解析を行うにはExcelで十分と言われる方もおられるでしょうし、最近はPythonもデータ解析分野(特に機械学習分野)で脚光を浴びています。一体どれを使ったら良いのでしょうか?使い慣れているものを使えば良いという結論でしょうが、判断するには、やはり自分で一通りどのようなものか味わってみることが必要であると思いました。

 Excelには「分析ツール」があり、いくつかの機能は仕事で使ったことがありますが、すべての機能は使ったことがないので、腰を据えてRPythonと比較しながら勉強し直そうと思い立ちました。今回は比較的よく使う「ヒストグラム」です。

1.Excel
 以前パソコントラブルがあった時に、購入したExcel 2016(ダウンロード版)を使って、ヒストグラムを作成しました。その前に、まず、「分析ツール」を使える状態にするための設定から始めました。
➀ Excelを起動し、メニューから「ファイル」を選択します。ExcelTool1_180103.png➁ オプションを選択します。ExcelTool2_180103.png➂ アドインを選択します。下線の「ソルバーアドイン」、「分析ツール」、「分析ツール - VBA」をアクティブにするために、「設定」ボタンを押します。ExcelTool3_180103.png④ アドインのウィンドウが開くので、チェックを入れ、OKボタンを押します。ExcelTool4_180103.png⑤ ④のチェック項目がアクティブになったことを確認し、OKボタンを押します。これで「分析ツール」が利用可能になりました。ExcelTool5_180103.png
 次に、実際にヒストグラムを作成します。メニューの「データ」から「データ分析」を選択します。ExcelTool6_180103.png「データ分析」ウィンドウから「ヒストグラム」を選択し、OKボタンを押します。ExcelTool7_180103.png「ヒストグラム」ウィンドウで、入力データの範囲(赤枠)、データ区間(青枠)と度数分布表を出力するセル(緑枠)を設定します。グラフ作成にチェックを入れ、OKボタンを押します。ExcelTool8_180103.png度数分布表が作成され、グラフが作成されます。グラフはサイズや頻度データの表示等自由にカスタマイズできます。ExcelTool9_180103.png Excelでは、データ区間(階級の数)を意図的に与える必要がありますが、RPythonでは自動(設定)で最適なデータ区間に分けてくれます。一般的にはスタージェスの公式(Sturges' rule)で「階級の数k」を、「階級の幅」はデータの最大値と最小値の差をkで割った値で求めるのが目安とのこと。

 長くなりましたので、次回はRPythonでヒストグラムを作成しようと思います。 

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

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

月別アーカイブ

メールフォーム

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