📄 tld.java
字号:
pThisParam[1] = b; // b pThisParam[2] = w; // w pThisParam[3] = m; // m // Negative examplars: first run a = (maxVarsN[x]>ZERO) ? maxVarsN[x]:1.0; if (varMeanN[x]<=ZERO) varMeanN[x] = ZERO; // modified by LinDong (09/2005) b = a/varMeanN[x]+2.0; // a/(b-2) = E(\sigma^2) w = meanVarN[x]/varMeanN[x]; // E[var(\mu)] = w*E[\sigma^2] if(w<=ZERO) w=1.0; m = nSumVal[x]; nThisParam[0] = a; // a nThisParam[1] = b; // b nThisParam[2] = w; // w nThisParam[3] = m; // m // Bound constraints bounds[0][0] = ZERO; // a > 0 bounds[0][1] = 2.0+ZERO; // b > 2 bounds[0][2] = ZERO; // w > 0 bounds[0][3] = Double.NaN; for(int t=0; t<4; t++){ bounds[1][t] = Double.NaN; m_ParamsP[4*x+t] = pThisParam[t]; m_ParamsN[4*x+t] = nThisParam[t]; } double pminVal=Double.MAX_VALUE, nminVal=Double.MAX_VALUE; Random whichEx = new Random(m_Seed); TLD_Optm pOp=null, nOp=null; boolean isRunValid = true; double[] sumP=new double[pnum], meanP=new double[pnum], varP=new double[pnum]; double[] sumN=new double[nnum], meanN=new double[nnum], varN=new double[nnum]; // One dimension for(int p=0; p<pnum; p++){ sumP[p] = m_SumP[p][x]; meanP[p] = m_MeanP[p][x]; varP[p] = m_VarianceP[p][x]; } for(int q=0; q<nnum; q++){ sumN[q] = m_SumN[q][x]; meanN[q] = m_MeanN[q][x]; varN[q] = m_VarianceN[q][x]; } for(int y=0; y<m_Run;){ if (getDebug()) System.err.println("\n\n!!!!!!!!!!!!!!!!!!!!!!???Run #"+y); double thisMin; if (getDebug()) System.err.println("\nPositive exemplars"); pOp = new TLD_Optm(); pOp.setNum(sumP); pOp.setSSquare(varP); pOp.setXBar(meanP); pThisParam = pOp.findArgmin(pThisParam, bounds); while(pThisParam==null){ pThisParam = pOp.getVarbValues(); if (getDebug()) System.err.println("!!! 200 iterations finished, not enough!"); pThisParam = pOp.findArgmin(pThisParam, bounds); } thisMin = pOp.getMinFunction(); if(!Double.isNaN(thisMin) && (thisMin<pminVal)){ pminVal = thisMin; for(int z=0; z<4; z++) m_ParamsP[4*x+z] = pThisParam[z]; } if(Double.isNaN(thisMin)){ pThisParam = new double[4]; isRunValid =false; } if (getDebug()) System.err.println("\nNegative exemplars"); nOp = new TLD_Optm(); nOp.setNum(sumN); nOp.setSSquare(varN); nOp.setXBar(meanN); nThisParam = nOp.findArgmin(nThisParam, bounds); while(nThisParam==null){ nThisParam = nOp.getVarbValues(); if (getDebug()) System.err.println("!!! 200 iterations finished, not enough!"); nThisParam = nOp.findArgmin(nThisParam, bounds); } thisMin = nOp.getMinFunction(); if(!Double.isNaN(thisMin) && (thisMin<nminVal)){ nminVal = thisMin; for(int z=0; z<4; z++) m_ParamsN[4*x+z] = nThisParam[z]; } if(Double.isNaN(thisMin)){ nThisParam = new double[4]; isRunValid =false; } if(!isRunValid){ y--; isRunValid=true; } if(++y<m_Run){ // Change the initial parameters and restart int pone = whichEx.nextInt(pnum), // Randomly pick one pos. exmpl. none = whichEx.nextInt(nnum); // Positive exemplars: next run while((m_SumP[pone][x]<=1.0)||Double.isNaN(m_MeanP[pone][x])) pone = whichEx.nextInt(pnum); a = m_VarianceP[pone][x]/(m_SumP[pone][x]-1.0); if(a<=ZERO) a=m_ParamsN[4*x]; // Change to negative params m = m_MeanP[pone][x]; double sq = (m-m_ParamsP[4*x+3])*(m-m_ParamsP[4*x+3]); b = a*m_ParamsP[4*x+2]/sq+2.0; // b=a/Var+2, assuming Var=Sq/w' if((b<=ZERO) || Double.isNaN(b) || Double.isInfinite(b)) b=m_ParamsN[4*x+1]; w = sq*(m_ParamsP[4*x+1]-2.0)/m_ParamsP[4*x];//w=Sq/Var, assuming Var=a'/(b'-2) if((w<=ZERO) || Double.isNaN(w) || Double.isInfinite(w)) w=m_ParamsN[4*x+2]; pThisParam[0] = a; // a pThisParam[1] = b; // b pThisParam[2] = w; // w pThisParam[3] = m; // m // Negative exemplars: next run while((m_SumN[none][x]<=1.0)||Double.isNaN(m_MeanN[none][x])) none = whichEx.nextInt(nnum); a = m_VarianceN[none][x]/(m_SumN[none][x]-1.0); if(a<=ZERO) a=m_ParamsP[4*x]; m = m_MeanN[none][x]; sq = (m-m_ParamsN[4*x+3])*(m-m_ParamsN[4*x+3]); b = a*m_ParamsN[4*x+2]/sq+2.0; // b=a/Var+2, assuming Var=Sq/w' if((b<=ZERO) || Double.isNaN(b) || Double.isInfinite(b)) b=m_ParamsP[4*x+1]; w = sq*(m_ParamsN[4*x+1]-2.0)/m_ParamsN[4*x];//w=Sq/Var, assuming Var=a'/(b'-2) if((w<=ZERO) || Double.isNaN(w) || Double.isInfinite(w)) w=m_ParamsP[4*x+2]; nThisParam[0] = a; // a nThisParam[1] = b; // b nThisParam[2] = w; // w nThisParam[3] = m; // m } } } for (int x=0, y=0; x<m_Dimension; x++, y++){ //if((x==exs.classIndex()) || (x==exs.idIndex())) //y++; a=m_ParamsP[4*x]; b=m_ParamsP[4*x+1]; w=m_ParamsP[4*x+2]; m=m_ParamsP[4*x+3]; if (getDebug()) System.err.println("\n\n???Positive: ( "+exs.attribute(1).relation().attribute(y)+ "): a="+a+", b="+b+", w="+w+", m="+m); a=m_ParamsN[4*x]; b=m_ParamsN[4*x+1]; w=m_ParamsN[4*x+2]; m=m_ParamsN[4*x+3]; if (getDebug()) System.err.println("???Negative: ("+exs.attribute(1).relation().attribute(y)+ "): a="+a+", b="+b+", w="+w+", m="+m); } if(m_UseEmpiricalCutOff){ // Find the empirical cut-off double[] pLogOdds=new double[pnum], nLogOdds=new double[nnum]; for(int p=0; p<pnum; p++) pLogOdds[p] = likelihoodRatio(m_SumP[p], m_MeanP[p], m_VarianceP[p]); for(int q=0; q<nnum; q++) nLogOdds[q] = likelihoodRatio(m_SumN[q], m_MeanN[q], m_VarianceN[q]); // Update m_Cutoff findCutOff(pLogOdds, nLogOdds); } else m_Cutoff = -Math.log((double)pnum/(double)nnum); if (getDebug()) System.err.println("???Cut-off="+m_Cutoff); } /** * * @param ex the given test exemplar * @return the classification * @throws Exception if the exemplar could not be classified * successfully */ public double classifyInstance(Instance ex)throws Exception{ //Exemplar ex = new Exemplar(e); Instances exi = ex.relationalValue(1); double[] n = new double[m_Dimension]; double [] xBar = new double[m_Dimension]; double [] sSq = new double[m_Dimension]; for (int i=0; i<exi.numAttributes() ; i++){ xBar[i] = exi.meanOrMode(i); sSq[i] = exi.variance(i); } for (int w=0, t=0; w < m_Dimension; w++, t++){ //if((t==m_ClassIndex) || (t==m_IdIndex)) //t++; for(int u=0;u<exi.numInstances();u++) if(!exi.instance(u).isMissing(t)) n[w] += exi.instance(u).weight(); sSq[w] = sSq[w]*(n[w]-1.0); if(sSq[w] <= 0.0) sSq[w] = 0.0; } double logOdds = likelihoodRatio(n, xBar, sSq); return (logOdds > m_Cutoff) ? 1 : 0 ; } private double likelihoodRatio(double[] n, double[] xBar, double[] sSq){ double LLP = 0.0, LLN = 0.0; for (int x=0; x<m_Dimension; x++){ if(Double.isNaN(xBar[x])) continue; // All missing values int halfN = ((int)n[x])/2; //Log-likelihood for positive double a=m_ParamsP[4*x], b=m_ParamsP[4*x+1], w=m_ParamsP[4*x+2], m=m_ParamsP[4*x+3]; LLP += 0.5*b*Math.log(a) + 0.5*(b+n[x]-1.0)*Math.log(1.0+n[x]*w) - 0.5*(b+n[x])*Math.log((1.0+n[x]*w)*(a+sSq[x])+ n[x]*(xBar[x]-m)*(xBar[x]-m)) - 0.5*n[x]*Math.log(Math.PI); for(int y=1; y<=halfN; y++) LLP += Math.log(b/2.0+n[x]/2.0-(double)y); if(n[x]/2.0 > halfN) // n is odd LLP += TLD_Optm.diffLnGamma(b/2.0); //Log-likelihood for negative a=m_ParamsN[4*x]; b=m_ParamsN[4*x+1]; w=m_ParamsN[4*x+2]; m=m_ParamsN[4*x+3]; LLN += 0.5*b*Math.log(a) + 0.5*(b+n[x]-1.0)*Math.log(1.0+n[x]*w) - 0.5*(b+n[x])*Math.log((1.0+n[x]*w)*(a+sSq[x])+ n[x]*(xBar[x]-m)*(xBar[x]-m)) - 0.5*n[x]*Math.log(Math.PI); for(int y=1; y<=halfN; y++) LLN += Math.log(b/2.0+n[x]/2.0-(double)y); if(n[x]/2.0 > halfN) // n is odd LLN += TLD_Optm.diffLnGamma(b/2.0); } return LLP - LLN; } private void findCutOff(double[] pos, double[] neg){ int[] pOrder = Utils.sort(pos), nOrder = Utils.sort(neg); /* System.err.println("\n\n???Positive: "); for(int t=0; t<pOrder.length; t++) System.err.print(t+":"+Utils.doubleToString(pos[pOrder[t]],0,2)+" "); System.err.println("\n\n???Negative: "); for(int t=0; t<nOrder.length; t++) System.err.print(t+":"+Utils.doubleToString(neg[nOrder[t]],0,2)+" "); */ int pNum = pos.length, nNum = neg.length, count, p=0, n=0; double fstAccu=0.0, sndAccu=(double)pNum, split; double maxAccu = 0, minDistTo0 = Double.MAX_VALUE; // Skip continuous negatives for(;(n<nNum)&&(pos[pOrder[0]]>=neg[nOrder[n]]); n++, fstAccu++); if(n>=nNum){ // totally seperate m_Cutoff = (neg[nOrder[nNum-1]]+pos[pOrder[0]])/2.0; //m_Cutoff = neg[nOrder[nNum-1]]; return; } count=n; while((p<pNum)&&(n<nNum)){ // Compare the next in the two lists if(pos[pOrder[p]]>=neg[nOrder[n]]){ // Neg has less log-odds fstAccu += 1.0; split=neg[nOrder[n]]; n++; } else{ sndAccu -= 1.0; split=pos[pOrder[p]]; p++; } count++; if((fstAccu+sndAccu > maxAccu) || ((fstAccu+sndAccu == maxAccu) && (Math.abs(split)<minDistTo0))){ maxAccu = fstAccu+sndAccu; m_Cutoff = split; minDistTo0 = Math.abs(split); } } } /** * Returns an enumeration describing the available options * * @return an enumeration of all the available options */ public Enumeration listOptions() { Vector result = new Vector(); result.addElement(new Option( "\tSet whether or not use empirical\n" + "\tlog-odds cut-off instead of 0", "C", 0, "-C")); result.addElement(new Option( "\tSet the number of multiple runs \n" + "\tneeded for searching the MLE.", "R", 1, "-R <numOfRuns>")); Enumeration enu = super.listOptions(); while (enu.hasMoreElements()) { result.addElement(enu.nextElement()); } return result.elements(); } /** * Parses a given list of options. <p/> * <!-- options-start --> * Valid options are: <p/> * * <pre> -C * Set whether or not use empirical * log-odds cut-off instead of 0</pre> * * <pre> -R <numOfRuns> * Set the number of multiple runs * needed for searching the MLE.</pre> * * <pre> -S <num> * Random number seed. * (default 1)</pre> * * <pre> -D * If set, classifier is run in debug mode and * may output additional info to the console</pre> * <!-- options-end --> * * @param options the list of options as an array of strings * @throws Exception if an option is not supported */ public void setOptions(String[] options) throws Exception{ setDebug(Utils.getFlag('D', options)); setUsingCutOff(Utils.getFlag('C', options)); String runString = Utils.getOption('R', options); if (runString.length() != 0) setNumRuns(Integer.parseInt(runString)); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -