統計計算で,R と Python のどちらが速いかというのは多くの人の関心事のようで,ネット上でもいくつかある。
PythonとR言語のプログラム処理速度を比較!
https://ai-trend.jp/programming/python/speed-comp-python-r/
というのもそれ類のページで,初見 2018/02/01 で 2020/04/14 に更新されたようである。
それによると,どうも R の分が悪いようなので,掲載例以外の統計処理についても再試してみる。
システム構成
mxcOS Catalina バージョン 10.15.7
MacBook Pro (Retina, Mid 2012)
プロセッサ 2.7 GHz クアッドコアIntel Core i7
メモリ 16 GB 1600 MHz DDR3
R version 4.0.3
Python 3.8.1
まず,データフレームを用意する。100000行,1500列 のデータフレーム。各列は平均値50,標準偏差10の正規乱数を小数点以下2桁までで丸めた値を使う。変数名は X1, X2, ..., X1500。
CSV ファイル "test.csv" へ書き出す。
ちなみに,書き出しに要する時間は system.time() を用いて以下のように測定した。
R: system.time({write.csv(x, file="test.csv", row.names=FALSE)}) 135.968 sec.
135.968 秒かかった。
データフレームへの読み込み
R: system.time({df = read.csv("test.csv")}) 78.787 sec.
列ごとの変数型を指定すると速くなる
R: system.time({df = read.csv("test.csv", colClasses="numeric")}) 33.607 sec.
data.table パッケージの fread() はもっともっと速い。Python の 5.7 倍速
R: library(data.table)
system.time(df = fread("test.csv")) 5.023 sec.
Python: start = time(); df = pd.read_csv('test.csv'); print(time() - start) 28.793 sec.
各変数ごとに単変量解析 R の圧勝。Python の 5〜20 倍速
和 R の圧勝
R: s = colSums(df) 0.739 sec.
Python: s = df.sum() 5.416 sec.
平均値 R の圧勝
R: m = colMeans(df) 0.662 sec.
Python: m = df.mean() 5.352 sec.
不偏分散 R の圧勝
R: v = sapply(df, var) 0.552 sec.
Python: v = df.var(ddof=1) 8.466 sec.
標準偏差 R の圧勝
R: sd = sapply(df, sd) 0.561 sec.
Python: sd = df.std(ddof=1) 11.574 sec.
相関係数(単相関係数; 二変数相関)
R: cor(df[,1], df[,2]) 0.011 sec.
Python: import numpy as np
np.corrcoef(df['X1'], df['X2'])[0,1] 0.011 sec.
Python: from scipy.stats import pearsonr
pearsonr(df['X1'], df['X2'])[0] 0.004 sec.
相関係数行列 R の圧勝 ただし,ケンドールの順位相関係数は話にならないほど遅い
以下を追記した
R ユーザ,歓喜の涙 -- ケンドールの順位相関係数の計算が Python の倍速!
https://blog.goo.ne.jp/r-de-r/e/2716d7ca3c9fb3a1eb643d83d10dfecd
以下で,予測式中の p は変数の個数(df の列数)
ピアソンの積率相関係数 R が 8.7 倍速い
R: r = cor(df) 100.509 sec. 予測式 sec = 0.00001828 * p ** 2
Pythom: r = df.corr() 360.236 sec. 予測式 sec = 0.0001586 * p ** 2
スピアマンの順位相関係数 R が 20 倍速い
R: rs = cor(df, method="spearman") 140.892sec. 予測式 sec = 0.00006395 * p ** 2
Python: rs = df.corr(method='spearman') 4238.496 sec. 予測式 sec = 0.001282 * p ** 2
ケンドールの順位相関係数 R は測定不能なほど遅い
R: rk = cor(df, method="kendall") 推定値 106216279 sec. 約 3.36 年 !
Python: rk = df.corr(method='kendall') 28072.694 sec. 予測式 sec = 0.01353 * p ** 2
分散・共分散行列(R, Python とも不偏) Python の圧勝 20倍速い
R: v = var(df) 106.829 sec.
Python: v = df.cov() 4.987 sec.
重回帰分析 Python の圧勝
数個の独立変数を使うとき
R: ans = lm(X1 ~ X2+X3+X4+X5+X6+X7+X8+X9+X10, data=df)
summary(ans)
ans$coeff
str(summary(ans))
summary(ans)$r.squared # 0.163 sec.
Python: import scipy as sp
from sklearn.linear_model import LinearRegression
clf = LinearRegression()
y = df['X1']
x = df[['X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10']]
ans = clf.fit(x, y)
ans.coef_
ans.intercept_
ans.score(x, y)
print(time() - start) # 0.031 sec.
たくさんの独立変数を使うとき
R: x = as.matrix(df[-1])
ans = lm(df[, 1] ~ x)
summary.ans = summary(ans)
coeff = ans$coeff
R2 = summary(ans)$r.squared # 412.829 sec.
Python: y = df['X1']
x = df.drop('X1', axis=1)
ans = clf.fit(x, y)
coef = ans.coef_
intercept = ans.intercept_
R2 = ans.score(x, y) # 136.559 sec.