def mini_banch_SGD(matX, matY, cf):
    '''
    function:批量随机梯度下降
    :param matX:
    :param matY:
    :return:
    '''
    count = 0  # 当前迭代次数
    matA = np.random.randn(cf.k)
    old_matA = matA
    # 确认最小梯度
    if cf.n/10 > 1:
        least_banch = int(cf.n/10)
    else:
        least_banch = 1
    while count < cf.loop_max:
        sum_m = np.zeros(cf.k)  # 记录一批数据的梯度差
        count += 1
        chosen = np.random.randint(0, cf.n, least_banch)  # 生成随机数
        for i in chosen:
            # 计算梯度
            diff = matX[i].dot(matX[i].dot(matA.T) - matY[i])
            sum_m = sum_m + diff  # 计算梯度和
        sum_m = sum_m/len(chosen)

        if np.linalg.norm(sum_m) < cf.epsilon:
            break
        # 带有正则化的loss
        matA = matA*(1-cf.theta*cf.alpha/len(chosen)) - cf.alpha*sum_m
        # 提前结束
        if np.linalg.norm(matA - old_matA) < cf.epsilon:
            break
        old_matA = matA
        print('count=', count, 'loss=', function.RMSE(matX, matY, matA))
    return matA
def SGD(matX, matY, cf):
    count = 0  # 当前迭代次数
    matA = np.zeros(cf.k)
    old_matA = matA
    while count < cf.loop_max:
        count += 1
        for i in range(cf.n):
            # 计算梯度
            diff = matX[i].dot(matX[i].dot(matA.T) - matY[i])
            # 带有正则化的loss
            matA = matA * (1 - cf.theta * cf.alpha) - cf.alpha * diff

        # 提前结束
        if np.linalg.norm(matA-old_matA) < cf.epsilon:
            break
        old_matA = matA
        print('count=',count,'loss=',function.RMSE(matX,matY,matA))
    return matA
def fitting(matX,matY,cf):
    #计算X.T*X
    squareX = np.dot(matX.T, matX)
    invX = np.linalg.inv(squareX)
    MatA = (invX.dot(matX.T)).dot(matY)
    return MatA

# 加入正则化的最小二乘法
def fittingRegular(matX,matY,cf):
    #计算X.T*X+NRI
    squareX = np.dot(matX.T, matX) + cf.n*cf.theta*np.eye(cf.k, cf.k)
    invX = np.linalg.inv(squareX)
    MatA = (invX.dot(matX.T)).dot(matY)
    return MatA

if __name__ == '__main__':
    cf = function.config(-20, 20, 200, 25, 3e-7, 150000, 1e-20, 0.0)
    x,y = function.create_data(cf.x0, cf.x1, cf.n)
    #print(x,y)
    matX, matY = function.create_mat(x,y,cf.k)
    #print(matX)
    #print(matY)
    #print(matA)
    matA = fitting(matX,matY,cf)
    #print(matA)
    err = function.RMSE(matX,matY,matA)
    print(err)
    plt.title('Least Squares with Regular')
    function.show(x,y,matX, matA)
Esempio n. 4
0
    # 梯度下降法,无正则项
    cf.theta = 0
    matA3 = gd.SGD(matX, matY, cf)

    # 梯度下降法,有正则项
    cf.theta = 0.3
    matA4 = gd.SGD(matX, matY, cf)

    # 共轭梯度法
    matA5 = cg.CG(matX, matY, cf)

    plt.plot(x, y, color='b', linestyle='', marker='.')
    plt.plot(x, matX.dot(matA1), color='R', linestyle='-', marker='', label='least squares')

    plt.plot(x, matX.dot(matA2), color='b', linestyle='-', marker='', label='least squares with regular')

    plt.plot(x, matX.dot(matA3), color='c', linestyle='-', marker='', label='gradient descent')

    plt.plot(x, matX.dot(matA4), color='m', linestyle='-', marker='', label='gradient descent with regular')

    plt.plot(x, matX.dot(matA5), color='g', linestyle='-', marker='', label='conjugate gradient')
    plt.legend(loc='upper right')
    print('least squares                 =', function.RMSE(matX,matY,matA1))
    print('least squares with regular    =', function.RMSE(matX, matY, matA2))
    print('gradient descent              =', function.RMSE(matX, matY, matA3))
    print('gradient descent with regular =', function.RMSE(matX, matY, matA4))
    print('conjugate gradient            =', function.RMSE(matX, matY, matA5))
    plt.show()