SGD没有使用Python

时间:2017-06-07 15:06:31

标签: python machine-learning gradient-descent

我一直试图在数据集上使用分解机器(http://www.algo.uni-konstanz.de/members/rendle/pdf/Rendle2010FM.pdf)来解决分类问题(ERROR VS NO ERROR),使用随机梯度下降作为学习方法。 我试图将它用于非常稀疏的矩阵(1000列,仅1-0,大约90%的条目值为0)。

事情并没有真正起作用:当我尝试将我的代码应用于testing_set时,V和w在此过程中几乎是不变的。没有任何变化或趋同或任何变化。 结果是,最终,我得到了一个预测数据,其中绝对没有检测到错误 我的第一个猜测是,可能是因为我的数据非常不平衡(10%的错误),所以我根据这个改变了我的训练集,现在我已经获得了14000的训练集7000个错误的行。仍然没有改变一件事!

我整天都在努力去看我错在哪里,但我似乎无法找到它。我试过了'ypred'和' grad_hinge'关于V,w的非常具体的值,在纸上做了数学计算,它们似乎都很好用 SDG只使用这两个功能,在我看来,与理论上的SDG相比,实现是好的(http://cs229.stanford.edu/notes/cs229-notes1.pdf,第7页)。

这是我的代码:

def ypred(V,w,x):
j=0
x2=[nb*nb for nb in x]
for f in range (V.shape[1]):
    v2=[nb*nb for nb in V[:,f]]
    j+=np.dot(x,V[:,f])**2-np.dot(x2,v2)
return w[0]+np.dot(w[1:],x)+0.5*j

第一个是Rendle的文章(第2页和第3页)中介绍的y_hat。我用

进行了测试
Vtest=np.array([[0.5,3,4],[5,1,0],[8,1,2],[9,-4,5]])
wtest=np.array([0.5,0.3,2,4,0.8])
xtest=np.array([1,4,6,2])
y_main=0.5+(0.3+8+24+1.6)+0.5*((0.5+20+48+18)**2-(0.25+400+1728+324)+(3+4+6-8)**2-(9+16+36+64)+26**2-(16+144+60))
ypred(Vtest,wtest,xtest)

我得到 y_pred = 2914.4 ,这是个好结果。

def grad_hinge(V,w,x,y):
Jv=np.zeros(V.shape)
Jw=np.zeros(len(w))
y_hat=ypred(V,w,x)
c=y*y_hat
Jw[0]= 0 if c > 1 else -y
for i in range (1,len(w)):
    Jw[i]= 0 if  c > 1 else -y*x[i-1]
for i in range (V.shape[0]):
    for k in range (V.shape[1]):
        Jv[i,k]=0 if c > 1 else -y*(x[i]*np.dot(V[:,k],x)-V[i,k]*(x[i]**2))
return Jw,Jv

grad_hinge用于铰链损耗梯度。有两类参数(w_i和v_ {i,j}),这就是我引入Jw和Jv的原因。经测试:

Vtest=np.array([[0.5,3],[5,1],[-2,1],[1,-4]])
wtest=np.array([0.5,0.3,2,4,0.8])
xtest=np.array([1,0,0,1])
y=1
print(ypred(Vtest,wtest,xtest))
print(grad_hinge(Vtest,wtest,xtest,y))

返回 w = [ - 1,-1,0,0,-1] V = [[ - 1,4],[0,0],[0 ,0],[ - 0.5,-3]] ,这是预期的结果。

def SDG(V,w,X,Y,a,c,niter):
delta1, delta2, epoch = [100],[100], 0
while ((norm(delta1, np.inf) >c or norm(delta2, np.inf)>c) and epoch < niter) :
    for i in range (X.shape[0]):
        print(i*100/X.shape[0])
        Jw,Jv=grad_hinge(V,w,X[i],Y[i])
        w1=np.array([w[j]-a*Jw[j] for j in range(len(w))])
        V1=np.zeros(V.shape)
        for i in range (V.shape[0]):
            V1[i]=[V[i,k] - a*Jv[i,k] for k in range (V.shape[1])]
    delta1=w1-w
    delta2=V1-V
    w,V=w1,V1
    epoch+=1
print(epoch)
return w,V

在这里,我尝试按照Andrew Ng的课程(在那里链接)中的描述实现SGD。

有人能告诉我在我的代码中我可能有缺陷吗? 谢谢 !

0 个答案:

没有答案