ベクトル操作
import numpy as np
import matplotlib.pyplot as plt
# ベクトルの基本演算
a = np.array([1, 2, 3])# ベクトルの定義
b = np.array([4, 5, 6])
print(f"a + b = {a + b}")# ベクトルの加算
print(f"a - b = {a - b}")# ベクトルの減算
print(f"2 * a = {2 * a}")# ベクトルのスカラー倍
# 内積
dot = np.dot(a, b)# ベクトルの内積こっちの方高速
print(f"\n内積 a·b = {dot}")
print(f"内積(手計算) = {sum(ai*bi for ai, bi in zip(a, b))}")# 内積の手計算
# zipは各要素のペア sumで合計 1,4をかける、2,5をかける、3,6をかける それらを合計する
# ノルム
l2_norm = np.linalg.norm(a)# ベクトルの大きさルートミーンスクエア
l1_norm = np.linalg.norm(a, ord=1)# ベクトルの大きさの別定義 絶対値の合計
print(f"\nL2ノルム ||a|| = {l2_norm:.4f}")
print(f"L1ノルム ||a||_1 = {l1_norm:.4f}")
# コサイン類似度
cos_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(f"\nコサイン類似度 = {cos_sim:.4f}")# 2つのベクトルがどれだけ同じ方向か 1.0が同じ向きで0.0が直角-1.0が逆向き
# 外積 (3次元)
cross = np.cross(a, b)# 外積計算
print(f"外積 a×b = {cross}")
# 2Dベクトルの可視化
fig, axes = plt.subplots(1, 2, figsize=(12, 5))# 1行2列、12インチ×5インチの図を作成
# ベクトルの加算
v1 = np.array([2, 1])
v2 = np.array([1, 3])
ax = axes[0]
# 左のグラフをaxに設定
ax.quiver(0, 0, v1[0], v1[1], angles='xy', scale_units='xy', scale=1, color='blue', label='v1')
# quiverはベクトルを描画する関数 0,0からv1[0],v1[1]の位置に矢印を描く angles='xy'は座標系に合わせる scale_units='xy'はスケールを座標系に合わせる scale=1はスケールをそのまま colorは色 labelは凡例のラベル
ax.quiver(0, 0, v2[0], v2[1], angles='xy', scale_units='xy', scale=1, color='red', label='v2')
# v1とv2を同じグラフに描画
ax.quiver(0, 0, v1[0]+v2[0], v1[1]+v2[1], angles='xy', scale_units='xy', scale=1, color='green', label='v1+v2')
# v1とv2の和を描画
ax.set_xlim(-1, 5)
ax.set_ylim(-1, 5)
# グラフの範囲を設定x,yともに-1から5まで
ax.grid(True)
# グリッドを表示
ax.legend()
# 凡例(labelで設定したテキスト)を表示
ax.set_title('Vector Addition')
# タイトルを表示
ax.set_aspect('equal')
# x軸とy軸のスケールを同じにする
# 正規化
vectors = np.random.randn(10, 2)
# 10個のランダムな2Dベクトルを生成 正規分布に従う
norms = np.linalg.norm(vectors, axis=1, keepdims=True)
# 各ベクトルのノルムを計算 axis=1は行ごとに計算 keepdims=Trueは結果を元の形状に保つ
normalized = vectors / norms
for i in range(10):
print(f"元のベクトル: {vectors[i]}, ノルム: {norms[i][0]:.4f}, 正規化されたベクトル: {normalized[i]}")
# ベクトルをノルムで割ることで最大1に正規化
ax = axes[1]
for v in normalized:
ax.quiver(0, 0, v[0], v[1], angles='xy', scale_units='xy', scale=1, alpha=0.6)
# 正規化されたベクトルを描画 alphaは透明度
circle = plt.Circle((0, 0), 1, fill=False, color='gray', linestyle='--')
# 単位円を描画 中心が(0,0)で半径が1の円 fill=Falseは塗りつぶさない colorは色 linestyle='--'は点線
ax.add_patch(circle)
# 単位円をグラフに追加
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
# グラフの範囲設定
ax.grid(True)
ax.set_title('Normalized Vectors (Unit Circle)')
ax.set_aspect('equal')
plt.tight_layout()
# レイアウトを調整してグラフが重ならないようにする
plt.savefig('day03_vectors.png', dpi=100)
# 図を保存 dpiは解像度
plt.close()
# 図を表示する場合はplt.show()を使用
print("\n図をday03_vectors.pngに保存しました")
a + b = [5 7 9]
a - b = [-3 -3 -3]
2 * a = [2 4 6]
内積 a·b = 32
内積(手計算) = 32
L2ノルム ||a|| = 3.7417
L1ノルム ||a||_1 = 6.0000
コサイン類似度 = 0.9746
外積 a×b = [-3 6 -3]
ノルム: 1.7124
ノルム: 0.7095
ノルム: 0.6335
ノルム: 0.6822
ノルム: 0.5884
ノルム: 2.2364
ノルム: 2.1165
ノルム: 1.7087
ノルム: 2.0794
ノルム: 1.3834
図をday03_vectors.pngに保存しました
C:\Users\yuzuk\OneDrive\ドキュメント\AI勉強>python -u "c:\Users\yuzuk\OneDrive\ドキュメント\AI勉強\ai_learning_130days\ai_course\month1_math\day03_vectors.py"
a + b = [5 7 9]
a - b = [-3 -3 -3]
2 * a = [2 4 6]
内積 a·b = 32
内積(手計算) = 32
L2ノルム ||a|| = 3.7417
L1ノルム ||a||_1 = 6.0000
コサイン類似度 = 0.9746
外積 a×b = [-3 6 -3]
元のベクトル: [ 1.58916343 -0.21742019], ノルム: 1.6040, 正規化されたベクトル: [ 0.9907703 -0.13555149]
元のベクトル: [ 0.59836771 -0.11804862], ノルム: 0.6099, 正規化されたベクトル: [ 0.98108968 -0.1935537 ]
元のベクトル: [-1.21230687 0.39735072], ノルム: 1.2758, 正規化されたベクトル: [-0.95025899 0.31146082]
元のベクトル: [-0.24938664 -0.0435534 ], ノルム: 0.2532, 正規化されたベクトル: [-0.98509028 -0.17203821]
元のベクトル: [-0.22220934 -0.66085785], ノルム: 0.6972, 正規化されたベクトル: [-0.31870948 -0.94785245]
元のベクトル: [-0.88409386 0.06941209], ノルム: 0.8868, 正規化されたベクトル: [-0.9969321 0.07827126]
元のベクトル: [-0.45507544 0.43287221], ノルム: 0.6281, 正規化されたベクトル: [-0.72456158 0.68921006]
元のベクトル: [0.65221783 1.87765324], ノルム: 1.9877, 正規化されたベクトル: [0.32812613 0.94463392]
元のベクトル: [-1.35823633 0.34104547], ノルム: 1.4004, 正規化されたベクトル: [-0.96989224 0.24353446]
元のベクトル: [0.18156482 0.5870476 ], ノルム: 0.6145, 正規化されたベクトル: [0.29547522 0.9553504 ]
図をday03_vectors.pngに保存しました
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 行列積
print(f"A @ B =\n{A @ B}")# numpyの行列積
print(f"np.dot(A, B) =\n{np.dot(A, B)}")# np.dotも行列積
# 転置
print(f"\nA^T =\n{A.T}")
# 行列式
det_A = np.linalg.det(A)# ad-bc = 1*4 - 2*3 = -2の計算をする
print(f"\ndet(A) = {det_A:.4f}")# 行列式が0でないのでAは正則行列(逆行列が存在する)
# 逆行列
A_inv = np.linalg.inv(A)# 逆行列を計算
print(f"\nA^-1 =\n{A_inv}")
print(f"A @ A^-1 =\n{A @ A_inv}") # 元の行列×逆行列は単位行列に近い
# スクラッチで2x2逆行列
def inv_2x2(M):
a, b, c, d = M[0, 0], M[0, 1], M[1, 0], M[1, 1]
det = a * d - b * c
return np.array([[d, -b], [-c, a]]) / det# 行列式で割る
print(f"\n手動計算 A^-1 =\n{inv_2x2(A)}")
# 行列式のスクラッチ実装 (再帰的)
def det_recursive(M):
n = M.shape[0]# 行列の行数を取得
if n == 1:# 1x1行列の行列式はその唯一の要素
return M[0, 0]
if n == 2:# 2x2行列の行列式はad - bc
return M[0, 0] * M[1, 1] - M[0, 1] * M[1, 0]
result = 0# 3x3以上の行列の行列式は、第一行を展開して計算
for j in range(n):
minor = np.delete(np.delete(M, 0, axis=0), j, axis=1)# 第一行とj列を削除して小行列を作成
result += ((-1) ** j) * M[0, j] * det_recursive(minor)# 余韻子を掛けて再帰的に行列式を計算
return result
C = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
print(f"\n3x3行列式 (numpy): {np.linalg.det(C):.4f}")
print(f"3x3行列式 (手動): {det_recursive(C):.4f}")
# 連立方程式 Ax = b
b = np.array([5, 11])
x = np.linalg.solve(A, b)# 連立方程式を解くためにnumpyの関数を使用
print(f"\n連立方程式の解: x = {x}")# Ax = bの解を表示
print(f"検証 Ax = {A @ x}")# 解を検証するためにAxを計算してbと比較
# トレース
print(f"\ntr(A) = {np.trace(A)}")# 対角成分の和を計算
# ランク
print(f"rank(A) = {np.linalg.matrix_rank(A)}")# 行列のランクを計算
A @ B =
[[19 22]
[43 50]]
np.dot(A, B) =
[[19 22]
[43 50]]
A^T =
[[1 3]
[2 4]]
det(A) = -2.0000
A^-1 =
[[-2. 1. ]
[ 1.5 -0.5]]
A @ A^-1 =
[[1.0000000e+00 0.0000000e+00]
[8.8817842e-16 1.0000000e+00]]
手動計算 A^-1 =
[[-2. 1. ]
[ 1.5 -0.5]]
3x3行列式 (numpy): -3.0000
3x3行列式 (手動): -3.0000
連立方程式の解: x = [1. 2.]
検証 Ax = [ 5. 11.]
tr(A) = 5
rank(A) = 2
