Давайте подумаем об этом шаг за шагом
def f():
# w.shape = (n,1)
# X.shape = (m,n)
# y.shape = (m,)
# v.shape = (n,n)
# c is constant
for t in range(len(X)):
x = X[t].reshape((1,-1))
X
is (m, n), x
is (n,), преобразованный в (1, n)
flag = np.dot(x, w)*y[t]
flag
- это dot of (1,n) with (n,1) => (1,1) times scalar element of
y`; скалярный результат
Как насчет (m, n) X
точки с (n, 1) для получения (m, 1)? (X@w)*y[:,None]
=> (м, 1).
В качестве альтернативы X@w[:,0])*y
для создания (м) формы
cov = np.matmul(np.matmul(x, v), x.T) # cov is a scalar
matmul/dot
x
с v
, (1, n) с (n, n) => (1, п); и matmul/dot
с (n, 1) => (1,1)
Снова с использованием X
: X@v
(m,n)@(n,n)=>(m,n)
Еще одна (n, 1) точка для получения (m, 1)
cov = X@v@X.T
if flag<1:
b = 1.0/(cov + c)
a = max(0.0, 1-flag) * b
w += a*y[t]*np.matmul(v, x.T)
v -= b*np.matmul(np.matmul(v, x.T), np.matmul(x, v))
Если flag
равен (m, 1) или (m,), мы не можем использовать if
. Но мы делаем
mask = flag < 1
b = 1.0/(cov[mask]+c # (k,) (k less than m)
a = np.amax(0.0, 1-flag[mask]) * b # (k,)
w = np.sum(a*y[mask]*(X[mask,:]@v), axis=?) # ???
v ???
Я не проработал детали в последней части. Чтобы было ясно, вы можете назвать X[mask,:]
, cov[mask]
, flag[mask]
, y[mask]
, так что теперь у вас есть куча массивов (p, n) и (p,).
return w, v