くますきIT日記

IT系資格、競技プログラミングの情報を書いていきます。

E資格の勉強③深層学習day1

目次

1 本投稿の目的

深層学習(day1)に関する学習のまとめ

2 Section1:入力層~中間層

入力層 → 中間層 → 出力層

【要点】

入力層:

 ニューラルネットワークが入力を受け取る部分。

 任意の数の変数(ノード)を受け取る。(x1,x2,・・xN)と表現。

中間層: 

 入力層→出力層の間にある層。

 ※入力層からの最初の出力は中間層(1層目)が受け取る。

 この時、各変数に個別に設定された重み(w1,w2・・wN)を掛けた合計値(+バイアス項もある)を入力とする。

 入力に対して活性化関数を実施した値を、次の層(中間層or出力層)に渡す。

 

【考察結果】

確認テスト1:各変数に動物分類の実例を入れてみよう。

入力層:

 x1,x2,・・xN → 身長(cm)、体重(g)、耳の長さ(mm)。

中間層の入力:

 上記に各重み(w)を掛けた値の合計(総入力)

 ※ポイント:重みは要素の重要度に依存する。重要度(高)の要素ほど重みが大きくなる。

 

確認テスト2:以下数式をPythonで書け。

 W =[W1,W2,W3,W4]

 X =[W1,W2,W3,W4]

 u = W1X1 + W2X2 + W3X3 + W4X4 + b ← この数式(行列の掛け算+b)

 (回答)

import numpy as np
u = np.dot(x, W) + b # np.dot(行列のドット積)

 

確認テスト3:中間層の出力を定義しているソースを抜き出せ。

 (回答)

# 2層の総入力
u2 = np.dot(z1, W2) + b2

# 2層の総出力
z2 = functions.relu(u2)

 

【実装演習】

演習ソース

# 重み
W = np.array([
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6]
])

print_vec("重み", W)

# バイアス項
b = np.array([0.1, 0.2, 0.3])
print_vec("バイアス", b)

# 入力値
x = np.array([1.0, 5.0, 2.0, -1.0])
print_vec("入力", x)

# 総入力
u = np.dot(x, W) + b
print_vec("総入力", u)

# 中間層出力
z = functions.sigmoid(u)
print_vec("中間層出力", z)

 

実行結果

*** 重み ***
[[0.1 0.2 0.3]
[0.2 0.3 0.4]
[0.3 0.4 0.5]
[0.4 0.5 0.6]]

*** バイアス ***
[0.1 0.2 0.3]

*** 入力 ***
[ 1. 5. 2. -1.]

*** 総入力 ***
[1.4 2.2 3. ]

*** 中間層出力 ***
[0.80218389 0.90024951 0.95257413
 

→ 総入力 =「入力」と「重み(W)」のドット積 + バイアス項

 中間層出力 = シグモイド関数(総入力)

 となっている事を確認できる。

 ※シグモイド関数:入力を「0~1の範囲」の数値に変換する関数。後述するのでここでは詳しく記述しない。

 

3 Section2:活性化関数

入力層中間層 出力層

【要点】

活性化関数:値を非線形に変換する関数。出力を次の層に渡す前に使用する。

Section1で行っていた「 W1X1 + W2X2 + W3X3 + W4X4 + b・・」は線形の処理。これを線形の出力に変換する事が目的。

 

中間層で利用する活性化関数。

・ステップ関数(現在はほぼ利用されていない)

 ある一定の点を境に、出力が変わる関数。(0 or 1)

シグモイド関数

 数式:f(u) = 1/ (1+ e^-w)

 値を0~1の範囲に変換する関数。ネイピア数を使用しており、微分が容易にできる。

・ReLU関数

 ある一定の点を境に、出力が変わる関数。

  ある一点を満たしていない = 0

  ある一点を満たす = 0~1の範囲

 

出力層で利用する活性化関数。※「出力層の活性化関数」を参照。

・ソフトマックス関数

・恒等写像

シグモイド関数

 

【考察結果】

確認テスト1:線形と非線形の違いを図に書いて簡易に説明せよ。

 

線形:直線としてグラフに表示できる。

f:id:you_it_blog:20211012233852p:plain

非線形:直線としてグラフに表示できない。※厳密には「線形が満たす条件を満たしていない」もの。

f:id:you_it_blog:20211012234114p:plain

※グラフの作成には以下を使用した。

www.geogebra.org

 

確認テスト2:配布されたソースコードの該当する箇所を抜き出せ。

※活性化関数の使用箇所

 (回答)

y = functions.sigmoid(u2)

 

【実装演習】

演習ソース

# 重み
W = np.array([
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6]
])

# バイアス項
b = np.array([0.1, 0.2, 0.3])

# 入力値
x = np.array([1.0, 5.0, 2.0, -1.0])

# 総入力
u = np.dot(x, W) + b
print_vec("総入力", u)

# 中間層出力
z = functions.sigmoid(u)
print_vec("中間層出力", z)

 

実行結果

*** 総入力 ***
[1.4 2.2 3. ]

*** 中間層出力 ***
[0.80218389 0.90024951 0.95257413

→「総入力」と「中間層出力」の違いに注目。

 シグモイド関数により、値の大小関係を維持したまま、値が0~1の範囲に変換されている。

 

4 Section3:出力層

入力層 → 中間層 出力層

【要点】

出力層:

 最終的なデータを出力する層。

 「中間層の出力 → 次の層の入力に使用するための値」であるが、

 「出力層の出力 → 人間が使用したい値」

 分類問題の場合は、該当の分類である確率であったり、

 回帰問題の場合は、想定される値(数値) となる。

誤差関数:

 出力層の出力と、正解(ラベル)の誤差を比較する関数。

 ※学習で使用した誤差関数は二乗和誤差。全ての誤差を2乗したものの総和 / 2

出力層の活性化関数:

 中間層の活性化関数とは異なる。(中間層とは出力する値の使い方が異なるため)

・恒等写像

 回帰問題の場合に使用する。値を何も加工しない。

 ※ 確率などでなく、値を知りたい(出力させたい)ため、加工する必要が無い。

 使用する誤差関数は2乗和誤差。

シグモイド関数

 分類問題(2クラス)の場合に使用する。値を0~1の範囲に変換する関数。

 使用する誤差関数はクロスエントロピー

・ソフトマックス関数

 分類問題(3クラス)の場合に使用する。値を0~1の範囲に変換する、かつ全確率の総和を1とする関数。

 使用する誤差関数はクロスエントロピー

 

【考察結果】

★誤差関数について★

確認テスト1:なぜ、引き算でなく2乗するか。また、「/2」はどういう意味を持つか。

 (回答:2乗する理由)

 符号の違いの考慮を無くすため。2乗すると、値は2乗されが、ラベルと出力の純粋な距離を取得できる。

 (回答:「/2」する理由)

 誤差から重みとバイアス項を修正する(誤差逆伝搬)のときに、微分を簡単にするため。本質的な意味はない。

 

★活性化関数について★

確認テスト1:ソフトマックス関数の数式に該当するソースコードを示し、1行ずつ処理の説明をせよ。

(ソフトマックス関数の数式)

f:id:you_it_blog:20211013110236p:plain

※数式取得元は以下。

ja.wikipedia.org

(回答 ※「★」=追加した説明コメント)

# ソフトマックス関数
def softmax(x):
# ★:ミニバッチの場合(概ね実装は同じ)
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T

# ★:ミニバッチ以外の場合
x = x - np.max(x) # オーバーフロー対策
# ★:np.exp(x) → 数式の分母にあたる部分
# ★:np.sum(np.exp(x)) → 数式の分子にあたる部分
return np.exp(x) / np.sum(np.exp(x))

 

★誤差関数について★

確認テスト1:交差エントロピーの式に該当するソースコードを示し、1行ずつ処理の説明をせよ。

(回答 ※「★」=追加した説明コメント)

def cross_entropy_error(d, y):
if y.ndim == 1:
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)

# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if d.size == y.size:
d = d.argmax(axis=1)

batch_size = y.shape[0]
# ★:重要なのは「-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))
# ★:y:ラベル(正解:1、不正解:0) dnnの出力
# ★:1e-7:対数関数の答が「-∞」になることを防止するための値。
# ★:最終的に値を「-」することでlogの「-」を正数に変換する。
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size

 

【実装演習】

演習ソース:

誤差関数(2乗和誤差)の実装

# 平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2

誤差関数を使用

# 入力値
x = np.array([1., 2.])
network = init_network()
y, z1 = forward(network, x)
# 目標出力
d = np.array([2., 4.])
# 誤差
loss = functions.mean_squared_error(d, y)
## 表示
print_vec("出力", y)
print_vec("訓練データ", d)
print_vec("誤差", loss)

実行結果

*** 出力 ***
[1.02 2.29]

*** 訓練データ ***
[2. 4.]

*** 誤差 ***
0.9711249999999999

→yとdの誤差量が「誤差」として出力される。

 

5 Section4:勾配降下法

入力層 → 中間層 → 出力層

入力層中間層 ← 出力層 ※重みやバイアス項の修正に関係する。

【要点】

勾配降下法:

 深層学習※のそもそも目的 → 学習結果を通じて、重さ(W)やバイアス項(B)を「最も誤差が発生しない値 = 傾きが0になる値」に修正すること。

 ※深層学習 = 層が4層以上存在するNN。= 中間層が2層以上存在するNN。

 勾配降下法は、重さ(W)やバイアス項(B)を修正するための方法。

  

学習率: 

 誤差を反映させるときの割合。適切な値に設定する事が重要。

  →大きすぎる場合:振り子を強く振ったように、振り幅がどんどん大きくなる =発散してしまう。

  →小さすぎる場合:振り子を弱く振ったように、振り幅は小さい(最適解にゆっくり近づく。)が、ふり幅が弱いと、「誤差が小さいが最適解でない場所(=局所解)」から動けなくなる可能性がある。

 

勾配降下法の種類:

確率的勾配降下法(SGD):

 エポックごとに、学習データから一部をランダムに選んで学習する。

 確率的勾配降下法は、このような事が無い。また、オンライン学習(後述の確認テストを参照)も利用可能。

・バッチ勾配降下法:

 全データを一括学習 → 誤差を一気に修正する方法。

 ※データの追加時、全データを再度使用する必要がある。

・ミニバッチ勾配降下法:

 バッチ学習と確率的勾配降下法(SGD)の混合のような手法。

 データを一定単位のミニバッチにまとめる。

 ミニバッチ単位で学習を行い、全ミニバッチの誤差の平均を用いて誤差を修正する。

 → バッチ勾配降下法は「1命令1データ」 = 並列実行が不可能であるが、

  ミニバッチ勾配降下法は「1命令複数データ」 = 並列実行が可能。

 

【考察結果】

確認テスト1:オンライン学習とは何か。2行でまとめよ。

(回答)

 学習データの追加時に、都度パラメータを修正して、学習する方法。

 ※全データを一気に使用するバッチ学習では行えない。(毎回全データを使用することになり、現実的でない)

 

確認テスト2:勾配降下法の以下数式の意味を図に書いて説明せよ。

「W(t+1) = W(t) - ε∇Et」

 

(回答)

※Wに関する説明なので、バイアス項(B)についての説明は省略している。

―――――――――――――――――――――――――

エポック|  重み

―――――――――――――――――――――――――

t   |  Wt →→↓

    |      ↓ - ε∇Et (※誤差×学習率 = 改善)

t+1 |  Wt+1  ← ※前回のWに改善を行った値=次エポックのW

・   |  ・

t+n |  Wt+n

―――――――――――――――――――――――――

※考察

 この説明については「超AI入門講座」の「スタートテスト(一般)」で見た記憶がある。万一分からない場合、「超AI入門講座」にて復習する事にする。

 

 

6 Section5:誤差逆伝搬法

入力層 → 中間層 → 出力層

入力層中間層 ← 出力層 ※重みやバイアス項の修正に関係する。

【要点】

数値微分で更新量を求めると、入力層側ほど、更新量を求めるのが大変。

出力層側の同じ計算を何回も行うことになる・・。

 

誤差逆伝搬では、一度求めた更新量を再利用して、更新量を簡単に、高速に求める事ができる。(微分の連鎖率を使用する)

※この説明については「超AI入門講座」で分かりやすい解説がある。

連鎖率はプログラム関係ない数学の知識。以下が参考になる。

※このサイトは数学に関して何かとお勧めである。

manabitimes.jp

 

 

 

 

【考察結果】

確認テスト1:誤差逆伝搬法では不要な再帰処理を避けることができる。既に行った計算方法を保持しているソースコードを抽出せよ。

(回答 ※「★」=追加した説明コメント)

# 誤差逆伝播
def backward(x, d, z1, y):
print("\n##### 誤差逆伝播開始 #####")

grad = {}

W1, W2 = network['W1'], network['W2']
# 出力層でのデルタ
delta2 = functions.d_sigmoid_with_loss(d, y) ★ここ。「delta2」★
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
# 中間層でのデルタ
delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1) ★「delta2」を流用★

→delta2を流用して、中間層の更新量の取得に使用している。

 これにより、計算量を「層の数-1」に抑えることができる。

 単純な数値微分では、計算量は「(層の数+1) × 層数/2」になる。

 ※いわゆるガウスの足し算。

mosipro.com

 

確認テスト2:2つの空欄に該当するソースコードを探せ

①∂E/∂y  ∂y/∂u

(回答)

delta2 = functions.d_mean_squared_error(d, y)

 

②∂E/∂y  ∂y/∂u  ∂u/∂w2ji

(回答)

# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)

 

→上記は微分の連鎖例なので「/」に注意。割り算でない。「a/b」→「aをbで微分した物」という意味。あとは、重み(W)とバイアス項(B)の微分を行う際、偏微分を行っていることに注意。(分からないなら、「超AI入門講座」を再確認する)

 

 

E資格の勉強②機械学習レポート

目次

1 本投稿の目的

機械学習に関する学習のまとめ

2 線形回帰モデル

【概要】

教師データありの回帰手法(回帰問題を解くためのモデルの1つ)

入力:m次元のパラメータ

出力:入力の線形結合※予測値は^(ハット)をつける。

パラメータの誤差は最小二乗法で推定する。

 

【ハンズオン】

ボストンの住宅データセットから住宅価格の最適な査定を行ってみる。

######################
# 線形回帰
######################
# モジュールをインポート
from sklearn.datasets import load_boston
from pandas import DataFrame
import numpy as np
from sklearn.linear_model import LinearRegression # 線形回帰モジュール

# データセットインスタンス
dataset = load_boston()
# print(dataset) # {'data': array([[6.3200e-03, 1.8000e+01],・・

# データフレーム作成
df = DataFrame(data=dataset.data, columns=dataset.feature_names)
df["PRICE"] = np.array(dataset.target)

######################
# パターン①線形単回帰分析(説明変数が1)
######################
# 説明変数(部屋数)と目的変数を設定
data = df.loc[:, ["RM"]].values
target = df.loc[:, ["PRICE"]].values

# 線形回帰インスタンス生成
model = LinearRegression()
# model.get_params() パラメータの確認
model.fit(data, target) # パラメータの推定

# 未知のデータを予測(部屋数1の価格は?)
print(model.predict([[1]]))
# [-25.5685118] → 価格が負数(明らかにおかしい) → 部屋数1という学習データが無いため予測ができない(外挿)

# 未知のデータを予測(外挿でない「部屋数6」の価格は?)
print(model.predict([[6]]))
# [19.94203311] → 妥当かもしれない価格を取得できた。

######################
# パターン②線形重回帰分析(説明変数が複数)
######################
# 説明変数(犯罪率と部屋数)と目的変数を設定
data = df.loc[:, ["CRIM", "RM"]].values
target = df.loc[:, ["PRICE"]].values

# 線形回帰インスタンス生成
model = LinearRegression()
# model.get_params() パラメータの確認
model.fit(data, target) # パラメータの推定

# 未知のデータを予測1(犯罪率0.3で部屋数4の価格は?)
print(model.predict([[0.3, 4]]))
# 4.24007956
# 未知のデータを予測2(犯罪率0.3で部屋数5の価格は?)
print(model.predict([[0.3, 5]]))
# 12.6311478
# → 部屋数が1つ増えると価格は急激に上昇。部屋数の方が重要度が高い?と思われる。

【ハンズオン後の考察】

外挿問題について、今回は「価格が負数」という分かりやすい問題となっていたが、

分析データによっては、外挿問題が発生していることに気付かない可能性もあると思われる。学習結果について、以下のような方法で検証が必要と思われる。

 ・正常と不正な出力の基準を明確にして、不正な結果が出力されないか。

 ・実務担当者による判定結果と比較して、想定外の差異が無いか。

 

 

【関連記事】

後述のロジスティック回帰は教師データありの分類手法。
回帰と分類の違いは、以下URLが分かりやすかった。

aiacademy.jp

 

3 非線形回帰モデル

【概要】

線形でない現象に対する回帰手法

入力、出力、パラメータの誤差:線形回帰と同様

汎化性能を失う過学習に注意する必要がある。(線形回帰も注意が必要)
過学習の防止にはいくつか手法があるが、オーソドックスなものは正則化法(罰則法)

 ・L2ノルムを利用したRidge推定量でパラメータを0に近づける

 ・L1ノルムを利用したLasso推定量でパラメータを0にする

過学習が発生する場合、汎化性能を失う→学習データ以外の分析精度が低下する。

 

【ハンズオン】

非線形のデータを適切に予測できるモデルを作成する。

######################
# 非線形回帰
######################
# モジュールをインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.kernel_ridge import KernelRidge


def true_func(x):
return 1 - 48 * x + 218 * x ** 2 - 315 * x ** 3 + 145 * x ** 4


# データ(散布)生成
n = 100
data = np.random.rand(n).astype(np.float32)
data = np.sort(data)
target = true_func(data) # 非線形のグラフを作成
# 散布にノイズを付与
target = target + 0.5 * np.random.randn(n)

# データ(散布)を描画
plt.scatter(data, target, color='blue', label='data')
plt.title('NonLinear Regression')

# 非線形回帰(カーネルリッジ回帰)インスタンスを生成
clf = KernelRidge(alpha=0.0002, kernel='rbf')
data = data.reshape(-1, 1) # 2次元1列の配列への変形
target = target.reshape(-1, 1) # 2次元1列の配列への変形
# 学習
clf.fit(data, target)
p_kridge = clf.predict(data)

# 学習結果を描画
plt.plot(data, p_kridge, color='red', linestyle='-', linewidth=3, markersize=6, label='kernel ridge')
plt.legend()

plt.savefig("test.png")

作成した画像ファイルは以下の通り。
(非線形の分布にフィットしたグラフを作成できている!)

f:id:you_it_blog:20211005233937p:plain

 

【関連記事】

非線形回帰の理解には以下サイトがとっかかりとして良かった。

www.gixo.jp

 

4 ロジスティック回帰モデル

【概要】

教師データありの分類手法(分類問題を解くためのモデルの1つ)

※名称に「回帰」とついているが、分類手法。紛らわしい・・。

入力:数値とm次元パラメータの線形結合をシグモイド関数※に入力

   ※入力値を0~1の範囲の数値に変換する関数の一つ。

    シグモイド関数は1/( 1+exp ^-ax)。

    「a」を使用する場合、aが1以下で小さいほど、緩やかな出力となる。

出力:0 or 1の2択に対して1となる確率。コインの裏表や、~する、しない等。

誤差関数には尤度関数を使用する。

 

【ハンズオン】

タイタニック号の乗客の生存状況を学習して、特定の条件[男性、30歳]にて生存できるか確認する。

######################
# ロジスティック回帰
######################
# モジュールをインポート
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression

# sklearnに付属している実験用データセットを読み込む
# データセットについての説明:https://www.openml.org/d/40945
titanic = fetch_openml(data_id=40945, as_frame=True)

# 必要な説明変数を取得(2列目:性別 、3列目:年齢)
x = titanic.data.to_numpy()[:, [2, 3]]
# 性別を数値に変換する。(male1,female0)
x[:, 0] = (x[:, 0] == 'male').astype(float)
x = x.astype(float)

# 欠損値が存在しない添え字の一覧を取得
# 一覧 = ~[反転](性別が欠損している索引の一覧 or 年齢が欠損している索引の一覧)
idx = ~(np.isnan(x[:, 0]) + np.isnan(x[:, 1]))
# 説明変数を絞り込み。(欠損値が存在しない索引に絞り込み)
x = x[idx]
# 目的変数を取得(欠損値が存在しない索引を取得)
y = titanic.target.to_numpy().astype(float)[idx]

# インスタンスを生成
model = LogisticRegression()
# 学習
model.fit(x, y)
# 未知のデータを判定。(男性、30)
print(model.predict([[1, 30]]))
# →[0.] = 生存できない

 

【関連記事】
使用したデータセットに関する説明。

説明変数と目的変数についての説明や、データの分布を確認できる。

www.openml.org

 

5 主成分分析

【概要】

複数の変数を1つに変換する。(次元の圧縮)

正しく利用することで、以下を実現する事ができる。

 ・使用する変数を減らして計算を簡単にする。

 ・(2~3次元に圧縮できる場合)データの可視化(=図への変換)が可能となる。

 

変換する際、線形変換後の値の分散が最大となる軸を探索する必要がある。

※線形変換後に全く値が散らばらない軸を使用すると、

 変換した値による分析が不可能となる。

 

探索はラグランジュ関数を微分して行う。

【用語】

寄与率:線形変換後の値が元々の情報と比較してどれほどの情報量を持っているか。

累積寄与率:各主成分の寄与率を大きい順に足し込んだ値。

 

【ハンズオン】

乳がん検査データ(32次元)を2次元に圧縮する。

また、圧縮したデータで適切に判定を実施できるか確認する。

######################
# 主成分分析
######################
# モジュールをインポート
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

# 乳がんデータセットを読み込む
cancer_ds = load_breast_cancer()

df_target = pd.DataFrame(cancer_ds.target, columns=["target"])
df_data = pd.DataFrame(cancer_ds.data, columns=cancer_ds.feature_names)
df = pd.concat([df_target, df_data], axis=1)

# 必要な説明変数を取得(備考:列番号でなく列名でも取得できる)
# dfから「全行」かつ「mean radius」列以降の列の情報を取得
# このデータセット1列目がtargetなので、上記の絞り込みで、目的変数を除いた全ての説明変数を取得できる。
x = df.loc[:, "mean radius":]
# 目的変数を取得(今回は欠損値が存在しない前提)
y = df.target

# データの標準化(データの大小を異なる項目間で比較できるようにする)
# ※主成分分析はデータの標準化を必ず実施する※
# https://free.kikagaku.ai/tutorial/basic_of_machine_learning/learn/machine_learning_unsupervised
x = StandardScaler().fit_transform(x)
# データを学習用とテスト用に分割する(train_test_split:デフォルトでは25%がテスト用、75%が学習用となる)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)

# 主成分分析のインスタンス生成
pca = PCA(n_components=2)
x_train_pca = pca.fit_transform(x_train)

# 主成分の寄与率は以下で確認可能。
# print(pca.explained_variance_ratio_)
# → [0.43711585 0.19513199]
# 第一成分で元データの43.3%、第二成分で元データの19.5%の情報を持っている。累積寄与率は62.8%

# 主成分分析した結果を図で確認してみる。
# 結果をデータフレーム化
df_pca = pd.DataFrame(x_train_pca, columns=["PC{}".format(x + 1) for x in range(2)])
# データフレームに解析結果も追加(主成分分析は教師なし学習であるが、今回は色分けするため追加)
df_pca['Outcome'] = y_train.values

# 目的変数ごとに色分けして描画するため、分割する。
malignant = df_pca[df_pca['Outcome'] == 0] # 悪性データ
benign = df_pca[df_pca['Outcome'] == 1] # 良性データ
# 描画
plt.scatter(x=malignant['PC1'], y=malignant['PC2'], label='malignant', c='r', marker='x', alpha=0.5)
plt.scatter(x=benign['PC1'], y=benign['PC2'], label='benign', c='b', marker='x', alpha=0.5)
plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.savefig("aa.png")

描画結果は以下。概ね正しく分類できていると判断できる。
※かたよらずに混ざっている場合、分類が正しく実施できていないと判断する。

f:id:you_it_blog:20211009000447p:plain


さらに、主成分分析の結果を利用したクラスタリングを行う。
(主成分分析の目的はこれ。次元を減らして終わり・・ではない)
k平均法(k-means clustering)を使用する。

from sklearn.cluster import KMeans

# クラスター数は2(悪性、良性)
model = KMeans(n_clusters=2)
# クラスタリング
y_pred = model.fit_predict(x_train_pca)
# データフレームにクラスタリング結果を追加。
# 乳がんデータセットの目的変数は「0:悪性、1:良性」。KMeansの実行結果は「0:良性、1:悪性」なので、値を反転させた物を追加する。
df_pca['Outcome_pred'] = y_pred
df_pca['Outcome_pred'] = df_pca['Outcome_pred'].map({1: 0, 0: 1}).astype(int)

# 正解と学習結果を描画して目で確認する。
# ※主成分分析を用いてクラスタリングした結果と、正解データを描画する。今回は教師データが存在するため可能。
pred_kmeans_1 = df_pca[df_pca['Outcome_pred'] == 0]
pred_kmeans_2 = df_pca[df_pca['Outcome_pred'] == 1]
# 教師データを基にしたデータを描画(色付きの「×」を描画)
plt.scatter(x=malignant['PC1'], y=malignant['PC2'], label='malignant', c='r', marker='x')
plt.scatter(x=benign['PC1'], y=benign['PC2'], label='benign', c='b', marker='x')
# クラスタリングの結果を描画
plt.scatter(x=pred_kmeans_1['PC1'], y=pred_kmeans_1['PC2'], label='Ir1', c='b', alpha=0.5)
plt.scatter(x=pred_kmeans_2['PC1'], y=pred_kmeans_2['PC2'], label='Ir2', c='r', alpha=0.5)
plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.savefig("aaa.png")

描画結果は以下。概ね正しく分類できているが・・境界付近に誤りがある。
※「□」と「×」の色が異なる部分が誤り。

ただ、一定の精度を保ったまま32次元 → 2次元まで圧縮できたため効果はある。

f:id:you_it_blog:20211009094859p:plain



【関連記事】

分かりやすい説明が記載されている。

一読すると、主成分分析をよく理解できた。

logics-of-blue.com

qiita.com

 

 

6 アルゴリズム_1(k近傍法-KNN)

【概要】

教師有り学習の分類手法。

識別対象データを受け取った際、識別対象データに最も近い(最近傍)のデータをk個取得。取得したk個のデータの分類を集計して、最も多い分類を返す。

例:k=3の場合

 ①識別対象データの最近傍を3個取得。

 ②「分類A:2個、分類B:1個」の場合 → 識別対象データの分類はAである、と判定する。

 ※「①」で取得するデータを、事前に学習させておく必要がある。

 

上記の通りなので、kの値が変われば結果が変わる。

kが増えるほど、取得する最近傍のデータが増えるため、識別結果は平均的になる。

言い換えるならば、kが増えるほど、識別範囲の境界線が滑らかな線になる。

 

【ハンズオン】

人口のデータ(と仮定したデータ)を分類する。
まず、学習データの作成。

######################
# k近傍法(KNN)
######################
# モジュールをインポート
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats


# 訓練データ生成処理(乱数なので、結果は毎回変わる)
def generate_data():
# 説明変数生成
x0 = np.random.normal(size=50).reshape(-1, 2) - 1 # 分類A
x1 = np.random.normal(size=50).reshape(-1, 2) + 1 # 分類B
# 作成した説明変数を結合
x = np.concatenate([x0, x1])
# 目的変数を生成して結合
y = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)
return x, y


# 訓練データの作成 + 作成したデータの描画(確認のため)
x_train, y_train = generate_data()
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
plt.savefig("aa.png")

 

k近傍法に最適そうなデータを作成できた。

f:id:you_it_blog:20211009165234p:plain

次に、予測を行ってみる。(見やすくするため、判定の境界も描画する)
①numpyでの実装

# 距離を計算する関数(2乗するので符号の考慮が不要となる)
def distance(x1, x2):
return np.sum((x1 - x2) ** 2, axis=1)


# 予測処理
def knc_predict(x_train, y_train, X_test):
y_pred = np.empty(len(X_test), dtype=y_train.dtype)
for i, x in enumerate(X_test):
distances = distance(x, x_train)
nearest_index = distances.argsort()[:3] # 練習としてk=3を使用する。
mode, _ = stats.mode(y_train[nearest_index])
y_pred[i] = mode
return y_pred


# 結果を描画する関数
def plt_resut(x_train, y_train, y_pred):
xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
# 散布図を描画
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
# 塗りつぶし2次元等高線図を描画。(判定の境界を確認できる)
plt.contourf(xx0, xx1, y_pred.reshape(100, 100).astype(dtype=np.float), alpha=0.2, levels=np.linspace(0, 1, 3))
plt.savefig("aaaa.png")


xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
x_test = np.array([xx0, xx1]).reshape(2, -1).T

y_pred = knc_predict(x_train, y_train, x_test)
plt_resut(x_train, y_train, y_pred)

f:id:you_it_blog:20211009165540p:plain

 

②scikit-learnでの実装

from sklearn.neighbors import KNeighborsClassifier

xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T
knc = KNeighborsClassifier(n_neighbors=3).fit(x_train, y_train) # 練習としてk=3を使用する。
plt_resut(x_train, y_train, knc.predict(xx))

f:id:you_it_blog:20211009170019p:plain

※結果に差異があるが、これはそもそもの教師データ(ランダム値)が実行の度に変わるため。教師データが同じであれば、結果も同じとなる。

 →scikit-learnの利便性が高いことを実感できる。

 

7 アルゴリズム_2(k平均法-K-mean)

【概要】

教師なし学習の分類手法。

受け取ったデータをk個のクラスタに分類する。

 

【処理の手順】

以下を、収束(= 結果が変化しなくなる)するまで繰り返す。

 ①各データからクラスタの中心となるデータを設定する。(初回はランダム)

 ②各データを最も距離の近いクラスタに分類する。

 ③分類したクラスタの平均ベクトル(中心)を計算する。

 ④クラスタの中心を更新して、再度①~③を行う。

 

【ハンズオン】

「主成分分析」で使用したため省略する。

 

8 SVM(サポートベクターマシン)

【概要】

2クラス分類問題の代表的な手法の1つ。

→回帰問題や教師なし学習でも応用されている。

※ここでは、線形分類をハンズオン対象とするが、

 カーネル関数と呼ばれる関数を用いることで、非線形の分類も可能。

 

【用語】

マージン最大化:

 分類問題なので、「k近傍法」に記載した図のように、分類の境界となる線が発生する。この線とデータの距離をマージンと呼び、マージンが大きいほど、適切な境界が設定できている。SVMでは、このマージンが最大となる境界を探す。この考え方をマージン最大化と呼ぶ。

ハードマージン:

 分類を完璧に識別できる境界が設定可能、という前提の分類。

ソフトマージン:

 分類を完璧に識別できない(誤差がある)、という前提の分類。

 ※現実としては、全ての情報を完璧に分類できる、という事はありえない。

 ソフトマージンにおける誤差を表す変数を「スラック変数」と呼び、

 誤差を最小化したうえで、マージンが最大となる境界を探す。

サポートベクトル:

 境界に最も近いデータのこと。SVMはマージンが最大となる境界を探すため、

 境界から離れているデータは、境界作成に全く影響しない。(あっても無くても結果に影響しない)

 境界に最も近いデータの = 境界の決定に使用されるデータをサポートベクトルと呼ぶ。

 

【ハンズオン】

アヤメの分類(2クラス分類)を行う。

######################
# SVM
######################
# モジュールをインポート
from sklearn import datasets, svm
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# データセットの読み込みhttps://scikit-learn.org/stable/datasets/toy_dataset.html#iris-dataset
iris = datasets.load_iris()

# 説明変数は最初の2つのみを取得(がく片の長さ、がく片の幅)
# ハンズオンのために結果を2次元の図で出力するため。
x = iris.data[:, :2]
# 目的変数の取得
y = iris.target

# 2:iris virginica」以外のインデックスを取得(データセット3クラス。実施する分類は2クラス分類のため)
idx = (iris.target != 2)
# 2:iris virginica」以外のデータのみに絞り込み
x = x[idx]
y = y[idx]

# SVMインスタンス生成
clf = svm.SVC(C=1.0, kernel='linear')
# データに最適化フィット
clf.fit(x, y)

# 背景色を利用して、分類と境界を描画する
# グラフの表示エリアの取得(説明変数の最大+1 と 最小-1の範囲とする)
x1_min = min(x[:, 0]) - 1
x1_max = max(x[:, 0]) + 1
x2_min = min(x[:, 1]) - 1
x2_max = max(x[:, 1]) + 1

# グリッド情報の作成。
# mgrid:格子状の配列を作成。500jなので、500×500の要素数となる、
xx, yy = np.mgrid[x1_min:x1_max:500j, x2_min:x2_max:500j]

# グリッド情報を並べなおす(np.c_:配列を結合する。ravel():配列を1次元に変換する)
xg = np.c_[xx.ravel(), yy.ravel()]

# 各グリッドの点の分類結果の予測をZに格納
z = clf.predict(xg)

# グリッド情報を並べなおす
z = z.reshape(xx.shape)

# 分類ごと塗りつぶしに使用する色の設定
cmap = ListedColormap([(0.5, 1, 1, 1), (1, 0.93, 0.5, 1)])

# 背景の色を表示
plt.pcolormesh(xx, yy, z == 0, cmap=cmap)

# 軸ラベルを設定
plt.xlabel('sepal length')
plt.ylabel('sepal width')

Xc0 = x[y == 0] # 目的変数;0のデータ
Xc1 = x[y == 1] # 目的変数;1のデータ

# 目的変数;0のデータを描画
plt.scatter(Xc0[:, 0], Xc0[:, 1], c='#E69F00', linewidths=0.5, edgecolors='black')
# 目的変数;1のデータを描画
plt.scatter(Xc1[:, 0], Xc1[:, 1], c='#56B4E9', linewidths=0.5, edgecolors='black')

# サポートベクトルを取得
SV = clf.support_vectors_

# サポートベクトルの点を赤枠で囲む(可視化のため)
plt.scatter(SV[:, 0], SV[:, 1], c='black', linewidths=1.0, edgecolors='red')

# 描画したグラフを表示
plt.savefig("ii.png")

f:id:you_it_blog:20211010102259p:plain

作成された境界と、境界の決定に使用されているサポートベクトルを確認できる。

 

 

 

E資格の勉強①応用数学レポート

目次

1 本投稿の目的

応用数学に関する学習のまとめ

2 線形代数(行列と固有値)

【行列】

行列の使い方として以下がある。(もちろん、その他の用途もある)

  • 大量の連立方程式をシンプルに表現する
    (行列の掛け算を理解すると、この意味が分かる。)

また、以下のような行列特有の専門用語があるので、覚える必要がある。

  • 単位行列(普通の数値における1。
    「X × 1 = X」と同様、掛け算しても結果を変えない行列で1と0で構成される。

さらに、行列の計算は手法を覚える必要がある。

  • 行列同士の足し算、引き算
    → 行列のサイズが同一であれば、単なる足し算、引き算で算出可能。
  • 行列同士の掛け算
    → 直行表のようなイメージで、全パターンの掛け算を加算していく。
     これは練習して確実に理解する必要がある。
  • 行列 → 通常の数値の変換
    → 左斜めに掛け算 - →右斜めに掛け算 がベースで、3×3ならたすき掛けが必要。

固有値

行列のn乗を簡単に求めるために必要となる。

※厳密には、固有値の一覧 = 対角行列と固有ベクトルを使用することで、

 行列の累乗を簡単に求める事ができるようになる。
 対角行列の累乗は各数値をn乗する、という簡単な方法で計算できるため。

 

行列に対して固有値分解(書籍により対角化とも記載されている)

を行うことで、累乗式に必要な以下を取得できる。

なお、正方行列でない場合は特異値分解、という手法で求める必要がある。


【補足:参考資料】

全体的に、以下の資料がとても参考になった。
★行列を知らない人のための線形代数学入門 - 広島大学

http://www.math.sci.hiroshima-u.ac.jp/m-mat/TEACH/senkei-daisuu.pdf

 

3 確率・統計

条件付確率が、特に注意が必要。

解説:

 ①PA(B) = P(B|A) = 事象Aが発生した世界で、事象Bが発生する確率※

 ②P(B∩A) = AとBが同時に発生する確率

 →①②は別の意味であるので注意。

※各順番が逆じゃない?と思うが、英語ベースで考えるとこの順番になる。
 (日本語と異なり、主語がとにかく先頭にくる形式)

その他、以下の用語がある。

  • 期待値(期待される値の平均)
  • 分散(実際の値と期待値の差を2乗したもの、2乗するのは±の考慮を無くすため)
  • 標準偏差(分散を√したもの。2乗 = 単位自体が変わるため、それを解消する)


【補足:参考資料】
条件付確率の参考

https://ousar.lib.okayama-u.ac.jp/files/public/6/60999/20201203115534771574/bgeou_175_027_037.pdf

 

ベイズ統計の考え方については、以下の本が参考になった。
※数時間読めば、図ベースで、条件付確率が理解できるようになる。

www.diamond.co.jp

 

4 情報理論

【自己情報量】

「-log(p(x))」という公式を始めてみたが、実際に問題を考えてみると意味が良く分かった。確率は0~1の範囲になるので、p(x)の値はほぼ分数になる。分数は累乗に直すと-n乗になるので答えが正数になる。かつ、値が小さければ小さいほど(-n乗のnが大きいほど)最終的な値(その情報の価値)が大きくなる。

【シャノンエントロピー

自己情報量の期待値。誤差関数の中身として使う、という事もできそう。

【カルバック・ライブラー・ダイバージェンス

想定していた確率分布と、実際の確率分布の違いを表すことができる。

ダイバージェンス <> 距離。

ダイバージェンスは距離と呼ぶには一部の定義を満たせていない。

ここでもΣは使用するので、Σは非常に重要。

【公差エントロピー

KLダイバージェンスの一部分。Qに対する情報をP(現実)の分布で平均する。

 

全て、公式を覚えておく(意味も理解する)はもちろん、自己情報量以外も実際に計算してみて、解いてみる必要があると思われる。


以上

E資格の勉強を始めてみる

目次

1 本投稿の目的

E資格の勉強を始めてみる。その経緯を記載する。

2 自分について
  • 資格は色々持っている(高度試験3つ、情報処理安全確保支援士試験合格)
  • 数学は高卒レベル。プログラム(Python)は1年ほど個人で経験あり。
3 学習を始めようとした理由

昨年、奇跡的にITストラテジストプロマネに合格できたので、次を考えていた。
そこで、自社の雰囲気を見てみると、AIの知識を求めいている雰囲気があった。
→AIについて何か資格を取っておけば、今後何か評価が上がるのでは?、と感じた。

4 学習方法(予定) 

以下オンリーで対策してみる。

ai999.careers


E資格の受験対象となる講座を色々確認してみたが、
最安でも5万円近くかかる。(165,000円 × 専門実践教育訓練にで70%戻る)

しかし、これなら、上手くいけば35,000円くらいで済む。[登録20,000円 + 月額3,000円×5カ月]

値段が安い分、自分で色々調べる必要があるみたいだが・・頑張ってみよう。

 

5 計画と目標

2021年9月1日:学習開始

~12月末:修了認定テストを通過。

2022年2月:試験を受験。できれば一度で合格したい・・。

 

6 その他

数学の知識が無いので、調べながら進める。

その過程で、役立つサイトなどがあれば忘備のため追記していく。

 

 

7 数学の資料

行列

www.mext.go.jp

 

条件付確率

https://ousar.lib.okayama-u.ac.jp/files/public/6/60999/20201203115534771574/bgeou_175_027_037.pdf

記号の解説:

 ①PA(B) = P(B|A) = 事象Aが発生した世界で、事象Bが発生する確率

 ②P(B∩A) = AとBが同時に発生する確率

 →①②は別の意味であるので注意。

区間和(更新無し)の最大値(abc183_d)

概要

区間和(更新無し)の最大値を求める方法を、図で解説する。
※加算、減算を同時に行える。

解説図

以下の様な区間の最大値を求める。

1.全探索(ダメなパターン)

処理量がO(nw)
→(問題の制約的に)最大で20万×20万・・・とても間に合わない。

2.累積和を使う

「要素が変わるタイミング」は以下の通り。

これを1つの配列(変動表)にまとめて・・

累積和を求める。

→最大値は「7」と分かる。
この方法なら処理量はO(n+w)。最大で20万+20万なので、問題なく回答できる。

包除原理(abc178_c)

概要

知識不足で包除原理の解説が難しかったので、図で解説する。

問題

atcoder.jp

解説図

答えの式

1.初期イメージ


ベースはこれ。

2.加算:全パターン(10^n)。


全パターンを+1。

3.減算:0を含まないパターン(9^n)

「0を含む」以外のパターンを-1。

4.減算:1を含まないパターン(9^n)


「1を含む」以外のパターンを-1。

5.加算:0と1を含まないパターン(8^n)


「0を含む」「1を含む」以外のパターンを+1。

6.結果


「0を含む」かつ「1を含む」パターンだけ算出できた。
(そのほかの部分は0なので除外できている)

未経験で合格:ITストラテジスト(2019年秋期)

結論

  • 未経験でも合格可能。(1回落ちた)
  • 勉強時間は約300時間。
  • 午後2は運も影響する。何回か受けて当たりを待つべきかも。

目次

1.自分について

1.1 本投稿の目的

ITストラテジストに合格したので、勉強方法などの備忘録。

1.2 自分について
1.3 受験理由

自己研鑽のため。

2.勉強

2.1 午前1

応用情報技術者試験の過去問(午前1)を実施。

3年分実施して平均70%を取れるようにする。

※おそらくこれだけでOK。

2.2 午前2

ITストラテジストの過去問(午前2)を実施。

過去6~7年分実施して、回答内の全用語を把握する。

※毎年いくつか新出問題があるが、おそらく6割は過去問を流用(?)

 しているので、これでOK。専門書等は読まなくて良い。

2.3 午後1(大変)

ITストラテジストの過去問(午後2)を実施。

過去5年分を実施して、「なぜ、この設問に対する回答がこれになる」かを、

設問→問題文(システム改善後の運用)→問題文(システム改善前の課題)の順にトレース。

※正攻法(先頭~末尾まで読む、回答を1つずつ解く)では時間が足りない。

 パズルゲー感覚で問題文から回答を逆引きする必要がある。

 回答は問題文中にある場合が大半なので、専門書等は読まなくて良い。

2.4 午後2(超大変)

これが問題。調査が必要。以下、私が調査した情報。

  • 論述対象にする業界の特徴、規模(私の場合はアパレル業界)
  • システム開発の大まかな予算、期間、効果。
    ※各ベンダーの導入事例や日経クロステックで調べた。

以上を調べた後、過去問を何点か実施。以下3種類の論文を準備した。

  • 全体システム化計画
  • 個別システム化計画
  • 経営戦略の立案

これで本番を望むだけだが・・、午後2は運要素が強い気がする。

  • 突如、不意打ちのような問題が出題されることがある。
     平成24年度:事業継続計画の制定
     平成26年度:クラウドコンピューティング導入方針
     平成30年度:新技術と業務システムによる新サービス
     →全過去問の論文を準備しても(おそらく不可能だが)対応できない。
      ※その代わり、該当の実務経験がある人には、非常に有利。

  • 前提が合わず、準備した論文が流用できないことがある。
     平成27年度:グローバルな事業
     →「グローバル」システムの論文のみ流用できる。
      「国内向け」システムの論文は流用できない。

問題に対応した実務経験or事前対策が必須だが、

なにせ範囲が広い。自分にとっての当たりが出るまで受験が必要かもしれない。

 

3.受験

3.1 結果確認

点数は以下の通り。

f:id:you_it_blog:20191220230938p:plain


→午後2、準備した「個別システム化計画」の論文が当たった。

 ※準備したのは「AI活用事例」を元にした論文。これ以外なら落ちたはず。
 また、数十文字足りなかったかも・・!!と思っていたが合格した。

 最後まであがいたのが功を奏したかもしれない。

4.最後に

午後2の準備に注力しすて、足元を掬われないよう注意が必要。

合格した結果だけ書いているが、実は2018年度は午前2で落ちている。

→午後2は採点すらされなかった。100時間以上を無駄にした。

 

以上。

未経験で合格:kintone認定 アソシエイト

結論

  • 未経験でも合格可能。
  • 勉強時間は13時間。→適切かも。
  • 通常は15,000円かかるが、無料受験バウチャーで0円。

目次

1.自分について

1.1 本投稿の目的

kintone認定 アソシエイトに合格したので、勉強方法などの備忘録。

1.2 受験前の知識
  • ワークフローソフトの利用経験あり
  • kintoneに関する実務経験=0
1.3 受験理由

Cybozu Days 2019 -モンスターへの挑戦状-に参加後、以下キャンペーンに気付く。

※(2023年追記)リンク切れ。

→「試験無料バウチャー」をプレゼント。これを見て受験を決定。

 

2.勉強

2.1 試験対策テキスト(約10時間)

目的:基礎知識の取得。回答の練習。

以下の本を購入し、2周読み込む。 

読むときの準備

  1. kintone(キントーン)- 30日間無料お試しを登録。
    分かりづらいところは実際に叩いてみるのが一番。
  2.  Associate(アソシエイト) | kintone 認定資格の種類についてを読む。
    「出題範囲」は必ず読む。
    「XX年XX月時点のバージョンに対応しています。」という記載を確認する。
  3. kintone(キントーン)- 主なアップデートを読む。
    いわゆるリリースノート。
    ※以下の差異を把握するために必要※
     ・実試験:「出題範囲」に記載されたバージョン
     ・試験対策テキスト:出版時点(?)のバージョン 
     ・30日間お試し環境:おそらく最新のバージョン 

    上記を把握しないと、「試験対策テキスト」や「30日間お試し環境」の知識で
    回答して間違えるリスクがある。

2.2 kintoneヘルプ(約3時間)

目的:基礎知識の取得。

以下を読み込む。

 

「細かな制限」や「試験対策テキストに記載されていないが重要な点」を読む。
受験後の感想だが、以下だけで合格できたかも、と感じた。

  • ヘルプを全部読む
  • 試験対策テキストのサンプル問題を解く(サンプル問題以外は飛ばす)

3.受験

3.1 受験
  • 当日申込できる試験会場もある。
  • 受験後、すぐ結果が分かる。

→40分で全問回答。合格。

3.2 結果確認

点数は以下の通り。

f:id:you_it_blog:20191219233235p:plain
→合格ラインは不明だが、ちょうど良い点数かもしれない。
 過学習を回避できた気がする。

4.最後に

kintoneの感想として「とにかく操作が簡単」と感じた。

競合他社に務めるエンジニアが調査を兼ねて学習しても良いかもしれない。

 

以上。

未経験で合格:AWS認定 ソリューションアーキテクトプロフェッショナル

結論

  • 未経験でも合格可能。
  • 勉強時間は150時間。→過剰だったかも。
  • 受験費が高い(最低30,000円。バウチャー利用で15,000円)。

目次

1.自分について

1.1 本投稿の目的

SAP(ソリューションアーキテクト – プロフェッショナル)に合格したので、

3年後の再認定に備えた備忘録。

1.2 受験前の知識
1.3 受験理由

AWSからオンラインカンファレンスのメールを受け取る。

→「模擬試験無料バウチャー※」をプレゼント。

 これを見て受験を決定。

 ※ソリューションアーキテクト – プロフェッショナル限定

2.勉強

2.1 Jayendra's Blog(約30-40時間)

目的:基礎知識の取得。

以下の全リンクを読む。

読み方は・・

  • 関連リンクをひたすら追っていく。
  • 英語なのでGoogle翻訳
    ⇒翻訳不備は公式ドキュメントを読んで対応。
  • 適時日本語を修正して進めるので、なかなか辛い。
  • 日本語化した資料をまとめる。私はOneNoteを使用した。
2.2 サンプル問題(約100-120時間)

目的:実際の問題を読んで回答できるか確認。

実際の問題文と回答は非常に長い。3~5行とか。

数を積んで、速く正確に答えるテクニックを身に着ける必要がある。

→問題集で対策することにした。以下、見つけた問題集。
 ※全て有償。宣伝目的でないので価格は未記載。

  1. SAP-C01 Practice Exams※Jayendra's Blogが推奨

  2. Udemyの問題集

  3. AWS WEB問題集で学習しよう

→「1」だけ購入した。(半額セールで2,500円だったため)

 

以下の通り勉強を進めた。

  • 70問を実施(2.5時間)。
  • 復習。全ての正解、不正解を理解する。(10-15時間)
    AWSドキュメントで確認して、未記載ならAWSで検索

→上記を6セット。これが一番大変だった。

2.3 模擬試験の実施(約1.0時間)

目的:合格する可能性の確認。

以下ページの「試験のスケジュールを立てる」から、模擬試験を受験。

  • 受験後、点数が通知される。
    ※相変わらず個別の正否を教えてくれない。つらい。

70~80点だったが、模擬試験は実際と採点方法が違うとのこと。   

 Q:模擬試験と実際の認定試験は同じ方法で採点されますか?
 A:模擬試験は正解率に基づいて採点されます。
   例えば、20 問中 16 問が正解だった場合、スコアは 16/20 または 80% です。
   実際の認定試験のスコアは、100~1000 点のスコアで示されます。

3.受験

3.1 受験
  • 当日申込できる試験会場もある。
  • 受験後、すぐ結果が分かる。

→2時間で全問回答。疲れたので見返さずにテスト終了して・・合格。。
 合否がその場で分かるのはありがたい。

3.2 結果確認

数日後、点数を確認したところ・・

f:id:you_it_blog:20191127123340p:plain

→880点。高得点だが、過学習だった。問題集をざっと読むだけで十分かも。

4.最後に

試験の費用は非常に問題。

  • 模擬試験・・ 4000円 + 税
    →バウチャー利用で無料
  • 試験  ・・ 30000円 + 税
    →バウチャー利用で半額

→模擬試験で点数が低い場合、再勉強した方が良いかも。
 

誰かの参考になれば、うれしいです。 

以上。

未経験で合格:AWS認定 ソリューションアーキテクトアソシエイト

結論

  • 未経験でも15時間ほどで合格可能。(2019年5月)
  • 受験費が高い(最低15,000円)。慎重な受験が必要。

目次

1.自分について

1.1 受験前の知識
1.2 受験理由

2019年GW。以下の記事を発見。

AWSの資格、人気ランクは低いが、取得するのも良いかも・・。

 

さらに、以下を発見。

→「〜普段有償のトレーニングコースを期間限定で無償公開〜」
 これを見て受験を決定。

2.勉強

2.1 AWS Innovate(約2-3時間)

目的:基礎知識の取得。

AWS Innovateに登録し、以下セッションを閲覧。

  1. AWS イントロダクション
  2. AWSome Day
    →上記2つで大まかな概要を把握。
  3. AWS 認定 - 試験対策(SAA)
    →これがメイン。
2.2 サンプル問題(約0.5時間)

目的:実際の問題を読んで対策を考える。

以下ページの「サンプル問題」に挑戦。
※「試験ガイド」も閲覧し、各分野の比率を把握すること。

2.3 サービス概要の閲覧(約3-4時間)

目的:各サービスの概要、関係性を学ぶ。

サービスの概要を読み込む。
例:ストレージ関係

→「AWS Innovate」と「サンプル問題」で出たサービスは全て読む。

  • 大事なタブは「概要、特徴、料金」。
  • サービス固有のタブも重要。(例:S3の「ストレージクラス」タブ)
  • 料金やパラメータの丸暗記は不要。
    AよりBが高性能、AよりCが安い等、関係を覚える。
2.4 ユーザーガイドの閲覧(約3-4時間)

目的:実際の知識(設定やベストプラクティス)を学ぶ。

ユーザーガイドを読み込む。

例:EC2の場合

2.5 模擬試験の実施(約0.5時間)

目的:合格する可能性の確認。

以下ページの「試験のスケジュールを立てる」から、模擬試験を受験。

  • 全問題、キャプチャを取得する。
    ※後で復習するために必須。
  • 時間があれば、その他も一読すべき。
  • 受験後、点数は通知が来る。
    ※詳細は、分野ごとの比率のみ。
     個別の問題は教えてくれない。つらい。
2.6 模擬試験の復習(約1-2時間)

目的:足りない知識をカバーする。

試模擬試験のキャプチャを見て、正しい回答を調べる。
※「AWS Innovate」と「サンプル問題」では説明が無いサービスが
 突然出てくることも多いので、追加で勉強する。
例:Kinesis、DirectConnect

3.受験

3.1 受験
  • 当日申込できる試験会場もある。
  • 受験後、すぐ結果が分かる。

→なんとか合格。点数は後日教えてくれるらしい。

3.2 結果確認

数日後、点数を確認したところ・・

→ギリギリ合格。危なかった。

 あと2問ほど間違えたら落ちたと思われる。

4.最後に

試験の費用、すごい高い・・。

  • 模擬試験・・ 2000円 + 税
  • 試験  ・・ 15000円 + 税

→模擬試験で点数が低い場合、再勉強した方が良いかも。
 (70%正解できれば大丈夫?)
 

誰かの参考になれば、うれしいです。 

以上。