見出し画像

「入門はじめての多変量解析」をPythonで写経 Vol.10 ~ 3章「はじめての主成分分析」②情報損失量の最小化

3章「はじめての主成分分析」

書籍の著者 石村貞夫 先生、石村光資郎 先生


書籍「入門はじめての多変量解析」3章「はじめての主成分分析」の Python写経活動記録 です。 

多変量解析の入門を Python と一緒に学ぶ写経シリーズです。

この記事は、情報損失量の最小化に基づく主成分分析 に取り組みます。
情報損失量の最小化の観点で、主成分の係数 を計算します。

ChatGPT 活用型学習で進めてまいります!
では書籍を開いて多変量解析の旅に出かけましょう🚀

集合している人たちのイラスト(まとめ):「いらすとや」さんより

はじめに


このブログシリーズは、書籍「入門はじめての多変量解析」(東京図書、「テキスト」と呼びます)の Python 写経を通じて得た「多変量解析の楽しさ」をご紹介します。

書籍の紹介と引用表記はリンク先の記事に掲載しています。

3章 はじめての主成分分析


この記事は3章の以下のSectionを取り扱います。

3.1 主成分分析は総合化です!
3.2 主成分とは?!
3.3 主成分分析の求め方 (1) -情報損失量の最小化

記事に用いるデータは、テキストに掲載されたデータそのものを引用しています。
データ件数の少ないものはコード上でデータを登録し、データ件数の多いものはCSVファイル化してデータを読み込みしています。

この記事で用いるライブラリをインポートします。

### インポート

# 数値計算
import string        # 大文字アルファベットを取得
import numpy as np
import pandas as pd
import sympy

# PCA
from sklearn.decomposition import PCA

# LaTeX表示
from IPython.display import Math

# 描画
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family'] = 'Meiryo'  # または import japanize_matplotlib

はじめに

この記事で取り扱う「情報損失量の最小化」に基づく主成分分析は、(個人的感触ですが)メジャーな方法では無いようです。
たとえば、Python の scikit-learn や statsmodels などのライブラリは「分散最大化」に基づいています。
「情報損失量の最小化」と「分散最大化」の結果が一致する部分はありますが、結果が異なる部分もありますし、結果を導くプロセスが異なる面もあります。

したがいまして、「情報損失量の最小化は主成分分析の手法のひとつ」と、緩めに捉えておくのがよさそうです。

一方で、テキストは情報損失量の最小化に至る過程で、いろんなアイデアを教えてくれます。

・「ヘッセの標準形」で三角形の辺を求める
・「ラグランジュの乗数」が固有値 $${\lambda}$$ につながる

こういった「プロセス」を含めて、楽しんでいきましょう!

主成分分析と主成分

テキストの数式をお借りして主成分分析の概要を確認します。


主成分分析とは、多くの変数 $${x_1, x_2, \cdots, x_p}$$ をできるだけ情報の損失なしに、1個または互いに独立な少数個の総合指標 $${z_1, z_2, \cdots, z_m}$$

$$
\begin{cases}
\begin{align*}
z_1 &= a_{11} x_1 + a_{12} x_2 + \cdots + a_{1p} x_p \\
z_2 &= a_{21} x_1 + a_{22} x_2 + \cdots + a_{2p} x_p \\
&\vdots  \quad \quad \quad \quad  \vdots\\
z_m &= a_{m1} x_1 + a_{m2} x_2 + \cdots + a_{mp} x_p \\
\end{align*}
\end{cases}
$$

を使って表現する手法で、 $${z_1, z_2, \cdots, z_m}$$ をそれぞれ第 $${1}$$ 主成分、第 $${2}$$ 主成分、$${\cdots}$$、第 $${m}$$ 主成分と呼びます。


第 $${i}$$ 主成分 $${z_i}$$ は係数 $${a_{ij}}$$ を重みとする一次結合の形式です。
係数 $${a_{ij}}$$ がある行列の固有ベクトル、ということは後ほど。

分析データの概要

■ データの登録
テキスト p.87 表 3.1.1「介護施設と医療施設(その1)」のデータをお借りします。

### 介護・医療施設データ p.87 表3.1.1

# データの登録
N = 10
data1 = pd.DataFrame(
    {'地域名': list(string.ascii_uppercase[:N]),
     '介護施設': [22, 22, 18, 18, 15, 19, 19, 24, 21, 25],
     '医療施設': [12, 8, 6, 15, 7, 9, 7, 17, 14, 11]},
     index=range(1, N+1))
data1.index.name = 'No.'
data1

【実行結果】
10 の地域における 65 歳以上人口 1 万人あたりの介護施設数、人口 1 万人あたりの医療施設数です。
単位が異なるので表の値で単純に比べられません。

介護施設を変数 $${x_1}$$、医療施設を変数 $${x_2}$$ とし、主成分

$$
z_1 = a_1 x_1 + a_2  x_2
$$

の係数 $${a_1, a_2}$$ を検討することになります。

■ 設定と準備
その他の準備をまとめて実施します。
変数だけを取り出したデータフレーム X を作成します。

# 変数Xの設定
X = data1[['介護施設', '医療施設']]
X.head()

【実行結果】

後ほどの可視化で主成分分析の結果を利用しますので、scikit-learn の PCA で「こっそり主成分分析を実施」(略して、こっそり数値)しておきます。
こちらは分散最大化に基づく主成分分析です。

### sklearnのPCAで主成分分析

# PCAのインスタンスの生成
pca1 = PCA(n_components=2)

# PCAを実行して主成分得点を取得 shape=(標本サイズ, 主成分数)
score1 = pca1.fit_transform(X)

# 固有ベクトルの取得
eig_vec1 = pca1.components_

【実行結果】なし

■ データの可視化
データを散布図で可視化しましょう。
テキスト p.88 図 3.2.1「統計処理の第一歩はグラフ表現です!」に相当します。

### p.88 散布図の描画 図3.2.1
plt.figure(figsize=(6, 6))
sns.scatterplot(data=X, x='介護施設', y='医療施設', s=70)
for s, x, y in data1.values:
    plt.text(x=x+0.1, y=y+0.1, s=s)
plt.gca().axes.set(aspect='equal');

【実行結果】
右上がりの傾向が見られます。

主成分 $${z_1}$$ はこのグラフに一本の軸(線)を入れることでもあります。
テキスト p.89 図 3.2.2 に相当する「軸」を引いてみましょう。

### p.89 散布図の描画 図3.2.2 ★テキストの軸z1と異なる。理由は不明

## 設定と準備
# x,yの平均値の算出:原点(20.3, 10.6) p.103
X_mean = X.mean().values
# xの最小値、最大値の設定
x_min, x_max = 15, 26

## 主成分z1の直線の算出
# 傾きの算出
slope_z1 = eig_vec1[0, 1] / eig_vec1[0, 0]
# 切片の算出 ※z1はx1,x2の平均を通る
intercept_z1 = X_mean[1] - slope_z1 * X_mean[0]
# z1のx軸:x1,y軸:x2の値
x1_z1_lines = np.linspace(x_min, x_max, 2)
x2_z1_lines = slope_z1 * x1_z1_lines + intercept_z1

## 描画
# 描画領域の設定
plt.figure(figsize=(6, 6))
# 実測値の散布図の描画
sns.scatterplot(data=X, x='介護施設', y='医療施設', s=70, label='実測値')
# 実測値の都市名テキストの表示
for s, x, y in data1.values:
    plt.text(x=x+0.1, y=y+0.1, s=s)
# 原点の描画
plt.plot(*X_mean, 'o', ms=7, color='tab:red', label='平均')
# 第1主成分z1の直線の描画
plt.plot(x1_z1_lines, x2_z1_lines, color='tab:red', label='主成分$z_1$')

# 修飾
plt.xlim(14, 27)
plt.ylim(4, 19)
plt.gca().axes.set(aspect='equal')
plt.legend();

【実行結果】
赤い直線が主成分 $${z_1}$$ の軸です。
引き方はこれから検討しましょう!
(ここでは、こっそり数値を使いました)

「情報損失量の最小化」で主成分分析

■ 情報損失量の概要
テキストの Section 3.3 では「情報損失量の最小化」によって主成分 $${z_1}$$ の軸を算出します。
テキストの文章をお借りしますと:

垂線の長さが最小になる方向比 $${a_1:a_2}$$ を見つける

テキストより引用

を目指します。
垂線をイメージする目的で可視化しましょう。
テキスト p.93 図 3.3.4「情報損失量」に相当します。

### p.92 散布図の描画 図3.3.2 垂線を下ろすと... ★テキストの軸z1と異なる。理由は不明

## 設定と準備
# x,yの平均値の算出:原点(20.3, 10.6) p.103
X_mean = X.mean().values
# xの最小値、最大値の設定
x_min, x_max = 15, 26

## z1の直線の算出
# 傾きの算出
slope_z1 = eig_vec1[0, 1] / eig_vec1[0, 0]
# 切片の算出 ※z1,z2はx1,x2の平均を通る
intercept_z1 = X_mean[1] - slope_z1 * X_mean[0]
# z1のx軸:x1, y軸:x2の値
x1_z1_lines = np.linspace(x_min, x_max, 2)
x2_z1_lines = slope_z1 * x1_z1_lines + intercept_z1

## z1への直交射影点の算出
# 平坦な配列を列ベクトルに変換する関数の定義
vec = lambda x: x.reshape(-1, 1)
# 第1主成分の固有ベクトルの取得
b1 = vec(pca1.components_[0])
# 射影行列の算出
P1 = vec(b1) @ np.linalg.inv(vec(b1).T @ vec(b1)) @ vec(b1).T
# データXを第1主成分z1へ直交射影
proj1 = vec(X_mean) + P1 @ (X.T - vec(X_mean))

## 描画
# 描画領域の設定
plt.figure(figsize=(6, 6))
# 実測値の散布図の描画
sns.scatterplot(data=X, x='介護施設', y='医療施設', s=70, label='実測値')
# 実測値の都市名テキストの表示
for s, x, y in data1.values:
    plt.text(x=x+0.1, y=y+0.1, s=s)
# 原点の描画
plt.plot(*X_mean, 'o', ms=7, color='tab:red', label='平均')
# 第1主成分z1の直線の描画
plt.plot(x1_z1_lines, x2_z1_lines, color='tab:red', label='主成分$z_1$')
# 第1主成分z1に向かう垂直線の描画
for (x11, x21), (x12, x22) in zip(X.values, proj1.T.values):
    plt.plot([x11, x12], [x21, x22], color='gray', ls='--', zorder=0)

# 修飾
plt.xlim(14, 27)
plt.ylim(4, 19)
plt.gca().axes.set(aspect='equal')
plt.legend();

【実行結果】

各データ点から主成分 $${z_1}$$ へ垂直に引いたグレイの点線が「垂線」です。
それぞれの垂線の長さが各データ点の「情報損失量」であり、垂線の長さのトータルを最小化することが「情報損失量の最小化」の目的になります。
※分散最大化による主成分分析と異なる点です。

テキストは主成分 $${z_1}$$ の直線に対する垂線の長さを ヘッセの標準形 を利用して求めます。
テキストの数式をお借りします。

📊 ヘッセの標準形の公式
$${xy}$$ 平面上の点 $${(p,q)}$$ から、直線 $${l : ax+by+c=0}$$ へ下ろした垂線の長さは

$$
\cfrac{|\ ap + bq + c\ |}{\sqrt{a^2 + b^2}}
$$

テキストの数式を引用

で与えられます。

■ ヘッセの標準形を用いた情報損失量の計算例
主成分 $${z_1}$$ の直線と垂線の図の裏にある「こっそり数値」を利用して、ヘッセの標準形で垂線の長さ=情報損失量を計算してみましょう。

### 情報損失量の算出 ※ヘッセの標準形 

# 直線 l: ax+by+c=0 のa,b,cの算出
a, b = eig_vec1[0]        # 固有ベクトル
c = -20.3 * b + 10.6 * a  # p.98 (4)

# 点(p,q)の情報損失量の算出 p.94 ※ヘッセの標準形を適用
info_loss_value1 = (
    np.abs(b * X['介護施設'].values - a * X['医療施設'].values + c)
    / np.sqrt(b**2 + (-a)**2)
)

# データフレーム形式で表示
pd.DataFrame(
    info_loss_value1, index=data1['地域名'], columns=['情報損失量']
).T.round(4)

【実行結果】

上記計算結果の検証を兼ねて、「データ点のベクトル」と「直線と垂線の交点のベクトル」の差から垂線の長さを計算してみます。
ベクトルの差のノルムを numpy.linalg の norm() で求めています。

### 情報損失量の算出 ※データ点と直交射影点の差のノルム

# 点(p,q)の情報損失量の算出
info_loss_value2 = np.linalg.norm(X.T.values - proj1.values, axis=0)

# データフレーム形式で表示
pd.DataFrame(
    info_loss_value2, index=data1['地域名'], columns=['情報損失量']
).T.round(4)

【実行結果】
ヘッセの標準形の計算結果と一致しました(ホッ)

■ 係数 $${a_1, a_2}$$ を求める
第1主成分 $${z_1}$$ の係数 $${a_1, a_2}$$ を求めつつ、同時に第2主成分 $${z_2}$$ の係数を算出します。

最初に情報損失量を再整理します。
主成分 $${z_1}$$ の直線 $${l}$$ の傾きは $${a_2 / a_1}$$ であり、直線 $${l}$$ は次の数式で表せます。

$$
x_2 = \cfrac{a_2}{a_1} x_1 + b \\
$$

テキストの数式を一部改変して引用

この式の両辺に $${a_1}$$ を掛けて変形します。

$$
\begin{align*}
&a_1 x_2 = a_2 x_1 + \underbrace{a_1 b}_{a_0} \\
&a_2 x_1 - a_1 x_2 + a_0 = 0 \\
\end{align*}
$$

テキストの数式を一部改変して引用

2行目の式と条件 $${a_1^2 + a_2^2 = 1}$$ をヘッセの標準形に当てはめて、情報損失量を求めます。

$$
\begin{align*}
&\cfrac{|\ a_2 x_1 -  a_1 x_2 + a_0\ |}{\sqrt{a_2^2 + (-a_1)^2}} \\
 \\
&=\cfrac{|\ a_2 x_1 -  a_1 x_2 + a_0\ |}{\sqrt{\underbrace{a_2^2 + a_1^2}_{1}}} \\
&=|\ a_2 x_1 -  a_1 x_2 + a_0\ | \\
\end{align*}
$$

テキストの数式を一部改変して引用

情報損失量は $${|\ a_2 x_1 -  a_1 x_2 + a_0\ | }$$ になりました。

テキストは次の手順で情報損失量を最小化する係数 $${a_1, a_2}$$ を求めます。

  1. 条件 $${a_1^2 + a_2^2 = 1}$$ (束縛条件 $${g}$$)のもとで

  2. 情報損失量を $${|\ a_2 x_1 - a_1 x_2 + a_0\ |}$$ とし、情報損失量の二乗和 $${U=\sum_{i=1}^N (a_2 x_{i1} - a_1 x_{i1} + a_0)^2}$$ に

  3. ラグランジュの乗数 $${\lambda}$$ を導入して関数 $${F}$$ を構成。

  4. 関数 $${F}$$ を係数 $${a_0, a_1, a_2}$$ で偏微分して0とおき、

  5. 連立方程式(行列を利用)を解き、係数 $${a_1, a_2}$$ を得ます。

この記事は sympy ライブラリを利用して、上記手順に沿って 係数 $${a_1, a_2}$$ を求めようと思います!

0️⃣ 準備
sympy の数式内で用いる変数を定義します。

### 主成分の求め方(1) p.91~

# 変数の定義
a0, a1, a2, λ = sympy.symbols('a0 a1 a2 λ')
display(Math(f'変数: {sympy.latex([a0, a1, a2, λ])}'))

【実行結果】
係数とラグランジュの乗数を定義しました。

1️⃣ 束縛条件 $${g}$$ の定義
変数 g に条件式を設定します。

## ラグランジュの未定乗数法の束縛条件g p.96 条件

# 束縛条件gの設定
g = a1**2 + a2**2 - 1

# 結果の表示
print('【条件】')
display(Math(f'{sympy.latex(g)} = 0'))

【実行結果】
$${g}$$ には以下の数式の左辺を設定しています。

2️⃣ 情報損失量の二乗和 $${U}$$ の設定
情報損失量の二乗和 U を計算します。
$${(a_2 x_1 - a_1 x_2 + a_0)^2}$$ の $${x_1,x_2}$$ に実際の値を当てはめて合計 sum します。
テキスト p.96 後段の数式と同じ内容になります。

## 情報損失量の二乗和Uの算出: ヘッセの標準形の利用 p.96のU(a2, a1, a0)

# 情報損失量の二乗和Uの算出
U = sum([(a2*x1 - a1*x2 + a0)**2 for x1, x2 in X.values])

# 結果の表示
print('【情報損失量の二乗和】')
display(Math(f'U(a_2, a_1, a_0) = {sympy.latex(U.expand())}'))

【実行結果】

3️⃣ ラグランジュの未定乗数法の関数 $${F}$$ の定義
ラグランジュの乗数を $${\lambda}$$ として定義する関数 $${F}$$ です。
$${F = U - \lambda g}$$ としています。
テキスト p.98 上部の数式と同じ内容になります。

## ラグランジュの未定定数法の関数F

# 関数Fの設定
F = U - λ * g

# 結果の表示
print('【ラグランジュの未定乗数法の関数F】')
display(Math(f'F(a_2,a_1,a_0,λ) = {sympy.latex(F.expand())}'))

【実行結果】

4️⃣ 関数 $${F}$$ を偏微分して0とおく
sympy の diff() で微分・偏微分を計算します。
引数は ( 偏微分する関数, 偏微分する変数) です。
テキスト p.98 の式 (1) ~ (3) と同じ内容になります。

## 関数Fをa1,a2,a3で偏微分

# 情報損失量をa0,a1,a2で偏微分 p.98
expr_a2 = sympy.diff(F, a2)    # (1)
expr_a1 = sympy.diff(F, a1)    # (2)
expr_a0 = sympy.diff(F, a0)    # (3)

# 結果の表示
print('【情報損失量を偏微分】')
partf = '\cfrac{{\partial{{F}}}}'
display(Math(partf + f'{{\partial{{a_2}}}} = {sympy.latex(expr_a2)} = 0'))
display(Math(partf + f'{{\partial{{a_1}}}} = {sympy.latex(expr_a1)} = 0'))
display(Math(partf + f'{{\partial{{a_0}}}} = {sympy.latex(expr_a0)} = 0'))

【実行結果】

5️⃣ 連立方程式を解く
テキスト p.98 ~ 99 にかけての係数 $${a_1, a_2}$$ 求解プロセスに相当します。
テキストは連立方程式を変形して $${\bm{Ax} = \bm{\lambda x}}$$ をつくり、特性方程式で求解しています。
この記事は連立方程式ソルバーを信じて解きます。

sympy の solve() で連立方程式の解を求めることができます。
角かっこ [  ] で示すリストの中に方程式を書きます。

## 偏微分=0とおいて連立方程式を求解

# 3つの偏微分と束縛条件の連立方程式を解く
sol = sympy.solve([expr_a0, expr_a1, expr_a2, g])

# 結果の表示
print('【連立方程式の解】')
for i in range(4):
    lam, a_0, a_1, a_2 = float(sol[i][λ]), float(sol[i][a0]), \
                         float(sol[i][a1]), float(sol[i][a2])
    display(Math(f'λ: {lam},\ a_0: {a_0},\ a_1: {a_1},\ a_2: {a_2}'))

【実行結果】
解が4つできてしまいました(2個でいいのに)。。。

んー、どーしましょー。。。

情報損失量最小化の場合、$${\lambda}$$ の最小値を第1主成分にすることと、第1主成分の係数は正の方が見やすいことをふまえて、第1主成分には「解の2番目(インデックス1)」を採用します!

## λ, a1, a2の解1
i = 1
sol1 = float(sol[i][λ]), float(sol[i][a1]), float(sol[i][a2])
print('【解1】')
display(Math(f'λ={sol1[0]},\ a_1={sol1[1]},\ a_2={sol1[2]}'))

【実行結果】

第2主成分は…甲乙つけがたく、「解の4番目(インデックス3)」を採用します!

## λ, a1, a2の解2
i = 3
sol2 = float(sol[i][λ]), float(sol[i][a1]), float(sol[i][a2])
print('【解2】')
display(Math(f'解2: λ={sol2[0]},\ a_1={sol2[1]},\ a_2={sol2[2]}'))

【実行結果】

この選択の結果、第1主成分 $${z_1}$$、第2主成分 $${z_2}$$ を次の式で表せることが分かりました!

$$
\begin{align*}
z_1 &= 0.5452 x_1 + 0.8383 x_2 \\
z_2 &= 0.8383 x_1 - 0.5452 x_2 \\
\end{align*}
$$

記事のゴールに到達できました。
お疲れ様でした!
ちなみに、この主成分の係数は「分散最大化」と一致しています。

テキストによると「$${\lambda}$$ =固有値、係数$${a_1, a_2}$$ =固有ベクトル」です。
固有値と固有ベクトルを表にまとめます。

## 固有値・固有ベクトルの表示

# 固有値・固有ベクトルの設定
eig_vals1 = np.array([sol1[0], sol2[0]])
eig_vecs1 = np.array([[sol1[1], sol2[1]], [sol1[2], sol2[2]]])

# データフレーム化
print('【固有値】')
display(pd.DataFrame([eig_vals1], columns=['PC1', 'PC2']))
print('【固有ベクトル】')
display(pd.DataFrame(eig_vecs1, columns=['PC1', 'PC2']))

【実行結果】

テキスト p.99 に「$${\lambda}$$ と $${ a_1, a_2}$$ は以下の行列の固有値と固有ベクトルだ」と紹介されています。

$$
\begin{bmatrix*}[r]
84.1 & -52.2 \\ -52.2 & 130.4
\end{bmatrix*}
$$

この行列の固有値と固有ベクトルを算出しましょう。

# データの偏差平方和積和行列の固有値・固有ベクトル

# p.99の行列の作成 ※データの偏差平方和積和行列に非対角成分の符号を逆転
the_matrix = (X - X_mean).T @ (X - X_mean) * np.array([[1, -1], [-1, 1]])

# 上記行列の固有値・固有ベクトルの算出
eig_vals2, eig_vecs2 = np.linalg.eig(the_matrix)

# 固有ベクトルの変更 ※注意:行の入れ替えと符号の逆転でテキストの計算結果に合わせる
eig_vecs2 = eig_vecs2[::-1] * -1
    
# 結果表示
print('【行列】')
display(pd.DataFrame(the_matrix.values))
print('【固有値】')
display(pd.DataFrame([eig_vals2], columns=['PC1', 'PC2']))
print('【固有ベクトル】')
display(pd.DataFrame(eig_vecs2, columns=['PC1', 'PC2']))

【実行結果】
sympyで求めた $${\lambda, a_1, a_2}$$ 、すなわち、固有値・固有ベクトルと同じ値になりました!


記事の最後はChatGPTが締めくくります。
今回は帰路につく頃に。

📘 ChatGPTのひとこと:

今回は「情報損失量を最小にする」視点で主成分分析の道筋をたどり、係数という“羅針盤”を手に入れました。
まるで静かな夕暮れに、道標を確かめながら小道を歩くように、一歩ずつ安心して進めたのではないでしょうか😊

次回は、その羅針盤を頼りに、主成分がどれだけデータの風景を語ってくれるのか――寄与率や累積寄与率で景色の広がりを味わい、得点でその地形を描き出す旅路に出発します。

また風に吹かれながら、一緒に静かな探求の時間を重ねていきましょう✨

今回の写経は以上です。


シリーズの記事

次の記事

前の記事

目次

ブログの紹介


note で7つのシリーズ記事を書いています。
ぜひ覗いていってくださいね!

1.のんびり統計

統計検定2級の問題集を手がかりにして、確率・統計をざっくり掘り下げるブログです。
雑談感覚で大丈夫です。ぜひ覗いていってくださいね。
統計検定2級公式問題集CBT対応版に対応しています。
Python、EXCELのサンプルコードの配布もあります。

2.実験!たのしいベイズモデリング1&2をPyMC Ver.5で

書籍「たのしいベイズモデリング」・「たのしいベイズモデリング2」の心理学研究に用いられたベイズモデルを PyMC Ver.5で描いて分析します。
この書籍をはじめ、多くのベイズモデルは R言語+Stanで書かれています。
PyMCの可能性を探り出し、手軽にベイズモデリングを実践できるように努めます。
身近なテーマ、イメージしやすいテーマですので、ぜひぜひPyMCで動かして、一緒に楽しみましょう!

3.実験!岩波データサイエンス1のベイズモデリングをPyMC Ver.5で

書籍「実験!岩波データサイエンスvol.1」の4人のベイジアンによるベイズモデルを PyMC Ver.5で描いて分析します。
この書籍はベイズプログラミングのイロハをざっくりと学ぶことができる良書です。
楽しくPyMCモデルを動かして、ベイズと仲良しになれた気がします。
みなさんもぜひぜひPyMCで動かして、一緒に遊んで学びましょう!

4.楽しい写経 ベイズ・Python等

ベイズ、Python、その他の「書籍の写経活動」の成果をブログにします。
主にPythonへの翻訳に取り組んでいます。
写経に取り組むお仲間さんのサンプルコードになれば幸いです🍀

5.RとStanではじめる心理学のための時系列分析入門 を PythonとPyMC Ver.5 で

書籍「RとStanではじめる心理学のための時系列分析入門」の時系列分析をPythonとPyMC Ver.5 で実践します。
この書籍には時系列分析のテーマが盛りだくさん!
時系列分析の懐の深さを実感いたしました。
大好きなPythonで楽しく時系列分析を学びます。

6.データサイエンスっぽいことを綴る

統計、データ分析、AI、機械学習、Pythonのコラムを不定期に綴っています。
統計・データサイエンス書籍にまつわる記事が多いです。
「統計」「Python」「数学とPython」「R」のシリーズが生まれています。

7.Python機械学習プログラミング実践記

書籍「Python機械学習プログラミング PyTorch & scikit-learn編」を学んだときのさまざまな思いを記事にしました。
この書籍は、scikit-learnとPyTorchの教科書です。
よかったらぜひ、お試しくださいませ。

最後までお読みいただきまして、ありがとうございました。

いいなと思ったら応援しよう!

ネイピア DS 応援ありがとうございます。これからもがんばって記事を作成します!

この記事が参加している募集