📄 logisticbase.java
字号:
// Evaluate / increment trainFs from the classifier for (int i = 0; i < trainFs.length; i++) { double [] pred = new double [m_numClasses]; double predSum = 0; for (int j = 0; j < m_numClasses; j++) { pred[j] = m_regressions[j][iteration] .classifyInstance(trainNumeric.instance(i)); predSum += pred[j]; } predSum /= m_numClasses; for (int j = 0; j < m_numClasses; j++) { trainFs[i][j] += (pred[j] - predSum) * (m_numClasses - 1) / m_numClasses; } } // Compute the current probability estimates for (int i = 0; i < trainYs.length; i++) { probs[i] = probs(trainFs[i]); } return true; } /** * Helper function to initialize m_regressions. */ protected SimpleLinearRegression[][] initRegressions(){ SimpleLinearRegression[][] classifiers = new SimpleLinearRegression[m_numClasses][m_maxIterations]; for (int j = 0; j < m_numClasses; j++) { for (int i = 0; i < m_maxIterations; i++) { classifiers[j][i] = new SimpleLinearRegression(); classifiers[j][i].setSuppressErrorMessage(true); } } return classifiers; } /** * Converts training data to numeric version. The class variable is replaced by a pseudo-class * used by LogitBoost. */ protected Instances getNumericData(Instances data) throws Exception{ Instances numericData = new Instances(data); int classIndex = numericData.classIndex(); numericData.setClassIndex(-1); numericData.deleteAttributeAt(classIndex); numericData.insertAttributeAt(new Attribute("'pseudo class'"), classIndex); numericData.setClassIndex(classIndex); return numericData; } /** * Helper function for cutting back m_regressions to the set of classifiers (corresponsing to the number of * LogitBoost iterations) that gave the smallest error. */ protected SimpleLinearRegression[][] selectRegressions(SimpleLinearRegression[][] classifiers){ SimpleLinearRegression[][] goodClassifiers = new SimpleLinearRegression[m_numClasses][m_numRegressions]; for (int j = 0; j < m_numClasses; j++) { for (int i = 0; i < m_numRegressions; i++) { goodClassifiers[j][i] = classifiers[j][i]; } } return goodClassifiers; } /** * Computes the LogitBoost response variable from y/p values (actual/estimated class probabilities). */ protected double getZ(double actual, double p) { double z; if (actual == 1) { z = 1.0 / p; if (z > Z_MAX) { // threshold z = Z_MAX; } } else { z = -1.0 / (1.0 - p); if (z < -Z_MAX) { // threshold z = -Z_MAX; } } return z; } /** * Computes the LogitBoost response for an array of y/p values (actual/estimated class probabilities). */ protected double[][] getZs(double[][] probs, double[][] dataYs) { double[][] dataZs = new double[probs.length][m_numClasses]; for (int j = 0; j < m_numClasses; j++) for (int i = 0; i < probs.length; i++) dataZs[i][j] = getZ(dataYs[i][j], probs[i][j]); return dataZs; } /** * Computes the LogitBoost weights from an array of y/p values (actual/estimated class probabilities). */ protected double[][] getWs(double[][] probs, double[][] dataYs) { double[][] dataWs = new double[probs.length][m_numClasses]; for (int j = 0; j < m_numClasses; j++) for (int i = 0; i < probs.length; i++){ double z = getZ(dataYs[i][j], probs[i][j]); dataWs[i][j] = (dataYs[i][j] - probs[i][j]) / z; } return dataWs; } /** * Computes the p-values (probabilities for the classes) from the F-values of the logistic model. */ protected double[] probs(double[] Fs) { double maxF = -Double.MAX_VALUE; for (int i = 0; i < Fs.length; i++) { if (Fs[i] > maxF) { maxF = Fs[i]; } } double sum = 0; double[] probs = new double[Fs.length]; for (int i = 0; i < Fs.length; i++) { probs[i] = Math.exp(Fs[i] - maxF); sum += probs[i]; } Utils.normalize(probs, sum); return probs; } /** * Computes the Y-values (actual class probabilities) for a set of instances. */ protected double[][] getYs(Instances data){ double [][] dataYs = new double [data.numInstances()][m_numClasses]; for (int j = 0; j < m_numClasses; j++) { for (int k = 0; k < data.numInstances(); k++) { dataYs[k][j] = (data.instance(k).classValue() == j) ? 1.0: 0.0; } } return dataYs; } /** * Computes the F-values for a single instance. */ protected double[] getFs(Instance instance) throws Exception{ double [] pred = new double [m_numClasses]; double [] instanceFs = new double [m_numClasses]; //add up the predictions from the simple regression functions for (int i = 0; i < m_numRegressions; i++) { double predSum = 0; for (int j = 0; j < m_numClasses; j++) { pred[j] = m_regressions[j][i].classifyInstance(instance); predSum += pred[j]; } predSum /= m_numClasses; for (int j = 0; j < m_numClasses; j++) { instanceFs[j] += (pred[j] - predSum) * (m_numClasses - 1) / m_numClasses; } } return instanceFs; } /** * Computes the F-values for a set of instances. */ protected double[][] getFs(Instances data) throws Exception{ double[][] dataFs = new double[data.numInstances()][]; for (int k = 0; k < data.numInstances(); k++) { dataFs[k] = getFs(data.instance(k)); } return dataFs; } /** * Computes the p-values (probabilities for the different classes) from the F-values for a set of instances. */ protected double[][] getProbs(double[][] dataFs){ int numInstances = dataFs.length; double[][] probs = new double[numInstances][]; for (int k = 0; k < numInstances; k++) { probs[k] = probs(dataFs[k]); } return probs; } /** * Returns the likelihood of the Y-values (actual class probabilities) given the * p-values (current probability estimates). */ protected double logLikelihood(double[][] dataYs, double[][] probs) { double logLikelihood = 0; for (int i = 0; i < dataYs.length; i++) { for (int j = 0; j < m_numClasses; j++) { if (dataYs[i][j] == 1.0) { logLikelihood -= Math.log(probs[i][j]); } } } return logLikelihood / (double)dataYs.length; } /** * Returns an array of the indices of the attributes used in the logistic model. * The first dimension is the class, the second dimension holds a list of attribute indices. * Attribute indices start at zero. * @return the array of attribute indices */ public int[][] getUsedAttributes(){ int[][] usedAttributes = new int[m_numClasses][]; //first extract coefficients double[][] coefficients = getCoefficients(); for (int j = 0; j < m_numClasses; j++){ //boolean array indicating if attribute used boolean[] attributes = new boolean[m_numericDataHeader.numAttributes()]; for (int i = 0; i < attributes.length; i++) { //attribute used if coefficient > 0 if (!Utils.eq(coefficients[j][i + 1],0)) attributes[i] = true; } int numAttributes = 0; for (int i = 0; i < m_numericDataHeader.numAttributes(); i++) if (attributes[i]) numAttributes++; //"collect" all attributes into array of indices int[] usedAttributesClass = new int[numAttributes]; int count = 0; for (int i = 0; i < m_numericDataHeader.numAttributes(); i++) { if (attributes[i]) { usedAttributesClass[count] = i; count++; } } usedAttributes[j] = usedAttributesClass; } return usedAttributes; } /** * The number of LogitBoost iterations performed (= the number of simple regression functions fit). */ public int getNumRegressions() { return m_numRegressions; } /** * Sets the parameter "maxIterations". */ public void setMaxIterations(int maxIterations) { m_maxIterations = maxIterations; } /** * Sets the option "heuristicStop". */ public void setHeuristicStop(int heuristicStop){ m_heuristicStop = heuristicStop; } /** * Returns the maxIterations parameter. */ public int getMaxIterations(){ return m_maxIterations; } /** * Returns an array holding the coefficients of the logistic model. * First dimension is the class, the second one holds a list of coefficients. * At position zero, the constant term of the model is stored, then, the coefficients for * the attributes in ascending order. * @return the array of coefficients */ protected double[][] getCoefficients(){ double[][] coefficients = new double[m_numClasses][m_numericDataHeader.numAttributes() + 1]; for (int j = 0; j < m_numClasses; j++) { //go through simple regression functions and add their coefficient to the coefficient of //the attribute they are built on. for (int i = 0; i < m_numRegressions; i++) { double slope = m_regressions[j][i].getSlope(); double intercept = m_regressions[j][i].getIntercept(); int attribute = m_regressions[j][i].getAttributeIndex(); coefficients[j][0] += intercept; coefficients[j][attribute + 1] += slope; } } return coefficients; } /** * Returns the fraction of all attributes in the data that are used in the logistic model (in percent). * An attribute is used in the model if it is used in any of the models for the different classes. */ public double percentAttributesUsed(){ boolean[] attributes = new boolean[m_numericDataHeader.numAttributes()]; double[][] coefficients = getCoefficients(); for (int j = 0; j < m_numClasses; j++){ for (int i = 1; i < m_numericDataHeader.numAttributes() + 1; i++) { //attribute used if it is used in any class, note coefficients are shifted by one (because //of constant term). if (!Utils.eq(coefficients[j][i],0)) attributes[i - 1] = true; } } //count number of used attributes (without the class attribute) double count = 0; for (int i = 0; i < attributes.length; i++) if (attributes[i]) count++; return count / (double)(m_numericDataHeader.numAttributes() - 1) * 100.0; } /** * Returns a description of the logistic model (i.e., attributes and coefficients). */ public String toString(){ StringBuffer s = new StringBuffer(); //get used attributes int[][] attributes = getUsedAttributes(); //get coefficients double[][] coefficients = getCoefficients(); for (int j = 0; j < m_numClasses; j++) { s.append("\nClass "+j+" :\n"); //constant term s.append(Utils.doubleToString(coefficients[j][0],4,2)+" + \n"); for (int i = 0; i < attributes[j].length; i++) { //attribute/coefficient pairs s.append("["+m_numericDataHeader.attribute(attributes[j][i]).name()+"]"); s.append(" * " + Utils.doubleToString(coefficients[j][attributes[j][i]+1],4,2)); if (i != attributes[j].length - 1) s.append(" +"); s.append("\n"); } } return new String(s); } /** * Returns class probabilities for an instance. * * @exception Exception if distribution can't be computed successfully */ public double[] distributionForInstance(Instance instance) throws Exception { instance = (Instance)instance.copy(); //set to numeric pseudo-class instance.setDataset(m_numericDataHeader); //calculate probs via Fs return probs(getFs(instance)); } /** * Cleanup in order to save memory. */ public void cleanup() { //save just header info m_train = new Instances(m_train,0); m_numericData = null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -