List of usage examples for org.apache.commons.math3.stat.descriptive.moment StandardDeviation clear
@Override public void clear()
From source file:com.itemanalysis.psychometrics.irt.estimation.StartingValues.java
/** * Computes normal approximation estimates (PROX) of item difficulty and person ability * in a way that allows for missing data (Linacre, 1994). It is an iterative procedure. * * Linacre, J. M., (1994). PROX with missing data, or known item or person measures. * Rasch Measurement Transactions, 8:3, 378, http://www.rasch.org/rmt/rmt83g.htm. * * @param converge convergence criterion as the maximum change in person logits. * @param maxIter maximum number of iterations. About 10 iterations works well. *//*from w ww. j a v a 2 s. com*/ private void prox(double converge, int maxIter) { double delta = 1.0 + converge; int iter = 0; double pProx = 0; double pScore = 0; double maxTestScore = 0; double maxChange = 0; double logit = 0; Mean personGrandMean = new Mean(); StandardDeviation personGrandSd = new StandardDeviation(); double iProx = 0.0; double iMean = 0; theta = new double[nResponseVectors]; Mean[] mPerson = new Mean[nItems];//Item difficulty mean for those examinees completing item j StandardDeviation[] sdPerson = new StandardDeviation[nItems];//Item difficulty standard deviation for those examinees completing item j double[] Si = null; double[] Ni = null; Mean[] mItem = new Mean[nResponseVectors]; StandardDeviation[] sdItem = new StandardDeviation[nResponseVectors]; while (delta > converge && iter < maxIter) { Si = new double[nItems]; Ni = new double[nItems]; //Compute descriptive statistics for persons and items double resp = 0; double freq = 0; for (int l = 0; l < nResponseVectors; l++) { freq = responseVector[l].getFrequency(); for (int j = 0; j < nItems; j++) { //initialize arrays if (l == 0) { mPerson[j] = new Mean(); sdPerson[j] = new StandardDeviation(); } if (j == 0) { mItem[l] = new Mean(); sdItem[l] = new StandardDeviation(); } if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) { resp = responseVector[l].getResponseAt(j); //increment item and person summary statistics if (resp != -1) { //incorporate weights - crude workaround for (int w = 0; w < freq; w++) { mItem[l].increment(irm[j].getDifficulty()); sdItem[l].increment(irm[j].getDifficulty()); mPerson[j].increment(theta[l]); sdPerson[j].increment(theta[l]); Si[j] += resp; Ni[j]++; } } } } //end item loop } //end summary loop //Compute item PROX for binary items only iMean = 0; double pSd = 1e-8; double ni = 0; for (int j = 0; j < nItems; j++) { if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) { pSd = sdPerson[j].getResult(); //adjust extreme item scores if (Si[j] == 0) Si[j] += 0.3; if (Si[j] == Ni[j]) Si[j] -= 0.3; logit = Math.log(Si[j] / (Ni[j] - Si[j])); iProx = mPerson[j].getResult() - Math.sqrt(1.0 + pSd / 2.9) * logit; irm[j].setDifficulty(iProx); iMean += iProx; ni++; } } iMean /= ni; //center difficulties about the mean item difficulty for (int j = 0; j < nItems; j++) { if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) { iProx = irm[j].getDifficulty(); irm[j].setDifficulty(iProx - iMean); } } //Compute person PROX maxChange = 0; personGrandMean.clear(); personGrandSd.clear(); Pair<Double, Double> personScores = null; for (int l = 0; l < nResponseVectors; l++) { personScores = computePersonScores(responseVector[l]); pScore = personScores.getFirst(); maxTestScore = personScores.getSecond(); //adjust extreme person scores if (pScore == 0) pScore += 0.3; if (pScore == maxTestScore) pScore -= 0.3; logit = Math.log(pScore / (maxTestScore - pScore)); pProx = mItem[l].getResult() + Math.sqrt(1.0 + sdItem[l].getResult() / 2.9) * logit; maxChange = Math.max(maxChange, Math.abs(theta[l] - pProx)); theta[l] = pProx; personGrandMean.increment(pProx); personGrandSd.increment(pProx); } delta = maxChange; iter++; fireEMStatusEvent(iter, delta, Double.NaN); } //end while //Linearly transform theta estimate to have a mean of 0 and a standard deviation of 1. //Apply the same transformation to item difficulty values. double A = 1.0 / personGrandSd.getResult(); double B = -A * personGrandMean.getResult(); for (int l = 0; l < nResponseVectors; l++) { theta[l] = theta[l] * A + B; } double a = 1; double b = 0; for (int j = 0; j < nItems; j++) { if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L3) { b = irm[j].getDifficulty(); irm[j].setDifficulty(b * A + B); //Adjust discrimination parameter for scaling constant. //PROX assumes a logit scale. This conversion is to convert to the normal metric. a = irm[j].getDiscrimination(); irm[j].setDiscrimination(a / irm[j].getScalingConstant()); } } //For debugging // System.out.println("ITER: " + iter); // for(int j=0;j<nItems;j++){ // System.out.println("PROX: " + irm[j].toString()); // } }