美文网首页
优化器: 构建参数化模型

优化器: 构建参数化模型

作者: D_Major | 来源:发表于2019-05-07 22:22 被阅读0次

    优化器:

    • 可以找到函数取最小值时的点
    • 从数据中找到参数化模型的参数, 即寻找多项式拟合曲线
    • 改善股票投资组合中分配方式

    优化器求最小值

    import scipy.optimize as spo
    
    def f(X):
        Y = (X - 1.5)**2 + 0.5
        return Y
    
    def test_run():
        Xguess = 2.0
        min_result = spo.minimize(f, Xguess, method='SLSQP', options={'disp': True})  # disp表示详细描述结果
        print "Minima found at:"
        print "X={}, Y={}".format(min_result.x, min_result.fun)
    

    凸函数只有一个局部最小值, 即全局最小值

    误差函数

    import scipy.optimize as spo
    
    def error(line, data):
        """
        line: tuple/list/array (C0, C1), C0斜率, C1截距
        data: 2D-array, 点(x, y)
        返回实数error
        """
        err = np.sum((data[:, 1] - (line[0] * data[:, 0] + line[1])) ** 2)
        return err
    
    def fit_line(data, error_func):
        """data: (x,y) array"""
        # 生成模型的初始位置guess
        l = np.float32([0, np.mean(data[:, 1])])  # 斜率为0, 截距为y的均值, 即一条横着的直线
        # 画出初始直线
        x_ends = np.float32([-5, 5])
        plt.plot(x_ends, l[0] * x_ends + l[1], 'm--', linewidth=2.0, label="Initial guess")
        # 调用优化器使损失函数最小, 返回目标直线, args里的数据传给error_func
        result = spo.minimize(error_func, l, args=(data,),  method='SLSQP', options={'disp': True})
        
        return result.x
    
    def test_run():
        l_orig = np.float32([4, 2])  # 原始直线, C0=4, C1=2
        Xorig = np.linspace(0, 10, 21)  # 等差数列, [0, 10], 21个点(含端点)
        Yorig = l_orig[0] * Xorig + l_orig[1]
        plt.plot(Xorig, Yorig, 'b--', linewidth=2.0, label="Original line") 
    
        # 生成噪声干扰点
        noise_sigma = 3.0  # 标准差
        noise = np.random.normal(0, noise_sigma, Yorig.shape)
        data = np.asarray([Xorig, Yorig + noise]).T
        plt.plot(data[:, 0], data[:, 1], 'go', label="Data points")
    
        # 尝试拟合
        l_fit = fit_line(data, error)  # return [C0, C1]
        plt.plot(data[:, 0], l_fit[0] * data[:, 1] + l_fit[1], 'r--', linewidth=2.0, label="Fit line")
    
        plt.show()
    

    拟合多项式曲线 np.polyval()

    def error_poly(C, data):
        """
        C: numpy.poly1d object or equivalent array representing polynomial coefficients(系数)
        data: 2-D array (x, y)
        """
        err = np.sum((data[:, 1] - np.polyval(C, data[:, 0])) ** 2)
        return err
    
    def fit_poly(data, error_func, degree=3)
        """data: 2-D array (x, y), degree: 多项式次数"""
        # initial guess (all coeffs = 1) 初始系数等于1
        Cguess = np.poly1d(np.ones(degree + 1, np.float32))  # 4个1, 3次多项式+1个常数项
        
        # 画出initial guess
        x = np.linspace(-5, 5, 21)
        plt.plot(x, np.polyval(Cguess, x), 'm--', linewidth=2.0, label="Initial guess") 
    
        result = spo.minimize(error_func, Cguess, args=(data,),  method='SLSQP', options={'disp': True})
        
        return np.poly1d(result.x)
    
    • np.polyfit(), 多项式曲线拟合, 获得多项式各系数:
    poly = np.polyfit(x_data, y_data, deg = 1)
    
    • np.polyval(), 多项式曲线求值, 可以理解为代入x求多项式y值:
    plt.plot(x_data, np.polyval(poly, x_data))
    
    • np.poly1d(c_or_r, r=False, variable=None), 表征多项式, 当r=False时, 传入系数矩阵c, 返回poly1d多项式对象. 当r=True时, 传入方程根, 反推多项式. variable表示用不同字母表示自变量
      方法: p.c返回系数矩阵, p.r返回方程的根, p.o返回最高项次数, p(0.5)表示代入x=0.5时多项式的值, p[1]返回第一项系数
    如果f(x) = 2x^2 +x +1
    np.poly1d(5) # 或np.poly1d([5])
    Out[77]: poly1d([5])  # 常数项
    a= np.array([2,1,1])
    p = np.poly1d(a)
    p
    Out[78]: poly1d([2, 1, 1])      # 等同于2*x^2  + 1* x^1 +1*x^0 = 2x^2 + x +1
    print(p)
    2 x^2 + 1 x + 1
    代入值:
    p([1,2,3])
    Out[80]: array([ 4, 11, 22])  # 分别代入1, 2, 3的返回值
    

    对poly1d( )对象进行加减乘除运算,相当于对应多项式函数进行计算,如:

    >>> p+[-2,1] #和p+np.poly1d([-2,1])相同,-2x+1        等于2x^2 +x +1 -2x  +1 = 2x^2 -x +2
    Out[81]: poly1d([ 2, -1,  2]) 
    >>> p*p #两个3次多项式相乘,得到一个6次多项式     等于(2x^2 +x +1)^2=4x^4 + 4x^3 +5x^2+2x+1
    Out[82]:poly1d([4, 4, 5, 2, 1]) 
    >>> p/[1,1] #返回2个多项式除法的结果,分别为商式和余式  
    Out[83]: (poly1d([ 2., -1.]), poly1d([ 2.]))          (x+1)(2x-1)+2 = 2x^2+x +1
     
    多项式对象的deriv( )和integ( )方法分别用于计算多项式函数的微分和积分,如:
    >>> p.deriv()     #微分
    Out[84]: poly1d([4, 1])
    >>> p.integ()     #积分        integ(m=1,k= 0)   m是积几次分,k是常数项是多少
    Out[85]: poly1d([ 0.66666667, 0.5 , 1. , 0. ])
    
    多项式函数的根可以用roots( )计算:
    >>> np.roots(p)
    Out[86]: array([-0.25+0.66143783j, -0.25-0.66143783j])
    

    优化器: 优化投资组合

    计算量最少最简单的优化方式是对累计收益进行优化, 只需100%投入到回报最高的股票即可

    优化夏普指数:

    优化分配比例使负夏普指数最小, 从而使夏普指数最大

    优化器加速:

    1. 限定x范围, 比如将分配比例限制在[0, 1]
    2. 设定约束条件, 比如分配比例之和要为1

    相关文章

      网友评论

          本文标题:优化器: 构建参数化模型

          本文链接:https://www.haomeiwen.com/subject/vhkuoqtx.html