1. なぜ線形代数を学ぶのか
ここまで NumPy の「配列としての側面」を学んできました。 このレッスンでは 「行列としての側面」 を扱います。 AI・機械学習の世界では 線形代数(特に行列の演算)が事実上の共通言語 です。
- 特徴量 × 重み:AIモデルの推論は「入力ベクトル × 重み行列 + バイアス」の繰り返し
- 画像処理:フィルタ・畳み込み・座標変換はすべて行列演算
- 統計:共分散行列・主成分分析・回帰分析の中身は線形代数
このレッスンでは 「線形代数の理論」には踏み込まず、 「NumPyでどう書くか」と「何のために使うか」に絞って学びます。 理論を深掘りしたい方は、後で線形代数の専門教材や E資格対策で学習しましょう。(※コンテンツに関するご希望あれば「お問い合わせ」ページでご意見ください。)
2. ベクトルのドット積
ドット積(内積) は、2つの同じ長さのベクトルから1つのスカラーを返す演算です。 各要素を掛けて、その和を取ります。
数式:a · b = a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1]
💡 ドット積の使いどころ:
- 重み付き合計(特徴量×重みでスコア計算)
- ベクトルの類似度(コサイン類似度の計算に使う)
- ベクトルの長さ(自身とのドット積の平方根)
🩺 医療AI文脈:
「患者の特徴量から疾患リスクを点数化」する処理は、内部的にはドット積です。
特徴量 @ 重み という1行で、複数項目の貢献度を合算した1つのリスクスコアが得られます。
3. 行列積(@ 演算子)
行列積は、2つの行列を掛けて新しい行列を返す演算です。
@ 演算子で書くのが Python 3.5以降の標準です。
形状の条件:(m, n) と (n, k) の行列を掛けると (m, k) になります。
左の列数と右の行数が一致している必要があります。
💡 「ドット積」と「行列積」で同じ @ を使うのはなぜ?
NumPyの @ 演算子は 入力配列の次元によって動作が自動的に切り替わる ように設計されています。
- 1D × 1D(前セクション):ドット積 → スカラーを返す
- 2D × 2D(このセクション):行列積 → 2D行列を返す
- 1D × 2D / 2D × 1D:ベクトル×行列 → 1D配列を返す
数学的には「ドット積は行列積の特殊ケース」と捉えられるため、同じ記号で扱えます。NumPyが入力の shape を見て、適切な計算を自動的に選びます。
⚠ ただし、* は まったく別の演算(要素積)です。混同しないよう、次セクションで @ と * の違いを整理します。
💡 行列積の形状の覚え方:
(m, n) @ (n, k) → (m, k)
「内側の n が一致して消え、外側の m と k が残る」と覚えるとミスが減ります。
実コードでは print(A.shape, B.shape) で確認してから書く習慣をつけましょう。
🤖 AI用語メモ — 「全結合層」とは?
AIニューラルネットワークで最も基本的な構成要素のひとつが 全結合層(Fully Connected Layer)です。
その計算の正体は 「入力 @ 重み + バイアス」。つまり、このレッスンで学んだ行列積そのものです。
PyTorch の nn.Linear も TensorFlow の Dense も、内部ではこの計算を行っています。
NumPy で X @ W + b が書ければ、AIの基本構造はもう半分理解したも同然です(残り半分は活性化関数で、次のレッスンで扱います)。
4. 要素積(*)と行列積(@)の違い
初学者が最も混乱するポイントです。* と @ はまったく違う計算です。
| 記号 | 呼び方 | 入力 shape | 結果の shape | 用途 |
|---|---|---|---|---|
A * B |
要素積 | 同じ shape(または broadcast 可能) | 入力と同じ | マスク・スケーリング |
a @ b |
ドット積(@ の1D版) | 1D × 1D(同じ長さ) | スカラー | 重み付き合計・類似度 |
A @ B |
行列積(@ の2D版) | 2D × 2D(左の列数 = 右の行数) | 2D 行列 | 線形変換・AI推論 |
💡 ひと言で整理:
@は 数学の「内積・行列積」を1記号でカバー(入力次元で自動切替)*は 「要素ごとの掛け算」。@とは完全に別物- 判断基準:「線形変換をしたい」→
@/「マスクをかける・スケーリングする」→*
⚠ * と @ を間違えるとバグになる:
両方とも文法的にはエラーにならないことが多く、結果も「(N, N) の行列」になるので気づきにくいバグの温床です。
AI実装で「線形変換をしたい」場合は必ず @、「マスクをかける・スケーリングする」場合は *、と意識して使い分けましょう。
5. 逆行列・固有値(概念紹介)
NumPy には線形代数の専門関数群が np.linalg モジュールに用意されています。
ここでは 「こういう機能がある」ことを知ってもらう紹介に留めます。
理論や応用は線形代数の専門学習や E資格対策で深めてください。
💡 np.linalg の主な機能と使われる場面:
inv(A):逆行列。連立方程式を解く・回帰係数を求めるdet(A):行列式。線形変換の体積比、行列が逆を持つかの判定eig(A):固有値・固有ベクトル。主成分分析(PCA)の中核norm(A):ベクトル・行列のノルム(長さ)solve(A, b):連立方程式Ax = bを高速に解く
これらは初学者が「いま使う」必要はありませんが、AI・データ解析で必ず再会します。「np.linalg に色々ある」と覚えておくだけでも十分です。
6. 練習問題
特徴量×重みでスコアを計算しよう
患者の特徴量 x = np.array([60, 25.0, 1])(年齢、BMI、喫煙歴)と
重み w = np.array([0.03, 0.04, 0.30]) から、
ドット積でリスクスコアを計算してください。
ヒントを見る(答え+解説)
import numpy as np
x = np.array([60, 25.0, 1])
w = np.array([0.03, 0.04, 0.30])
# ドット積でスコアを計算してください
score = x @ w
# 代替: score = np.dot(x, w)
print("リスクスコア:", score)
# → 60*0.03 + 25*0.04 + 1*0.30 = 1.8 + 1.0 + 0.3 = 3.1
x @ w がドット積の最も推奨される書き方です。「重み付き合計」がそのまま1行で計算できます。
行列積で複数患者の複数リスクを一気に計算
以下の特徴量行列 X(3患者×3項目)と重み行列 W(3項目×2リスク)から、
行列積で全患者の両リスクスコアを一気に計算してください。
ヒントを見る(答え+解説)
import numpy as np
X = np.array([
[50, 24.0, 0],
[65, 28.5, 1],
[40, 22.0, 0]
])
W = np.array([
[0.02, 0.01],
[0.05, 0.08],
[0.40, 0.20]
])
# 行列積で全患者×全リスクのスコアを計算してください
scores = X @ W
print("scores shape:", scores.shape) # (3, 2)
print("結果(心疾患, 糖尿病):")
print(scores)
(3, 3) @ (3, 2) → (3, 2)。1行で「3人×2リスク = 6つのスコア」が同時に計算されます。これがAIモデルの全結合層の計算そのものです(あとはバイアスを足して活性化関数を通せば完成)。
要素積と行列積の結果を比べよう
以下の2つの (2, 2) 行列について、要素積 (*) と 行列積 (@) の両方を計算し、結果が全く違うことを確認してください。
ヒントを見る(答え+解説)
import numpy as np
A = np.array([[2, 3],
[4, 5]])
B = np.array([[1, 0],
[0, 1]])
# 要素積と行列積をそれぞれ計算してください
elem_product = A * B
mat_product = A @ B
print("要素積 (A * B):")
print(elem_product)
# [[2 0] ← A * B は対応する要素同士を掛ける
# [0 5]]
print("\n行列積 (A @ B):")
print(mat_product)
# [[2 3] ← A @ I = A(単位行列との行列積は自分自身)
# [4 5]]
要素積では A * B = [[2*1, 3*0], [4*0, 5*1]] = [[2, 0], [0, 5]]。
一方、行列積では「単位行列との積は元のまま」という性質があり、A @ I = A となります。
同じ形の行列でも、* と @ で全く別物の結果になることを実感してください。
7. まとめ
このレッスンのポイント
- ベクトルのドット積:
a @ b。重み付き合計や類似度の計算に - 行列積:
A @ B。(m, n) @ (n, k) → (m, k)の形状規則 - 要素積(
*)と行列積(@)はまったく別物。混同注意 np.linalg:逆行列・行列式・固有値・連立方程式などの専門関数群- AIの全結合層は
入力 @ 重み + バイアスという1行で表現できる(次のレッスンで実装)
自由に試してみましょう:
完了するとコース一覧に進捗が記録されます