Пример #1
0
        public TestItemScoreInfo(int itemBank, long itemName, string dimension, IRTModelFactory.Model irtType, string recodeRule, int parameterCount, double weight, int scorePoint)
        {
            this.bank = itemBank;
            this.itemName = itemName;
            this.dimension = dimension;
            this.measurementModel = irtType;
            if (irtType != IRTModelFactory.Model.Unknown)
            {
    			this.irtModel = IRTModelFactory.CreateModel(irtType);
	    		this.irtModel.SetParameterCount(parameterCount, scorePoint);
            }
            this.recodeRuleName = recodeRule;
            this.weight = weight;
			this.scorePoints = scorePoint;
            if (recodeRule.StartsWith("GRR("))
            {
                string[] recodes = recodeRuleName.Substring(4, recodeRuleName.Length - 5).Split('-');
                foreach (string recode in recodes)
                {
                    if (recode.Length != 1)
                        throw new ScoringEngineException("Recodes must be one digit integers: Item " + bank + "-" + itemName + ", recodeRule " + recodeRuleName);
                    if (!Char.IsDigit(recode[0]))
                        throw new ScoringEngineException("Recodes must be integers: Item " + bank + "-" + itemName + ", recodeRule " + recodeRuleName);
                    if (Convert.ToInt32(recode) > scorePoint)
                        throw new ScoringEngineException("Recodes must be less than or equal to dimension score points: Item " + bank + "-" + itemName + ", recodeRule " + recodeRuleName);
                }
            }
        }
Пример #2
0
        private static double GetSE(List <ItemScore> testScores, double theta, int seType)
        {
            double d2        = 0.0;
            double d1Squared = 0.0;

            foreach (ItemScore ir in testScores)
            {
                TestItemScoreInfo si    = ir.ScoreInfo;
                IRTModel          irt   = si.IRTModel;
                double            score = ir.Score;

                double deriv1 = irt.D1LnlWrtTheta(score, theta);
                d1Squared += deriv1 * deriv1;
                d2        += irt.D2LnlWrtTheta(score, theta);
            }

            if (seType == 1)
            {
                double k = testScores.Count;
                d1Squared *= k / (k - 1.0);
                return(Math.Sqrt(d1Squared / (d2 * d2)));
            }
            else
            {
                return(Math.Sqrt(1.0 / (-d2)));
            }
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="testResponses"></param>
        /// <param name="startValue"></param>
        /// <param name="seType">seType of 0 asks for the inverse of the information
        //      seType of 1 asks for the sandwich estimator</param>
        /// <param name="maxIter"></param>
        /// <param name="converge"></param>
        /// <param name="endAdjust"></param>
        /// <returns></returns>
        private static IRTScore MLEScore(List <ItemScore> testScores, double startValue, int seType, int maxIter, double converge)
        {
            double lnl = -9999999999.9, lnlChng = 99999.9, lnlNext = 0.0, se;
            int    iter = 0;

            double   step = 0.0, negD2 = 0.0;
            TestItem ti = null;
            IRTModel irt = null;
            double   theta = startValue, x, d1Squared = 0.0, deriv1, d1 = 0.0, d2 = 0.0;

            step = 0.0;

            while ((lnlChng > converge) && (iter < maxIter))
            {
                d1        = 0.0;
                d2        = 0.0;
                lnlNext   = 0.0;
                d1Squared = 0.0;
                x         = 0.0;

                foreach (ItemScore ir in testScores)
                {
                    TestItemScoreInfo si = ir.ScoreInfo;
                    irt = si.IRTModel;
                    double score = ir.Score;

                    x = irt.ComputeProbability(score, theta);

                    if (x <= 0.0)
                    {
                        x = -1.0E10; //double.MinValue;
                    }
                    else
                    {
                        x = Math.Log(x);
                    }

                    lnlNext   += x;
                    deriv1     = irt.D1LnlWrtTheta(score, theta);
                    d1Squared += deriv1 * deriv1;
                    d1        += deriv1;
                    d2        += irt.D2LnlWrtTheta(score, theta);
                }

                negD2 = d2 * -1.0;

                if (lnlNext >= lnl)
                {
                    step    = SteepestStep(d1, d2, d1Squared, 1.0);
                    theta  += step;
                    lnlChng = lnlNext - lnl;
                    lnl     = lnlNext;
                }
                else
                {
                    step    = step * .5;
                    theta  -= step;
                    lnlChng = lnl - lnlNext;
                    if (Double.IsNaN(lnlChng))
                    {
                        lnlChng = 100.0;
                    }
                }
                ++iter;
            } //end while

            if (iter == maxIter)
            {
                return(new IRTScore(double.MaxValue, double.MaxValue, IRTScoreType.FailedConvergence));
            }

            // NOTE: this computes se not at theta, but at the previous theta!
            if (seType == 1)
            {
                double k = testScores.Count;
                d1Squared *= k / (k - 1.0);
                se         = Math.Sqrt(d1Squared / (d2 * d2));
            }
            else
            {
                se = Math.Sqrt(1.0 / (-d2));
            }

            //check for bad values
            if (double.IsNaN(theta))
            {
                return(new IRTScore(theta, se, IRTScoreType.Diverged));
            }

            return(new IRTScore(theta, se, IRTScoreType.Converged));
        }