为了复杂的业务需求,我用pl/sql写了关于最小二乘法,协方差,曲线相关系数等复杂的数学计算,不可避免了用了很多循环,我曾经也想过用临时表去做计算,但是计算过程太复杂,很难实现,就算实现,我觉得也会走很多弯路,现在我是想,是不是可以用java来实现算法,然后封装成存储过程,这样会比较快。请各位前辈提点意见

解决方案 »

  1.   

    现在plsql好象有部分现成的数学计算
    我这几天看书的时候看到方差的,刚找了下COVAR_POP(expr1,expr2):该函数用于返回成对数字的协方差(Covariance),其数值使用表达式"(sum(expr1*expr2)-sum(expr1)*sum(expr2)/n)/n"COVAR_SAMP(expr1,expr2):该函数用于返回成对数字的协方差,其数值使用表达式
    "(sum(expr1*expr2)-sum(expr1)*sum(expr2)/n)/(n-1)"取得
    java好多东西也有现成的。东西没做过,不知道怎样快!但我认为,现成的东西都是底层实现,比你计算的要快
      

  2.   

    谢谢HelloWorld_001,函数我查过只有协方差和线性回归,有很多都不能满足需求。
      

  3.   

    那你查java的math类
    不知道有没有完整的数学计算,不能满足需求的话也是需要自己写的。我没写过这些。
      

  4.   

    写的话,没有问题。就是担心效率,查了一下,说是java是在oracle内部运行的,pl/sql是最快的,不免有点疑惑,怕写完后,白费劲。
      

  5.   

    这是我的逻辑,请各位高人指点,那中实现方式会比较快。
    模块1-求原始数据序列(如出帐收入)的移动平均数序列
    输入:1)原始数据序列;2)对应帐期;3)平滑步长i
    要求:1)平滑步长必须为大于1 的整数,且小于总帐期数;2)总帐期>=(2×i-1)个月;
    输出:移动平均数序列
    要求:1)移动平均数序列所处帐期必须是每月原始数据序列(如出帐收入)对应所有帐期的子
    集;2)如果i 为奇数,移动平均数列长途较原序列长度短i-1,如果i 为偶数,移动平均数列长
    度较原序列长度短i-2。
    加工过程:
    1) 从第一个帐期月开始,第i 个月开始计算移动平均数,该月移动平均数=(第1 月原始数
    据如“收入”+第2 月原始数据+…+第i 月原始数据) / i ;
    2) 依次求出剩余月的移动平均数原始值;
    3) 如果i 为奇数,计算完毕;
    4) 如果i 为偶数,则需要再次进行修正:当前月修正后移动平均数=(当前月移动平均数
    +次月移动平均数)/2。当前月为最后的帐期月时,因没有次月移动平均数,所以不再
    进行修正,该月移动平均数抛弃。
    模块2-求原始数据序列(如出帐收入)的季节指数
    输入:1)原始数据序列;2)对应帐期;3)平滑步长i
    要求:1)平滑步长必须为大于1 的整数,且小于总帐期数;2)总帐期>=(2×i-1)个月;
    输出:i 个月的每月季节指数
    加工过程:
    1) 调用模块1,得到缩短时间长度的移动平均数序列;
    2) 分别用移动平均序列所处帐期的原始数据(如出帐收入)除以该帐期移动平均值,得到
    不同帐期的样本季节指数;
    3) 对相同月份的样本季节指数进行平均,得到理论季节指数;
    4) 对每月季节指数进行修正:修正季节指数=理论季节指数×(1/(i 个月理论季节指数之
    和 / i)) ,完毕。
    模块3-求一元线性回归方程
    输入:1)自变量序列;2)因变量序列
    要求:自变量序列与因变量序列的长度相等
    输出:形似Y=a + b X 的一元回归方程,具体体现为两个数值:1)增长系数b ;2)截距a ;
    加工过程:
    1) 采用最小二乘法计算;
    2) 具体计算过程(置信度99%的情况下): ;
    3) EXCEL 计算过程参考:工具-》数据分析-》回归-》输入Y 值区域和X 值区域-》
    生成增长系数b 和截距a 。
    模块4-求相关系数
    输入:1)序列值1;2)序列值2
    输出:两个序列的相关系数r ;
    要求:1>= r >= -1
    加工过程:
    1) 具体计算过程:相关系数 ,其中,μx 为x 序列
    的平均数,μy 为y 序列的平均数。σx、σy 则分别为x、y 序列的标准差(计算过程见
    模块5)。
    2) EXCEL 计算过程参考:工具-》数据分析-》相关系数-》选择数据区域-》生成相
    关系数。或参考CORREL 函数。
    模块5-求标准差
    输入:序列值
    输出:该序列的标准差 ;
    加工过程:
    1) 具体计算过程: ;
    2) EXCEL 计算过程参考:STDEVP 函数。
    模块6-求原始数据序列(如出帐收入)在指定帐期内的成长序列
    输入:1)原始数据序列;2)对应帐期;3)平滑步长i;4)开始帐期;5)结束帐期
    要求:1)平滑步长必须为大于1 的整数,且小于原始数据序列总帐期数;2)原始数据序列总帐
    期>=(2×i-1)个月
    输出:指定帐期内每帐期的成长性数据序列
    加工过程:
    1) 调用模块2,得到i 个月的每月季节指数;
    2) 每月原始数据(如出帐收入)除以当月季节指数,得到去除季节因素的数据序列;
    3) 去除季节因素后,把指定帐期内的数据序列作为因变量序列,1、2、3、... n(指定帐期头
    尾长度) 为自变量序列,调用模块3 得到一元线性回归方程;
    4) 把自变量序列带入步骤3 得到的回归方程,得到成长序列,计算完毕。
    模块7-求原始数据序列(如出帐收入)在指定帐期内的随机指数序列
    输入:1)原始数据序列;2)对应帐期;3)平滑步长i;4)开始帐期;5)结束帐期
    要求:1)平滑步长必须为大于1 的整数,且小于原始数据序列总帐期数;2)原始数据序列总帐
    期>=(2×i-1)个月
    输出:指定帐期内所有帐期的随机指数序列
    加工过程:
    1) 调用模块2,得到i 个月的每月季节指数;
    2) 调用模块6,得到在指定帐期内的成长序列;
    3) 指定帐期内每月原始数据(如出帐收入)除以季节指数、成长收入,即得到该月随机指
    数;
    4) 依次按月执行步骤3,得到随机指数序列,计算完毕。
    模块8-求两个序列曲线的相异度
    输入:1)序列值1;2)序列值2;
    要求:1)序列个数相等;2)可一一对应;
    输出:相异度
    加工过程:
    1) 每个序列各自完成标准化过程,方法是序列中每个值除以序列的平均值;
    2) 两个标准化序列值按帐期对应相减,得到差值序列;
    3) 调用模块5,得到差值序列的标准差;
    4) 这个标准差是去除单位的,可以衡量两个曲线的相异度,计算完毕。
    模块9-求多个自变序列曲线对因变序列曲线的影响度
    输入:1)因变序列值;2)自变序列值1~自变序列值N,N 为自然数;
    要求:1)每个序列个数相等;2)可一一对应;
    输出:自变序列值1~N 对因变序列值的各自影响度
    要求:影响度值有N 个,格式均为百分比数,精确至小数点后两位
    加工过程:
    1) 调用模块8,求出因变序列值与每个自变序列值之间的相异度;
    2) 调用模块4,求出因变序列值与每个自变序列值之间的相关系数;
    3) 根据各个相异度及相关系数求影响度,具体公式为:
    1. 相关系数>=0 时,某自变序列的影响度=(1-该序列的相异度 /(所有自变序列相
    异度之和))/2;
    2. 相关系数<0 时,某自变序列的影响度=-1×(1-该序列的相异度 /(所有自变序
    列相异度之和))/2。