回答編集履歴
11
修正
test
CHANGED
@@ -88,7 +88,7 @@
|
|
88
88
|
|
89
89
|
|
90
90
|
|
91
|
-
このままでは線形分離できないので、Φ: (x, y) → (x, y, y^2) という関数で3次元空間に射影します。3次元空間上で
|
91
|
+
このままでは線形分離できないので、Φ: (x, y) → (x, y, y^2) という関数で3次元空間に射影します。3次元空間上に射影したことで線形分離可能になったので、線形 SVM で学習できます。
|
92
92
|
|
93
93
|
|
94
94
|
|
10
修正
test
CHANGED
@@ -88,7 +88,7 @@
|
|
88
88
|
|
89
89
|
|
90
90
|
|
91
|
-
このままでは線形分離できないので、Φ: (x
|
91
|
+
このままでは線形分離できないので、Φ: (x, y) → (x, y, y^2) という関数で3次元空間に射影します。3次元空間上では線形分離できるようになるので、線形 SVM で学習できます。
|
92
92
|
|
93
93
|
|
94
94
|
|
9
修正
test
CHANGED
File without changes
|
8
修正
test
CHANGED
@@ -88,7 +88,7 @@
|
|
88
88
|
|
89
89
|
|
90
90
|
|
91
|
-
このままでは線形分離できないので、Φ: (x1, x2) → (x1, x2, x2^2) という関数で3次元空間に射影します。
|
91
|
+
このままでは線形分離できないので、Φ: (x1, x2) → (x1, x2, x2^2) という関数で3次元空間に射影します。3次元空間上では線形分離できるようになるので、線形 SVM で学習できます。
|
92
92
|
|
93
93
|
|
94
94
|
|
7
修正
test
CHANGED
@@ -212,7 +212,7 @@
|
|
212
212
|
|
213
213
|
|
214
214
|
|
215
|
-
decision_function(x, y, y^2) = 0
|
215
|
+
{(x, y)|decision_function(x, y, y^2) = 0, x, y∈ℝ} が元の2次元空間において、決定境界となります。
|
216
216
|
|
217
217
|
なので、decision_function(x, y, y^2) = 0 である等高線を contourf() で描画します。
|
218
218
|
|
6
修正
test
CHANGED
File without changes
|
5
修正
test
CHANGED
@@ -68,21 +68,23 @@
|
|
68
68
|
|
69
69
|
|
70
70
|
|
71
|
-
# データを描画する。
|
72
|
-
|
73
71
|
fig, ax = plt.subplots()
|
74
72
|
|
75
73
|
class_colors = ListedColormap(["g", "k"])
|
76
74
|
|
77
75
|
ax.scatter(X[:, 0], X[:, 1], c=y, cmap=class_colors)
|
78
76
|
|
77
|
+
ax.set_xlabel("Feature 0")
|
78
|
+
|
79
|
+
ax.set_ylabel("Feature 1")
|
80
|
+
|
79
|
-
plt.show()
|
81
|
+
plt.show()
|
80
|
-
|
82
|
+
|
81
|
-
```
|
83
|
+
```
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
|
85
|
+
|
86
|
+
|
85
|
-
![イメージ説明](
|
87
|
+
![イメージ説明](036baed9ee38ee684f918844f06a15b0.jpeg)
|
86
88
|
|
87
89
|
|
88
90
|
|
@@ -90,7 +92,43 @@
|
|
90
92
|
|
91
93
|
|
92
94
|
|
95
|
+
```python
|
96
|
+
|
97
|
+
X_new = np.hstack([X, X[:, 1:] ** 2])
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
fig = plt.figure(figsize=(7, 7))
|
102
|
+
|
103
|
+
ax = fig.add_subplot(111, projection="3d")
|
104
|
+
|
105
|
+
ax.scatter(X_new[:, 0], X_new[:, 1], X_new[:, 2], c=y, cmap=class_colors)
|
106
|
+
|
107
|
+
ax.view_init(30, 30)
|
108
|
+
|
109
|
+
ax.set_xlabel("Feature 0")
|
110
|
+
|
111
|
+
ax.set_ylabel("Feature 1")
|
112
|
+
|
113
|
+
plt.show()
|
114
|
+
|
115
|
+
```
|
116
|
+
|
117
|
+
|
118
|
+
|
93
|
-
![イメージ説明](
|
119
|
+
![イメージ説明](3ec79079b60dfa0ce697e2f8735932b2.jpeg)
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
fit() で学習します。
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
```python
|
128
|
+
|
129
|
+
svc = LinearSVC().fit(X_new, y)
|
130
|
+
|
131
|
+
```
|
94
132
|
|
95
133
|
|
96
134
|
|
@@ -144,58 +182,58 @@
|
|
144
182
|
|
145
183
|
ax = fig.add_subplot(111, projection="3d")
|
146
184
|
|
185
|
+
# 学習データの点を可視化する。
|
186
|
+
|
187
|
+
ax.scatter(X_new[:, 0], X_new[:, 1], X_new[:, 2], c=y, cmap=class_colors)
|
188
|
+
|
189
|
+
# 射影した空間上の各点と分類超平面との距離を可視化する。
|
190
|
+
|
191
|
+
sc = ax.scatter(XX, YY, ZZ, c=dist, cmap="bwr", vmin=-15, vmax=15)
|
192
|
+
|
193
|
+
# 分類超平面を可視化する。
|
194
|
+
|
195
|
+
ax.plot_surface(XX, YY, plane, alpha=0.5)
|
196
|
+
|
197
|
+
ax.view_init(30, 30)
|
198
|
+
|
199
|
+
ax.set_xlabel("Feature 0")
|
200
|
+
|
201
|
+
ax.set_ylabel("Feature 1")
|
202
|
+
|
203
|
+
fig.colorbar(sc)
|
204
|
+
|
205
|
+
plt.show()
|
206
|
+
|
207
|
+
```
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
![イメージ説明](526a7253e975e19285e63902f7bc8f48.jpeg)
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
decision_function(x, y, y^2) = 0 となる {(x, y)|x, y∈ℝ} が射影前の2次元において、決定境界となります。
|
216
|
+
|
217
|
+
なので、decision_function(x, y, y^2) = 0 である等高線を contourf() で描画します。
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
```python
|
222
|
+
|
223
|
+
fig, ax = plt.subplots()
|
224
|
+
|
225
|
+
class_colors = ListedColormap(["g", "k"])
|
226
|
+
|
227
|
+
# 決定境界を可視化する。
|
228
|
+
|
229
|
+
ax.contourf(
|
230
|
+
|
231
|
+
XX, YY, dist.reshape(XX.shape), levels=[dist.min(), 0, dist.max()], cmap="Set2"
|
232
|
+
|
233
|
+
)
|
234
|
+
|
147
235
|
# データを可視化する。
|
148
236
|
|
149
|
-
ax.scatter(X_new[:, 0], X_new[:, 1], X_new[:, 2], c=y, cmap=class_colors)
|
150
|
-
|
151
|
-
# 射影した空間上の各点と分類超平面との距離を可視化する。
|
152
|
-
|
153
|
-
sc = ax.scatter(XX, YY, ZZ, c=dist, cmap="bwr", vmin=-15, vmax=15)
|
154
|
-
|
155
|
-
# 分類超平面を可視化する。
|
156
|
-
|
157
|
-
ax.plot_surface(XX, YY, plane, alpha=0.5)
|
158
|
-
|
159
|
-
ax.view_init(30, 30)
|
160
|
-
|
161
|
-
ax.set_xlabel("x")
|
162
|
-
|
163
|
-
ax.set_ylabel("y")
|
164
|
-
|
165
|
-
fig.colorbar(sc)
|
166
|
-
|
167
|
-
plt.show()
|
168
|
-
|
169
|
-
```
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
![イメージ説明](6f9fd69905ad5c7069e81b6187125654.jpeg)
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
decision_function(x, y, y^2) = 0 となる {(x, y)|x, y∈ℝ} が射影前の2次元において、決定境界となります。
|
178
|
-
|
179
|
-
なので、decision_function(x, y, y^2) = 0 である等高線を contourf() で描画します。
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
```python
|
184
|
-
|
185
|
-
fig, ax = plt.subplots()
|
186
|
-
|
187
|
-
class_colors = ListedColormap(["g", "k"])
|
188
|
-
|
189
|
-
# 決定境界を可視化する。
|
190
|
-
|
191
|
-
ax.contourf(
|
192
|
-
|
193
|
-
XX, YY, dist.reshape(XX.shape), levels=[dist.min(), 0, dist.max()], cmap="Set2"
|
194
|
-
|
195
|
-
)
|
196
|
-
|
197
|
-
# データを可視化する。
|
198
|
-
|
199
237
|
ax.scatter(X[:, 0], X[:, 1], c=y, cmap=class_colors)
|
200
238
|
|
201
239
|
plt.xlabel("Feature 0")
|
4
修正
test
CHANGED
@@ -6,15 +6,11 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
1. XX, YY, ZZ はそれぞれ (50, 50) の2次元配列で、`ndarray.ravel()` で
|
9
|
+
1. `XX, YY, ZZ` はそれぞれ (50, 50) の2次元配列であり、`ndarray.ravel()` でそれぞれ (2500,) の1次元配列に変更しています。
|
10
|
-
|
10
|
+
|
11
|
-
1. `numpy.c_[XX.ravel(),YY.ravel(),ZZ.ravel()]` で結合しているので、(2500, 3) の2次元配列にな
|
11
|
+
1. `numpy.c_[XX.ravel(),YY.ravel(),ZZ.ravel()]` で3つの1次元配列を横方向に結合しているので、(2500, 3) の2次元配列になります。
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
|
15
|
-
こ
|
13
|
+
この (2500, 3) の2次元配列を `decision_function()` に渡しています。
|
16
|
-
|
17
|
-
`decision_function()` は (N, 特徴量の次元数) の2次元配列を渡す必要があるため、このようにしています。
|
18
14
|
|
19
15
|
|
20
16
|
|
@@ -36,7 +32,7 @@
|
|
36
32
|
|
37
33
|
|
38
34
|
|
39
|
-
dec.reshape(XX.shape) としているのは、contourf() の仕様上、dec の形状 (2500,) を XX, YY に合わせて (50, 50) にしなければいけないためです。
|
35
|
+
`dec.reshape(XX.shape)` としているのは、contourf() の仕様上、`dec` の形状 (2500,) を XX, YY に合わせて (50, 50) にしなければいけないためです。
|
40
36
|
|
41
37
|
|
42
38
|
|
@@ -44,7 +40,7 @@
|
|
44
40
|
|
45
41
|
|
46
42
|
|
47
|
-
|
43
|
+
[線形分離](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%88%86%E9%9B%A2%E5%8F%AF%E8%83%BD)できない2次元のデータが与えられたとします。
|
48
44
|
|
49
45
|
|
50
46
|
|
@@ -52,124 +48,164 @@
|
|
52
48
|
|
53
49
|
import matplotlib.pyplot as plt
|
54
50
|
|
55
|
-
import mglearn
|
56
|
-
|
57
51
|
import numpy as np
|
58
52
|
|
53
|
+
from matplotlib.colors import ListedColormap
|
54
|
+
|
55
|
+
from mpl_toolkits.mplot3d import Axes3D
|
56
|
+
|
59
57
|
from sklearn.datasets import make_blobs
|
60
58
|
|
61
59
|
from sklearn.svm import LinearSVC
|
62
60
|
|
63
61
|
|
64
62
|
|
65
|
-
#
|
63
|
+
# 2次元のデータを作成する。
|
66
64
|
|
67
65
|
X, y = make_blobs(centers=4, random_state=8)
|
68
66
|
|
69
67
|
y = y % 2
|
70
68
|
|
69
|
+
|
70
|
+
|
71
|
+
# データを描画する。
|
72
|
+
|
71
|
-
|
73
|
+
fig, ax = plt.subplots()
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
|
76
|
-
|
77
|
-
l
|
75
|
+
class_colors = ListedColormap(["g", "k"])
|
76
|
+
|
77
|
+
ax.scatter(X[:, 0], X[:, 1], c=y, cmap=class_colors)
|
78
|
+
|
79
|
+
plt.show()
|
78
80
|
|
79
81
|
```
|
80
82
|
|
81
83
|
|
82
84
|
|
85
|
+
![イメージ説明](4ba616b7f87151122b6dfbcbbfc85e08.jpeg)
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
このままでは線形分離できないので、Φ: (x1, x2) → (x1, x2, x2^2) という関数で3次元空間に射影します。
|
90
|
+
|
91
|
+
|
92
|
+
|
83
|
-
![イメージ説明](3
|
93
|
+
![イメージ説明](13ecab51534b9fcaeb76fa57ab549d4c.jpeg)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
94
|
+
|
88
|
-
|
89
|
-
|
90
|
-
|
95
|
+
|
96
|
+
|
91
|
-
|
97
|
+
射影した空間 {(x, y, y^2)|x, y∈ℝ} 上の各点と分類超平面との距離を [decision_function()](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC.decision_function) で計算します。
|
92
98
|
|
93
99
|
|
94
100
|
|
95
101
|
```python
|
96
102
|
|
103
|
+
# 射影した空間上の点を作成する。
|
104
|
+
|
105
|
+
xs = np.linspace(X_new[:, 0].min() - 2, X_new[:, 0].max() + 2, 50)
|
106
|
+
|
107
|
+
ys = np.linspace(X_new[:, 1].min() - 2, X_new[:, 1].max() + 2, 50)
|
108
|
+
|
109
|
+
XX, YY = np.meshgrid(xs, ys)
|
110
|
+
|
97
|
-
|
111
|
+
ZZ = YY ** 2
|
112
|
+
|
113
|
+
|
114
|
+
|
98
|
-
|
115
|
+
# 作成した点と分類超平面との距離を計算する。
|
116
|
+
|
117
|
+
dist = svc.decision_function(np.c_[XX.ravel(), YY.ravel(), ZZ.ravel()])
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
# SVM の超平面を計算する。
|
122
|
+
|
123
|
+
def hyper_plane(svc, XX, YY):
|
124
|
+
|
125
|
+
a1, a2, a3 = svc.coef_[0]
|
126
|
+
|
127
|
+
b = svc.intercept_[0]
|
128
|
+
|
129
|
+
return (-b - a1 * XX - a2 * YY) / a3
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
99
|
-
l
|
135
|
+
plane = hyper_plane(svc, XX, YY)
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
# 可視化する。
|
142
|
+
|
143
|
+
fig = plt.figure(figsize=(9, 7))
|
144
|
+
|
145
|
+
ax = fig.add_subplot(111, projection="3d")
|
146
|
+
|
147
|
+
# データを可視化する。
|
148
|
+
|
149
|
+
ax.scatter(X_new[:, 0], X_new[:, 1], X_new[:, 2], c=y, cmap=class_colors)
|
150
|
+
|
151
|
+
# 射影した空間上の各点と分類超平面との距離を可視化する。
|
152
|
+
|
153
|
+
sc = ax.scatter(XX, YY, ZZ, c=dist, cmap="bwr", vmin=-15, vmax=15)
|
154
|
+
|
155
|
+
# 分類超平面を可視化する。
|
156
|
+
|
157
|
+
ax.plot_surface(XX, YY, plane, alpha=0.5)
|
158
|
+
|
159
|
+
ax.view_init(30, 30)
|
160
|
+
|
161
|
+
ax.set_xlabel("x")
|
162
|
+
|
163
|
+
ax.set_ylabel("y")
|
164
|
+
|
165
|
+
fig.colorbar(sc)
|
166
|
+
|
167
|
+
plt.show()
|
100
168
|
|
101
169
|
```
|
102
170
|
|
103
171
|
|
104
172
|
|
105
|
-
|
173
|
+
![イメージ説明](6f9fd69905ad5c7069e81b6187125654.jpeg)
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
decision_function(x, y, y^2) = 0 となる {(x, y)|x, y∈ℝ} が射影前の2次元において、決定境界となります。
|
178
|
+
|
179
|
+
なので、decision_function(x, y, y^2) = 0 である等高線を contourf() で描画します。
|
106
180
|
|
107
181
|
|
108
182
|
|
109
183
|
```python
|
110
184
|
|
111
|
-
xx = np.linspace(X_new[:, 0].min() - 2, X_new[:, 0].max() + 2, 50)
|
112
|
-
|
113
|
-
yy = np.linspace(X_new[:, 1].min() - 2, X_new[:, 1].max() + 2, 50)
|
114
|
-
|
115
|
-
|
185
|
+
fig, ax = plt.subplots()
|
186
|
+
|
116
|
-
|
187
|
+
class_colors = ListedColormap(["g", "k"])
|
188
|
+
|
189
|
+
# 決定境界を可視化する。
|
190
|
+
|
117
|
-
|
191
|
+
ax.contourf(
|
118
|
-
|
192
|
+
|
119
|
-
|
193
|
+
XX, YY, dist.reshape(XX.shape), levels=[dist.min(), 0, dist.max()], cmap="Set2"
|
194
|
+
|
195
|
+
)
|
196
|
+
|
197
|
+
# データを可視化する。
|
198
|
+
|
199
|
+
ax.scatter(X[:, 0], X[:, 1], c=y, cmap=class_colors)
|
200
|
+
|
201
|
+
plt.xlabel("Feature 0")
|
202
|
+
|
203
|
+
plt.ylabel("Feature 1")
|
204
|
+
|
205
|
+
plt.show()
|
120
206
|
|
121
207
|
```
|
122
208
|
|
123
209
|
|
124
210
|
|
125
|
-
![イメージ説明](f3d3d3b5222c36db5aaebdabc0a12709.jpeg)
|
126
|
-
|
127
|
-
色は分類超平面からの距離を表す
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
この図の等高線を描画しているのが以下です。
|
132
|
-
|
133
|
-
等高線を引く位置は `dec.min(), 0, dec.max()` の3つにしており、dec==0 の等高線が分離超平面からの距離が0ということなので、つまり、これが分離超平面になります。
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
```
|
138
|
-
|
139
|
-
plt.contourf(
|
140
|
-
|
141
|
-
XX,
|
142
|
-
|
143
|
-
YY,
|
144
|
-
|
145
|
-
dec.reshape(XX.shape),
|
146
|
-
|
147
|
-
levels=[dec.min(), 0, dec.max()],
|
148
|
-
|
149
|
-
cmap=mglearn.cm2,
|
150
|
-
|
151
|
-
alpha=0.5,
|
152
|
-
|
153
|
-
)
|
154
|
-
|
155
|
-
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
|
156
|
-
|
157
|
-
plt.xlabel("Feature 0")
|
158
|
-
|
159
|
-
plt.ylabel("Feature 1")
|
160
|
-
|
161
|
-
```
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
![イメージ説明](
|
211
|
+
![イメージ説明](ee23606b23b8d2debce89dce1f583732.jpeg)
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
## コメント
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
書籍は持っていないのですが、特徴量の次元が3次元になっているので、決定境界の可視化を学ぶという目的には難解なサンプルだと思います。
|
174
|
-
|
175
|
-
2次元の特徴量を使って確認したほうが理解しやすいと思います。
|
3
修正
test
CHANGED
File without changes
|
2
修正
test
CHANGED
@@ -124,9 +124,13 @@
|
|
124
124
|
|
125
125
|
![イメージ説明](f3d3d3b5222c36db5aaebdabc0a12709.jpeg)
|
126
126
|
|
127
|
+
色は分類超平面からの距離を表す
|
128
|
+
|
127
129
|
|
128
130
|
|
129
131
|
この図の等高線を描画しているのが以下です。
|
132
|
+
|
133
|
+
等高線を引く位置は `dec.min(), 0, dec.max()` の3つにしており、dec==0 の等高線が分離超平面からの距離が0ということなので、つまり、これが分離超平面になります。
|
130
134
|
|
131
135
|
|
132
136
|
|
1
修正
test
CHANGED
@@ -36,7 +36,7 @@
|
|
36
36
|
|
37
37
|
|
38
38
|
|
39
|
-
dec.reshape(XX.shape) としているのは、contourf() の仕様上、dec の形状
|
39
|
+
dec.reshape(XX.shape) としているのは、contourf() の仕様上、dec の形状 (2500,) を XX, YY に合わせて (50, 50) にしなければいけないためです。
|
40
40
|
|
41
41
|
|
42
42
|
|
@@ -44,7 +44,7 @@
|
|
44
44
|
|
45
45
|
|
46
46
|
|
47
|
-
|
47
|
+
特徴空間 S = {(x, y, y**2)|x∈ℝ, y∈ℝ} 上のデータについて、今回考えています。特徴空間 S 上から適当な個数のサンプルを以下で生成しています。
|
48
48
|
|
49
49
|
|
50
50
|
|
@@ -84,7 +84,7 @@
|
|
84
84
|
|
85
85
|
|
86
86
|
|
87
|
-
青の曲面が特徴空間、点が生成されたサンプル
|
87
|
+
青の曲面が特徴空間、黄色、黒の点が生成されたサンプル
|
88
88
|
|
89
89
|
|
90
90
|
|