之前用DeepSeek编程计算了较为简单的SEM,现在用DeepSeek编程计算较为复杂的SEM,如下:

import org.apache.commons.math3.linear.*;

import org.apache.commons.math3.optim.*;

import org.apache.commons.math3.optim.nonlinear.scalar.GoalType;

import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunction;

import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.BOBYQAOptimizer;

import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.CMAESOptimizer;

import org.apache.commons.math3.random.JDKRandomGenerator;

import java.util.Arrays;

public class SEMPathAnalysis {

    private static final RealMatrix S = MatrixUtils.createRealMatrix(new double[][] {

          {1, 0.2, 0.3, 0.1, 0.15, 0.2, 0.1, 0.12, 0.15},

        {0.2, 1, 0.4, 0.12, 0.18, 0.22, 0.11, 0.13, 0.16},

        {0.3, 0.4, 1, 0.15, 0.2, 0.25, 0.12, 0.14, 0.17},

        {0.1, 0.12, 0.15, 1, 0.3, 0.4, 0.15, 0.18, 0.2},

        {0.15, 0.18, 0.2, 0.3, 1, 0.5, 0.18, 0.2, 0.22},

        {0.2, 0.22, 0.25, 0.4, 0.5, 1, 0.2, 0.22, 0.25},

        {0.1, 0.11, 0.12, 0.15, 0.18, 0.2, 1, 0.3, 0.4},

        {0.12, 0.13, 0.14, 0.18, 0.2, 0.22, 0.3, 1, 0.5},

        {0.15, 0.16, 0.17, 0.2, 0.22, 0.25, 0.4, 0.5, 1}});

    public static void main(String[] args) {

        // 初始参数猜测

        double[] initialParams = new double[15];

        Arrays.fill(initialParams, 0.01);

        initialParams[3] = 0.3; // psi_A

        initialParams[4] = 0.3; // psi_B

        initialParams[5] = 0.3; // phi_C

        for (int i = 6; i < 15; i++) {

            initialParams[i] = 0.1; // theta1-theta9

        }

        double[]lowerBounds={-5,-5,-5,0,0,0,0,0,0,0,0,0,0,0,0};//每个维度的下界

        double[]upperBounds={5,5,5,5,5,5,5,5,5,5,5,5,5,5,5}; // 每个维度的上界

        SimpleBounds bounds = new SimpleBounds(lowerBounds, upperBounds);

      

        BOBYQAOptimizer bobyqa = new BOBYQAOptimizer(

                 15 + 2, // 插值点数

                 0.1,    // 初始信任区域半径

                 0.001   // 停止半径

             );

             PointValuePair intermediateResult = bobyqa.optimize(

                 new MaxEval(5000),

                 new ObjectiveFunction(params -> computeML(params)),

                 GoalType.MINIMIZE,

                 new InitialGuess(initialParams),

                 new SimpleBounds(lowerBounds, upperBounds)

             );

             CMAESOptimizer optimizer = new CMAESOptimizer(

                 10000, 1e-8, true, 0, 0,

                 new JDKRandomGenerator(), false,

                 new SimpleValueChecker(1e-6, 1e-6)

             );

             PointValuePair result = optimizer.optimize(

                 new MaxEval(10000),

                 new ObjectiveFunction(params -> computeML(params)),

                 GoalType.MINIMIZE,

                 new CMAESOptimizer.Sigma(new double[]{0.05, 0.05, 0.05, 0.03, 0.03, 0.03, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01}),

                 new CMAESOptimizer.PopulationSize(15),

                 new InitialGuess(intermediateResult.getPoint()),

                 new SimpleBounds(lowerBounds, upperBounds)

             );

        double[] optimalParams = result.getPoint();

        System.out.printf("gamma1: %.3f, gamma2: %.3f, beta: %.3f%n",

                optimalParams[0], optimalParams[1], optimalParams[2]);

    }

    private static double computeML(double[] params) {

        try {

            double gamma1 = params[0];

            double gamma2 = params[1];

            double beta = params[2];

            double psiA = params[3];

            double psiB = params[4];

            double phiC = params[5];

            double[] theta = Arrays.copyOfRange(params, 6, 15);

            // 计算潜变量协方差

            double varB = gamma2 * gamma2 * phiC + psiB;

            double covBC = gamma2 * phiC;

            double varA = Math.pow(gamma1 + beta * gamma2, 2) * phiC + beta * beta * varB + 2 * beta * (gamma1 + beta * gamma2) * covBC + psiA;

            double covAB = (gamma1 + beta * gamma2) * gamma2 * phiC + beta * varB;

            double covAC = (gamma1 + beta * gamma2) * phiC;

            // 构建隐含协方差矩阵

            RealMatrix sigma = MatrixUtils.createRealMatrix(9, 9);

            // 填充潜变量A的块

            for (int i = 0; i < 3; i++) {

                for (int j = 0; j < 3; j++) {

                    sigma.setEntry(i, j, i == j ? varA + theta[i] : varA);

                }

            }

            // 填充潜变量B的块

            for (int i = 3; i < 6; i++) {

                for (int j = 3; j < 6; j++) {

                    sigma.setEntry(i, j, i == j ? varB + theta[i] : varB);

                }

            }

            // 填充潜变量C的块

            for (int i = 6; i < 9; i++) {

                for (int j = 6; j < 9; j++) {

                    sigma.setEntry(i, j, i == j ? phiC + theta[i - 6] : phiC);

                }

            }

            // 填充跨潜变量的协方差

            for (int i = 0; i < 3; i++) {

                for (int j = 3; j < 6; j++) {

                    sigma.setEntry(i, j, covAB);

                    sigma.setEntry(j, i, covAB);

                }

                for (int j = 6; j < 9; j++) {

                    sigma.setEntry(i, j, covAC);

                    sigma.setEntry(j, i, covAC);

                }

            }

            for (int i = 3; i < 6; i++) {

                for (int j = 6; j < 9; j++) {

                    sigma.setEntry(i, j, covBC);

                    sigma.setEntry(j, i, covBC);

                }

            }

           

            SingularValueDecomposition svd = new SingularValueDecomposition(sigma);

            double logDet = 0;

            for (double s : svd.getSingularValues()) {

                logDet += Math.log(s);

            }

            RealMatrix invSigma = svd.getSolver().getInverse();

           

           

           

            RealMatrix product = S.multiply(invSigma);

            double trace = 0;

            for (int i = 0; i < 9; i++) trace += product.getEntry(i, i);

            return logDet + trace;

        } catch (Exception e) {

            return Double.MAX_VALUE;

        }

    }

}

两次的运行结果为:

gamma1: 0.214, gamma2: 0.517, beta: 0.263

gamma1: 0.205, gamma2: 0.519, beta: 0.267

第二次相当于:

C -> A 路径系数: 0.205

C -> B 路径系数: 0.519

B -> A 路径系数: 0.267

下来后用lisrel计算了一下,结果为:

C -> A 路径系数: 0.17

C -> B 路径系数: 0.45

B -> A 路径系数: 0.40

看来还有很多改进的空间哦。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐