Here's one vectorized approach making use of the efficient matrix-multiplication with np.dot -
n = y.shape[0]
exp_val = (1 - 1 / (1 + np.exp(-np.dot(X,w)*y)))
out = -(y*exp_val).dot(X)/n
We are basically solving/vectorizing it in two parts :
1) Vectorizing : np.dot(X[i],w) * y[i] by doing np.dot(X,w), thus performing all those iterative dot-products in one go.
2) Simulating the mean of y[i] * X[i] * exponential_part with a dot-product, which does the sum-reduction and then dividing by the number of elements along the axis of reduction.
Runtime test and verification
Approaches -
def original_app(y,X,w):
return [np.mean([-y[i] * X[i] * (1 - 1 / (1 + np.exp( - \
np.dot(X[i],w) * y[i]))) for i in range(X.shape[0])], axis = 0)]
def vectorized_app(y,X,w):
n = y.shape[0]
exp_val = (1 - 1 / (1 + np.exp(-np.dot(X,w)*y)))
out = -(y*exp_val).dot(X)/n
return out
Timings -
In [117]: N,M = 300,400
...: y = np.random.rand(N)
...: X = np.random.rand(N,M)
...: w = np.random.rand(M)
...:
In [118]: out1 = original_app(y,X,w)
In [120]: out2 = vectorized_app(y,X,w)
In [121]: np.allclose(out1, out2)
Out[121]: True
In [122]: %timeit original_app(y,X,w)
1000 loops, best of 3: 1.29 ms per loop
In [123]: %timeit vectorized_app(y,X,w)
10000 loops, best of 3: 47.1 µs per loop