PyStanおよびPyMC3をWindowsのUbuntuで利用する
備忘録2022.08、2024.10
Windows上にUbuntuをインストールするとPyStanとMSVC++との相性の問題を回避することができる。WindowsでのUbuntuのインストールは、Windows Subsystem for Linux (WSL)を利用すると簡単にできる。UbuntuのインストールとAnacondaのインストールについて説明する。
WSLは、管理者として起動したPowerShellにおいて、コマンド
wsl –-install
を実行すればインストールできる。詳しくは
https://docs.microsoft.com/ja-jp/windows/wsl/install
などを参照されたい。管理者としてPowerShellを起動するときは、マウスの右ボタンでクリックすればよい。
WSLのインストール後、Ubuntuのダウンロードが始まる。
Ubuntuのダウンロードが終了すると、Windowsの再起動が求められる。再起動が求められなくても、再起動する。
再起動後、スタートメニュに「Ubuntu」のアイコンが表示される。このアイコンをクリックすると
Installing, this may take a few minites…
というメッセージのある端末が表示される。
このInstallingが終了すると、UNIXユーザー名の設定が求められるので、好きな名前で設定する。
名前の設定の次はパスワードの設定になる。
ユーザー名とパスワードの設定が終わったら、logoutコマンドあるいはexitコマンドで端末をいったん閉じる。
なお、端末・コンソール・ターミナルの使い方の説明ウェブサイトを用意している。
WSLのアップデートを行うために、管理者としてPowerShellを起動する。
コマンド
wsl --update
を実行する。
アップデートが終了したら、コマンド
wsl --shutdown
を実行する。
次に、ubuntuのアップデートを行う。
WSLの画面をいったん閉じた後、スタートメニュにあるubuntuのアイコンをクリックして端末画面を表示する。
コマンド
sudo apt
update && sudo apt upgrade
を実行する。
アップデートとアップグレードが終了したら、端末画面を終了する。
なお、端末の使い方は、簡単な説明をこのウェブサイトに用意している。Windows端末での説明であるが、Ubuntu (Linux)の場合にも参考になると思う。Linuxの場合は、コマンドなどで大文字と小文字の区別があるので注意が必要である。また、フォルダなどの先頭に付ける円記号¥は、Linuxではスラッシュ/が用いられる。
次に、ubuntuにAnacondaをインストールするために、スタートメニュのUbuntuをクリックしてUbuntuを起動する。
Anacondaのインストールファイルは、WindowsにおいてEdgeなどのブラウザーによって適当なフォルダにダウンロードすればよい。
Anacondaのファイルは
https://www.anaconda.com/download
からダウンロードできる。
上記のURLに入ると、図A.1の画面が表示され、Emailアドレスの設定が求められる。
図A.1
Emailアドレスを設定して、Submitボタンをクリックすると、しばらくの後、Downloadのページが表示される(図A.2)。
図A.2
ダウンロード後、Ubuntuのカレントディレクトリをダウンロードしたディレクトリ(フォルダ)に移す。
UbuntuからWindowsのドライブは
cd /mnt/
で移ることができる。このmntの下にWindowsのフォルダ(ドライブ)がある。
次のコマンドでは、WindowsのRドライブのR:\Yasuharu\tempフォルダーに移っている。
cd
/mnt/r/Yasuharu/temp/
Windowsのドライブ名Rがubuntuでは小文字rであることに注意。
Anacondaのファイル、例えばAnaconda3-2022.05-Linux-x86_64.sh、をダウンロードしたフォルダにカレントディレクトリ(フォルダ)を移動した後、bashコマンドで次のようにインストールすればよい。
bash
Anaconda3-2022.05-Linux-x86_64.sh
インストール作業が進むと、license確認画面になり、画面左下に「--More--」が表示される(図A.2)。
図A.3
「Enterキー」をおすと、画面は1行進み、「スペースキー(空白文字キー)」を押すと画面は次の画面に進む。
Licenseの確認が進み、最後にlicenseの承認確認が行われる(図A.4)。
図A.4
「yes」と答えて、インストール作業を進めると、初期化についての確認画面になる(図A.5)。
図A.5
「yes」と答えておくと、後の作業が楽である。
インストール後、一旦端末すなわちUbuntuを終了した後、Ubuntuを再起動する。
再起動後、まずAnacondaのアップデートをコマンド
conda update –n base conda
を実行して行う。
続いて、コマンド
conda
update --all
を実行してパッケージのアップデートを行う。
この後、パッケージのインストールを行うが、pystanのインストールの前に、C++コンパイラーとしてg++をインストールしておく。コマンドは
sudo apt
install g++
である。g++のインストール後、pystanのインストールをコマンド
conda install
pystan
を実行して行う。ただし、PyStan 3をインストールするときは、Python 3.11の仮想環境を用意して、Python 3.11仮想環境において、コマンド
pip install
pystan
を実行する。importするときは
import stan
である。
pymc3のインストールは、Python 3.10仮想環境においてコマンド
conda install
pymc3
を実行して行えばよい。
PyStanやPyMC3の利用は、ubuntuのカレントディレクトリをWindows内のフォルダに移しておけば、実行はubuntuの環境で、スクリプトファイルの編集など他の操作はWindowsのソフトで行うことができる。
Windowsのディレクトリへのubuntuのカレントディレクトリの移動は、コマンドcd /mnt/で行うことができる。
(base) yasuharu@PSY-PM-PC:~$ cd /mnt/
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
wsl
しかし、/mnt/の下にはUSBメモリーは表示されていない(ubuntuには認識されていない)ので、USBメモリを使うときはマウントする必要がある。いま、WindowsでのUSBメモリのドライブ名がTであるとする。
まず、ubuntuのマウント先のディレクトリを用意する(既に存在すれば必要ない)。/mnt/の下にusb_tの名前のディレクトリを作成するときは、次のコマンドを実行する。
sudo mkdir
/mnt/usb_t/
下の例に示すように、/mnt/の下に/usb_t/が作成される。
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
wsl
(base) yasuharu@PSY-PM-PC:/mnt$ sudo
mkdir /mnt/usb_t/
[sudo] password for yasuharu:
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
usb_t wsl
WindowsのUSBメモリをマウントするときは、次の形式でmountコマンドを実行する。
sudo mount –t drvfs Windowのドライブ名 ubuntuのマウント先
オプション –t drvfsが必要である。
実行例を以下に示す。
(base) yasuharu@PSY-PM-PC:/mnt$ sudo
mount -t drvfs t: /mnt/usb_t/
(base) yasuharu@PSY-PM-PC:/mnt$ cd
/mnt/usb_t/
(base) yasuharu@PSY-PM-PC:/mnt/usb_t$
ls
BinomialDistriStan
PointEstimates.zip
RegressionStan.zip
Temp20220421
samples_2.zip
BinomialDistriStan.zip PythonSamples
SDT_d_prime
TempFolder
temp0311
DownLoad
RSamples
Sample
UpDown3Cat
PointEstimates RegressionStan 'System Volume Information' samples_2
ディレクトリ/usb_t/の下に、WindowsのドライブTの項目が表示されている。ドライブTは、ubuntuでは小文字tであることに注意。
アンマウントするときは、umountコマンドを用いる。以下に例を示す。
(base) yasuharu@PSY-PM-PC:/mnt/usb_t$
cd /mnt/
(base) yasuharu@PSY-PM-PC:/mnt$ sudo
umount /mnt/usb_t/
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
usb_t wsl
(base) yasuharu@PSY-PM-PC:/mnt$ cd
usb_t
(base) yasuharu@PSY-PM-PC:/mnt/usb_t$
ls
(base) yasuharu@PSY-PM-PC:/mnt/usb_t$
アンマウントしても、ubuntuのディレクトリusb_tは残っている。このディレクトリも削除するときは、rmdirコマンドを用いる。以下に、例を示す。
(base) yasuharu@PSY-PM-PC:/mnt/usb_t$
cd /mnt/
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
usb_t wsl
(base) yasuharu@PSY-PM-PC:/mnt$ sudo
rmdir /mnt/usb_t/
(base) yasuharu@PSY-PM-PC:/mnt$ ls
c
d f g
h i j
k l r
wsl
(base) yasuharu@PSY-PM-PC:/mnt$
スクリプトの編集と実行
図1は、スクリプトの編集をWindowsのPython IDLEエディタで行い、実行をubuntuから行う例を示すものである。現在(2024.10)、ubuntu22/WSLでのグラフ表示に問題がある。現在のubuntu22/WSL用のPyStan3スクリプト例については、このウェブサイトを参照されたい。
図1
Ubuntuのディレクトリ/mnt/usb_t/RegressionStanとWindowsのディレクトリT:Sample\RegressionStanが同じであることに注意。
図1のプログラムRegression.pyはリスト1に示した。
WSLのubuntuでリスト1のプログラムを実行した場合、matplotlib.pyplotのshow()メソッドを実行してもグラフは表示されない(2023.06現在は表示される;2024.10現在はトラブル中)。savefig()メソッドでファイルに保存すれば、プログラムの実行終了後、見ることができる(図2)。
図2
また、複数のグラフを描画している場合、グラフごとにclose()メソッドを実行してグラフが重ならないようにする必要がある。
PyStan 3のサンプルスクリプトはこのウェブサイトにも用意している。
リスト1 Pythonスクリプト例。リスト2のStanスクリプトを使っている。
import pystan
import matplotlib.pyplot as plt
import scipy.stats as scst
import numpy as np
RawData = [ ['City', 'Temperature',
'Latitude'],
['Sapporo',
15,
43.1],
['Sendai',
20,
38.3],
['Niigata',
17,
37.9],
['Kanazawa',
18,
36.6],
['Tokyo', 24,
35.7],
['Osaka', 22,
34.7],
['Fukuoka',
22,
33.6],
['Kochi', 24,
33.6],
['Kagoshima', 23,
31.6],
['Naha',
26,
26.2]
]
ID = []
Y = []
X = []
N = len(RawData) - 1
for i in range(N):
ID.append(RawData[i + 1][0])
Y.append(RawData[i + 1][1])
X.append(RawData[i + 1][2])
for v in zip(ID, Y, X):
print(v)
Data = {'N': N, 'Y': Y, 'X': X}
sm = pystan.StanModel(file =
'Regression.stan')
fit = sm.sampling(data = Data, n_jobs
= 1)
print(fit)
f = open('fit.txt', 'w')
f.write('fit = \n{}\n'.format(fit))
f.close()
Sampleb0 = fit['b0']
print('len(Sampleb0) = ',
len(Sampleb0))
plt.title('Samples of b0')
plt.xlabel('b0')
plt.ylabel('frequency')
plt.hist(Sampleb0)
plt.savefig('Figb0.png')
plt.show()
plt.close()
Sampleb1 = fit['b1']
nb1 = len(Sampleb1)
print('len(Sampleb1) = ', nb1)
npos = 0
for v in Sampleb1:
if v > 0.0:
npos
+= 1
plt.title(('Samples of b1\n') +
('Prop(b1 > 0) = {0:.3f}'.format(npos/nb1)))
plt.xlabel('b1')
plt.ylabel('frequency')
plt.hist(Sampleb1)
plt.savefig('Figb1.png')
plt.show()
plt.close()
Samplesgm = fit['sgm']
plt.title('Samples of sgm\n')
plt.xlabel('sgm')
plt.ylabel('frequency')
plt.hist(Samplesgm)
plt.savefig('Figsgm.png')
plt.show()
plt.close()
r, p = scst.pearsonr(Sampleb0,
Sampleb1)
print('r = ', r)
plt.xlabel('b0')
plt.ylabel('b1')
plt.title('r = {0:.3f}'.format(r))
plt.plot(Sampleb0, Sampleb1, 'b.')
plt.savefig('Figb0b1.png')
plt.show()
plt.close()
PredYs = fit['mu']
YsArray = []
for i in range(10):
YsArray.append([])
for v in PredYs:
for i in range(10):
YsArray[i].append(v[i])
MedPreds = []
for i in range(10):
MedPreds.append(np.percentile(YsArray[i], 50))
plt.xlabel('Data')
plt.ylabel('Prediction')
plt.plot(Y, MedPreds, 'bo')
for nm, y, pred in zip(ID, Y,
MedPreds):
plt.text(y + 0.1, pred +
0.1, nm)
plt.plot([14, 28], [14, 28], 'b-')
plt.savefig('FigPred.png')
plt.show()
plt.close()
data{
int N;
real Y[N];
real X[N];
}
parameters{
real b0;
real b1;
real<lower = 0> sgm;
}
transformed parameters{
real mu[N];
for (i in 1:N)
mu[i] = b0 + b1 * X[i];
}
model{
for (i in 1:N)
Y[i]
~ normal(mu[i], sgm);
}
なお、Pythonによるデータ分析の解説書<岡本安晴「いまさら聞けないPythonでデータ分析」丸善出版>を上梓している。