com.itemanalysis.jmetrik.stats.irt.linking.CommonItemSummaryStatistics.java Source code

Java tutorial

Introduction

Here is the source code for com.itemanalysis.jmetrik.stats.irt.linking.CommonItemSummaryStatistics.java

Source

/*
 * Copyright (c) 2012 Patrick Meyer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.itemanalysis.jmetrik.stats.irt.linking;

import com.itemanalysis.psychometrics.data.VariableName;
import com.itemanalysis.psychometrics.irt.equating.RobustZEquatingTest;
import com.itemanalysis.psychometrics.irt.model.IrmType;
import com.itemanalysis.psychometrics.irt.model.ItemResponseModel;
import com.itemanalysis.psychometrics.polycor.PearsonCorrelation;
import com.itemanalysis.psychometrics.texttable.TextTable;
import com.itemanalysis.psychometrics.texttable.TextTableColumnFormat;
import com.itemanalysis.psychometrics.texttable.TextTablePosition;
import org.apache.commons.math3.stat.descriptive.moment.Mean;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Formatter;
import java.util.LinkedHashMap;

public class CommonItemSummaryStatistics {

    private LinkedHashMap<String, ItemResponseModel> irmX = null;
    private LinkedHashMap<String, ItemResponseModel> irmY = null;
    private ArrayList<VariableName> varNamesA = null;
    private ArrayList<VariableName> varNamesB = null;
    private double[] aX = null;
    private double[] bX = null;
    private double[] cX = null;
    private double[] aY = null;
    private double[] bY = null;
    private double[] cY = null;
    private int numberOfCommonItems = 0;

    private Mean xAMean;
    private Mean yAMean;
    private Mean xBMean;
    private Mean yBMean;
    private Mean xCMean;
    private Mean yCMean;

    private StandardDeviation xASd;
    private StandardDeviation yASd;
    private StandardDeviation xBSd;
    private StandardDeviation yBSd;
    private StandardDeviation xCSd;
    private StandardDeviation yCSd;

    public CommonItemSummaryStatistics(LinkedHashMap<String, ItemResponseModel> irmX,
            LinkedHashMap<String, ItemResponseModel> irmY) {
        this.irmX = irmX;
        this.irmY = irmY;
        varNamesA = new ArrayList<VariableName>();
        varNamesB = new ArrayList<VariableName>();
        numberOfCommonItems = irmX.size();
        createArrays();
    }

    private void createArrays() {
        xAMean = new Mean();
        yAMean = new Mean();
        xBMean = new Mean();
        yBMean = new Mean();
        xCMean = new Mean();
        yCMean = new Mean();

        xASd = new StandardDeviation();
        yASd = new StandardDeviation();
        xBSd = new StandardDeviation();
        yBSd = new StandardDeviation();
        xCSd = new StandardDeviation();
        yCSd = new StandardDeviation();

        int xBinary = 0;
        int xPolytomous = 0;
        int xTotalSteps = 0;
        ItemResponseModel irm;
        for (String s : irmX.keySet()) {
            irm = irmX.get(s);
            if (irm.getNcat() == 2) {
                xBinary++;
            } else {
                xPolytomous++;
            }
            xTotalSteps += (irm.getNcat() - 1);
        }

        aX = new double[xBinary + xPolytomous];
        bX = new double[xTotalSteps];
        cX = new double[xBinary];

        int yBinary = 0;
        int yPolytomous = 0;
        int yTotalSteps = 0;
        for (String s : irmY.keySet()) {
            irm = irmY.get(s);
            if (irm.getNcat() == 2) {
                yBinary++;
            } else {
                yPolytomous++;
            }
            yTotalSteps += (irm.getNcat() - 1);
        }

        aY = new double[yBinary + yPolytomous];
        bY = new double[yTotalSteps];
        cY = new double[yBinary];

        //populate arrays for Form X
        int itemIndex = 0;
        int binaryIndex = 0;
        int polyIndex = 0;
        int ncat = 0;
        for (String s : irmX.keySet()) {
            irm = irmX.get(s);
            ncat = irm.getNcat();

            varNamesA.add(new VariableName(s));

            aX[itemIndex] = irm.getDiscrimination();
            xAMean.increment(aX[itemIndex]);
            xASd.increment(aX[itemIndex]);

            if (ncat == 2) {
                cX[binaryIndex] = irm.getGuessing();
                xCMean.increment(cX[binaryIndex]);
                xCSd.increment(cX[binaryIndex]);

                bX[polyIndex] = irm.getDifficulty();
                xBMean.increment(bX[polyIndex]);
                xBSd.increment(bX[polyIndex]);

                binaryIndex++;
                polyIndex++;
                varNamesB.add(new VariableName(s));
            } else {
                double[] steps;
                if (irm.getType() == IrmType.GPCM || irm.getType() == IrmType.PCM2) {
                    steps = irm.getStepParameters();
                    steps = Arrays.copyOfRange(steps, 1, steps.length);//Omit first step since it is zero.
                } else {
                    steps = irm.getStepParameters();
                }

                for (int k = 0; k < steps.length; k++) {
                    bX[polyIndex] = steps[k];
                    xBMean.increment(bX[polyIndex]);
                    xBSd.increment(bX[polyIndex]);

                    polyIndex++;
                    varNamesB.add(new VariableName(s + "_" + (k + 1)));
                }
            }
            itemIndex++;

        } //end loop over items

        //populate arrays for Form Y
        itemIndex = 0;
        binaryIndex = 0;
        polyIndex = 0;
        ncat = 0;
        for (String s : irmY.keySet()) {
            irm = irmY.get(s);
            ncat = irm.getNcat();

            aY[itemIndex] = irm.getDiscrimination();
            yAMean.increment(aY[itemIndex]);
            yASd.increment(aY[itemIndex]);

            if (ncat == 2) {
                cY[binaryIndex] = irm.getGuessing();
                yCMean.increment(cY[binaryIndex]);
                yCSd.increment(cY[binaryIndex]);

                bY[polyIndex] = irm.getDifficulty();
                yBMean.increment(bY[polyIndex]);
                yBSd.increment(bY[polyIndex]);

                binaryIndex++;
                polyIndex++;
            } else {
                double[] steps;
                if (irm.getType() == IrmType.GPCM || irm.getType() == IrmType.PCM2) {
                    steps = irm.getStepParameters();
                    steps = Arrays.copyOfRange(steps, 1, steps.length);//Omit first step since it is zero.
                } else {
                    steps = irm.getStepParameters();
                }

                for (int k = 0; k < steps.length; k++) {
                    bY[polyIndex] = steps[k];
                    yBMean.increment(bY[polyIndex]);
                    yBSd.increment(bY[polyIndex]);

                    polyIndex++;
                }
            }
            itemIndex++;

        } //end loop over items

    }

    public String robustZTest() {
        StringBuilder sb = new StringBuilder();
        RobustZEquatingTest robustZ = new RobustZEquatingTest(aX, aY, bX, bY, 0.05);
        robustZ.setNames(varNamesA, varNamesB);
        sb.append(robustZ.print(true) + "\n\n");
        sb.append(robustZ.print(false) + "\n\n");

        return sb.toString();
    }

    public String commonItemCorrelations() {
        PearsonCorrelation corA = new PearsonCorrelation();
        PearsonCorrelation corB = new PearsonCorrelation();
        for (int i = 0; i < numberOfCommonItems; i++) {
            corB.increment(bX[i], bY[i]);
            corA.increment(aX[i], aY[i]);
        }

        TextTable table = new TextTable();
        TextTableColumnFormat[] columnFormats = new TextTableColumnFormat[3];
        TextTableColumnFormat cf0 = new TextTableColumnFormat();
        cf0.setStringFormat(15, TextTableColumnFormat.OutputAlignment.LEFT);
        columnFormats[0] = cf0;
        TextTableColumnFormat cf1 = new TextTableColumnFormat();
        cf1.setDoubleFormat(8, 4, TextTableColumnFormat.OutputAlignment.RIGHT);
        columnFormats[1] = cf1;
        TextTableColumnFormat cf2 = new TextTableColumnFormat();
        cf2.setDoubleFormat(8, 4, TextTableColumnFormat.OutputAlignment.RIGHT);
        columnFormats[2] = cf2;
        int numRows = 6;
        numRows++;
        table.addAllColumnFormats(columnFormats, numRows);

        table.getRowAt(0).addHeader(0, 3, "Correlation and SD Ratio", TextTablePosition.CENTER);

        table.getRowAt(1).addHorizontalRule(0, 3, "=");

        table.getRowAt(2).addHeader(0, 1, "Parameter", TextTablePosition.CENTER);
        table.getRowAt(2).addHeader(1, 1, "r", TextTablePosition.CENTER);
        table.getRowAt(2).addHeader(2, 1, "Sy/Sx", TextTablePosition.CENTER);

        table.getRowAt(3).addHorizontalRule(0, 3, "-");

        table.getRowAt(4).addStringAt(0, "Difficulty");
        table.getRowAt(4).addDoubleAt(1, corB.value());
        table.getRowAt(4).addDoubleAt(2, yBSd.getResult() / xBSd.getResult());

        table.getRowAt(5).addStringAt(0, "Discrimination");
        table.getRowAt(5).addDoubleAt(1, corA.value());
        table.getRowAt(5).addDoubleAt(2, yASd.getResult() / xASd.getResult());

        table.getRowAt(6).addHorizontalRule(0, 3, "=");

        return table.toString() + "\n\n";
    }

    public String printItemSummary() {
        StringBuilder sb = new StringBuilder();
        Formatter f = new Formatter(sb);
        f.format("%n");
        f.format("%64s", "                    ITEM SUMMARY STATISTICS                     ");
        f.format("%n");
        f.format("%64s", "================================================================");
        f.format("%n");
        f.format("%-15s", " Form");
        f.format("%-17s", "Parameter");
        f.format("%-17s", " Mean");
        f.format("%-15s", "S.D.");
        f.format("%n");
        f.format("%64s", "----------------------------------------------------------------");
        f.format("%n");
        f.format("%-14s", " X (From)");
        f.format("%-17s", " Discrimination");
        f.format("%10.6f", xAMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", xASd.getResult());
        f.format("%n");
        f.format("%-14s", "  ");
        f.format("%-17s", " Difficulty");
        f.format("%10.6f", xBMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", xBSd.getResult());
        f.format("%n");
        f.format("%-14s", "  ");
        f.format("%-17s", " Guessing");
        f.format("%10.6f", xCMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", xCSd.getResult());
        f.format("%n");
        f.format("%64s", " ");
        f.format("%n");
        f.format("%-14s", " Y (To)");
        f.format("%-17s", " Discrimination");
        f.format("%10.6f", yAMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", yASd.getResult());
        f.format("%n");
        f.format("%-14s", "  ");
        f.format("%-17s", " Difficulty");
        f.format("%10.6f", yBMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", yBSd.getResult());
        f.format("%n");
        f.format("%-14s", "  ");
        f.format("%-17s", " Guessing");
        f.format("%10.6f", yCMean.getResult());
        f.format("%6s", " ");
        f.format("%10.6f", yCSd.getResult());
        f.format("%n");
        f.format("%64s", "================================================================");
        f.format("%n");
        f.format("%n");
        return f.toString();
    }

}