Juliaで作って学ぶベイズ統計学 正誤表(注:非公式です)

記事概要

本記事は「Juliaで作って学ぶベイズ統計学」 著:須山敦志
の正誤表になります。

 本書を購入して実際にコードを写経して勉強していたときに、上手く動かず躓いた部分がありました。本記事を執筆時点でサポートページには情報が無かったため、同じように困っている人の参考になればと思い、記事にしました。

本書についての感想

 プログラミング言語Juliaの日本語書籍はPythonなどに比べると、とても少ないです。明確な目的がないと、プログラミングの学習は長続きしませんが、「Juliaで作って学ぶベイズ統計学」はベイズ統計学とその数値計算処理をテーマにしており、ベイズ統計学と一緒にJulia言語を学ぶことができます。 実際に写経した印象は、自分の学習スタイルに合っていたこともあり、買って良かったと思いました。

コード確認の環境について

 コードの確認は、以下の版数、環境で確認しています。
〇 2021年11月24日 第1刷発行
〇 書籍で推奨されたjulia 1.6.1ではなく、Julia 1.7.1を使用
〇 VSCodeもしくはJupyter notebookで実行して確認

正誤表(注:非公式です)

以下、本に書かれた内容を写経した際に、エラーが出たり、誤記ではないか?と感じた箇所、補足があったほうが良いと感じた内容を記載しています。もし、下記修正内容でプログラムが動かなくても、みずぺんは対応しかねますので、ご了承願います。(ごめんなさい)

● p.12 3つ目のコード
1.2 基礎文法の項目を順番にJupyter notebookで実行していると、下記の箇所でエラーが出ました。

f(a, b, c) = a + b + c


a, b, c を上記コードの前に定義してしまっていたのが問題のようです。
セル単体のみ実行すれば問題ありませんでした。

● p.16  最下段 subplotsでグラフ描写を行うコード
Jupyter notebook上で実行する際は問題ありませんでしたが、
VSCode上などで動かす際は、最後に以下の一行を追加しないと、プロットが表示されませんでした。(環境によるのかもしれませんが・・・)
初心者は少し戸惑うかと思われます。

display(gcf()) # VSCodeなどでディスプレイに表示する場合に、一行追加必要

● p.57 真ん中のコード記載、p.213コード記載(動作に問題なし、不要な変数)
本書では使われていない変数が含まれていました。

function linear_fit(Y, X)
   N = length(Y)  # <- Nは本書で使われていないように思います
   w₁ = sum((Y .- mean(Y)) .* X) / sum((X .- mean(X)) .* X)
   w₂ = mean(Y) - w₁*mean(X)
   w₁, wend

● p.110 のコード記載、p.111の図(右上)
p.111の右上の図のdensityが異常に大きく、誤りがあるように思います。
対応するp.110のコードの下から7行目、11行目の部分

# (誤) 
p2_conditional(x₂) = pdf(d, [x₁, x₂]) / p2_marginal(x₁)

# (正)
p2_conditional(x₂) = pdf(d, [x₁, x₂]) / p1_marginal(x₁)

● p.158 下側のコード記載、下から9行目

# (誤)
for i in axes

# (正)
for ax in axes

● p.176 下側 ~ p.117 最上段のコード記載
p.176 下から2行目、3行目
w₂が w₁になっている。

# (誤)
log_joint(w₁, X, Y, w₁, σ, μ₁, σ₁) =
    sum(logpdf.(Normal.(w₁ * X .+ w₁, σ), Y)) +

# (正)
log_joint(w₁, X, Y, w₂, σ, μ₁, σ₁) =
    sum(logpdf.(Normal.(w₁ * X .+ w₂, σ), Y)) +

● p.177 上から1行目
w₂が w₁になっている。

# (誤)
params = (X_obs, Y_obs, w₁, σ, μ₁, σ₁)

# (正)
params = (X_obs, Y_obs, w₂, σ, μ₁, σ₁)

● p.181 コード記載 下から8行目、inference_wrapper_gdの関数定義が無い。
コード記載中の下から8行目の前に以下の関数定義を追記する必要があると思います。

(追記)
# 最適化のラッパー関数の定義
function inference_wrapper_gd(log_joint, params, w_init, η, maxiter)
   ulp(w) = log_joint(w, params...)
   w_seq = gradient_method(ulp, w_init, η, maxiter)
   w_seq
end


● p.188 下側のコード記載 変数xsの定義が不明確
変数xsの定義が直近で記載されていないため分かりづらかったです。
コード記載中の上から2行目の下に変数xsを追記したほうが良いように思いました。

# 近似分布から候補のサンプル100個を抽出
W = rand(MvNormal(μ_approx, Σ_approx), 100)
xs = range(-10, 10, length=100)   # (追記箇所)描画範囲xs

● p.196 下側コード記載、事前分布の定義が分かりづらい(誤記ではない)
事前分布の設定値はp180まで戻らないと確認できなかったので、
コード記載の先頭部分に明記したほうが分かりやすいと感じました。

# (追記)
# 事前分布の設定値
σ = 1.0
μ₁ = 0.0
μ₂ = 0.0
σ₁ = 10.0
σ₂ = 10.0

● p.208 下側コード記載、X_obs, Y_obsを直接参照している。
p.208 下側コード記載の上から3行目部分で本来引数XとYを使うところを、
X_obs, Y_obsを直接参照する形になっていました。
結果は変わりませんが、関数の本来の意図とは異なる挙動だと思います。

# (誤)
sum(logpdf.(Poisson.(exp.(w[1].* X_obs .+ w[2])), Y_obs)) +

# (正)
sum(logpdf.(Poisson.(exp.(w[1].* X .+ w[2])), Y)) +

● p.215 コード記載、X_obs, Y_obsを直接参照している。引数の順番修正
p.215 コード記載の下から3、4行目本来引数XとYを使うところを、
X_obs, Y_obsを直接参照する形になっていました。
また、X, Yに修正した場合、引数順番を入れ替えないとエラーになります。

# (誤)
log_joint(w, X, Y) = hyper_prior(w) + prior(w) +
                    log_likelihood(Y_obs, X_obs, w)
# (正)
log_joint(w, Y, X) = hyper_prior(w) + prior(w) +
                    log_likelihood(Y, X, w)

● p.216 コード記載、変数xsの定義(エラーではない)
可視化範囲を決める変数xsの定義が直近で記載されていないため分かりづらかったです。
(p.213 まで遡れば確認できます)
コード上から7行目の下に以下のxsに関する記載を追記したほうが理解しやすかったです。

# (追記)
# 予測分布の可視化
# 関数を可視化する範囲
xs = range(0, 1, length=100)

● p.225 コード記載2行目

# (誤) 
σ₁ = 10.0

# (正)
 σ₀ = 10.0

以上です。
誤記は見つかりましたが、本書はとても良い本だと思います。
(良書だと思えるから、エラーの修正方法を試行錯誤できました)

 講談社サイエンティフィクさんには連絡済みなので、エラーが発生する誤りについては、著者サポートページへの記載や増刷時の修正などの対応がされるといいですね。(検証に時間かかると思いますが・・・)

ここまで記事を読んでいただきありがとうございました。
もし、みなさんのエラー解決の助けになれば嬉しいです。

この記事が気に入ったらサポートをしてみませんか?