All Downloads are FREE. Search and download functionalities are using the official Maven repository.

meka.classifiers.multilabel.neurofuzzy.ARAMNetworkSparseHT Maven / Gradle / Ivy

Go to download

The MEKA project provides an open source implementation of methods for multi-label classification and evaluation. It is based on the WEKA Machine Learning Toolkit. Several benchmark methods are also included, as well as the pruned sets and classifier chains methods, other methods from the scientific literature, and a wrapper to the MULAN framework.

The newest version!
/*
 *
 *  
 *  Adapted from NaiveBayes.java
 *  
 *  Copyright (C) 2016 Fernando Benites
 *  @author Fernando Benites
 */
package meka.classifiers.multilabel.neurofuzzy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import meka.classifiers.multilabel.Evaluation;
import meka.classifiers.multilabel.MultiLabelClassifier;
import meka.classifiers.multilabel.ProblemTransformationMethod;
import weka.core.Attribute;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.Option;
import weka.core.Utils;

/**
 * ****REPLACE THE FOLLOWING WITH SIMILAR INFORMATION.
 * Class for a Naive Bayes classifier using estimator classes. Numeric 
 * estimator precision values are chosen based on analysis of the 
 * training data. For this reason, the classifier is not an 
 * UpdateableClassifier (which in typical usage are initialized with zero 
 * training instances) -- if you need the UpdateableClassifier functionality,
 * use the NaiveBayesUpdateable classifier. The NaiveBayesUpdateable
 * classifier will  use a default precision of 0.1 for numeric attributes
 * when buildClassifier is called with zero training instances.
 * 

* For more information on Naive Bayes classifiers, see

* * George H. John and Pat Langley (1995). Estimating * Continuous Distributions in Bayesian Classifiers. Proceedings * of the Eleventh Conference on Uncertainty in Artificial * Intelligence. pp. 338-345. Morgan Kaufmann, San Mateo.

* * Valid options are:

* * -K
* Use kernel estimation for modelling numeric attributes rather than * a single normal distribution.

* * -D
* Use supervised discretization to process numeric attributes.

* * @author Len Trigg ([email protected]) * @author Eibe Frank ([email protected]) * @author Rushi Bhatt ([email protected]) * @version $Revision: 1.16 $ * Modified by Rushi for use as a CN710 template */ public class ARAMNetworkSparseHT extends ARAMNetworkClass { //**** THIS IS WHERE CLASSIFIER WEIGHTS ETC GO **** //define stuff like weight matrices, classifier parameters etc. //e.g., protected double rho_a_bar=0.0; HashMap[] weightsA = null; HashSet[] upweightsA=null; double[] sweightsA = null; double sweightsA0; HashMap[] weightsB = null; HashMap hmclasses = null; int snumFeatures=0; int snumClasses=0; int numinstances=0; int activated=0; public ARAMNetworkSparseHT(int fnumFeatures, int fnumClasses, double fro, double fthreshold) { initARAM(fnumFeatures, fnumClasses, fro, fthreshold); } public ARAMNetworkSparseHT(){ } private void initARAM(int fnumFeatures, int fnumClasses, double fro, double fthreshold){ numFeatures = fnumFeatures; snumFeatures = (int)(0.5*numFeatures); numClasses = fnumClasses; snumClasses= (int)(0.5*numClasses); threshold = fthreshold; weightsA = new HashMap[1]; weightsA[0] = new HashMap(); upweightsA = new HashSet[1]; upweightsA[0] = new HashSet(); sweightsA = new double[1]; sweightsA[0]=0; for(int i=0;i(); } /** * Returns a string describing this classifier * @return a description of the classifier suitable for * displaying in the explorer/experimenter gui. * ****MODIFY WITH CORRECT INFORMATION**** */ public String globalInfo() { return "This is ARAM."; } /** * Generates the classifier. * * @param D set of instances serving as training data * @exception Exception if the classifier has not been generated * successfully */ public void buildClassifier(Instances D) throws Exception { int L = D.classIndex(); int featlength = (D.numAttributes() -L)*2; int numSamples = D.numInstances(); int classlength = L * 2; if (this.order==null){ order = new ArrayList(); for (int j=0; j data = new HashMap(); HashMap labels = new HashMap(); int numChanges = 0; int numCategories_1=numCategories -1; numinstances+=1; if (!instance.classIsMissing()) { //Do the weight updates using the instance. for (Integer tj=0; tj= roa) { if (currentCategory == numCategories_1) { if (currentSortedIndex == maxNumCategories) { System.out .println("WARNING: The maximum number of categories has been reached."); resonance = true; } else { // Add a new category sweightsA[currentCategory]=0; Set s1=data.keySet(); for (Integer j :s1) { Double da=data.get(j); weightsA[currentCategory].put(j,da); weightsA[currentCategory].put(j+snumFeatures, da); upweightsA[currentCategory].add(j+snumFeatures); } Set s2=weightsA[currentCategory].keySet(); int count=0; for (int j :s2) { double da=(Double)weightsA[currentCategory].get(j); if (j v = new Vector(); v.add(currentCategory); hmclasses.put(s,v); } ARAMm_Add_New_Category(); //System.out.println(numinstances+" "+numCategories); // fprintf(FileID,'Add a new category of %d\n', // network.numCategories); // Increment the number of changes since we added a // new category. numChanges = numChanges + 1; resonance = true; break; } } else { // % Update weights double weightChange = ARAMm_Update_Weights(data, labels, currentCategory); //System.out.println(numinstances+" "+currentCategory+" S:"+sweightsA[currentCategory]); //sumArrayF(this.weightsA[1]); if (weightChange == 1) { numChanges += 1; } resonance = true; break; } } else { currentSortedIndex += 1; resonance = false; } } if(!resonance && currentSortedIndex>=cateacti.length) { // Add a new category sweightsA[numCategories_1]=0; Set s1=data.keySet(); int count=0; for (int j: s1) { double da=data.get(j); weightsA[numCategories_1].put(j, da); sweightsA[numCategories_1]+=da; weightsA[numCategories_1].put(j+snumFeatures, da); sweightsA[numCategories_1]+=1-da; upweightsA[numCategories_1].add(j+snumFeatures); count+=1; } sweightsA[numCategories_1]+=snumFeatures-count; s1=labels.keySet(); for (int j : s1) { weightsB[numCategories_1].put(j, labels.get(j)); } String s = labels.keySet().toString(); if (hmclasses.containsKey(s)){ hmclasses.get(s).add(numCategories_1); hmclasses.put(s,hmclasses.get(s)); }else{ Vector v = new Vector(); v.add(numCategories_1); hmclasses.put(s,v); } ARAMm_Add_New_Category(); //System.out.println(numinstances+" "+numCategories); // fprintf(FileID,'Add a new category of %d\n', // network.numCategories); // Increment the number of changes since we added a // new category. numChanges = numChanges + 1; } } } //****THIS IS THE CLASSIFICATION ROUTINE. MODIFY TO CHANGE THE ALGORITHM**** //****classifyInstance() uses this method, so implement the //****nuts-and-bolts of your algorithm here. /** * Calculates the class membership probabilities for the given test * instance. * * @param instance the instance to be classified * @return predicted class probability distribution * @exception Exception if there is a problem generating the prediction */ public double[] distributionForInstance(Instance instance) throws Exception { int num_classes=(int) (snumClasses); double[] ranking = new double[num_classes]; // long startMilli = System.currentTimeMillis(); // for (int j = 0; j < num_features; j++) { // // double dt=instance.value(num_classes+j); // if (dt!=0){ // currentData.put(j, dt); // } // } //TODO use instance here SortPair[] sortedActivations = ARTActivateCategories(instance); java.util.Arrays.sort(sortedActivations); double s0=sortedActivations[0].getValue(); double diff_act = s0 - sortedActivations[numCategories - 2].getValue(); int largest_activ = 1; double activ_change = 0; for (int i = 1; i < sortedActivations.length; i++) { activ_change = (s0 - sortedActivations[i] .getValue()) / s0; if (activ_change > threshold * diff_act) { break; } largest_activ = largest_activ + 1; } // % largest_activ =5; double[] best_matches = new double[largest_activ]; java.util.Arrays.fill(best_matches, 1); best_matches[0]=s0; for (int i = 1; i < largest_activ; i++) { // % best_matches(i) = matches(sortedCategories(i)); best_matches[i] = sortedActivations[i].getValue(); } // % min_mat = min(best_matches); // % max_mat = max(best_matches); double sum_mat = sumArray(best_matches); int currentCategory = 0; this.neuronsactivated=new int[largest_activ]; this.neuronsactivity=new double[largest_activ]; for (int i = 0; i < largest_activ; i++) { this.neuronsactivity[i]=best_matches[i]; best_matches[i] = best_matches[i] / sum_mat; currentCategory = sortedActivations[i].getOriginalIndex(); this.neuronsactivated[i]=currentCategory; // % Fill return vector with weightB values Set s1= weightsB[currentCategory].keySet(); for (int j :s1) { ranking[j] = ranking[j] + best_matches[i] * (Double)weightsB[currentCategory].get(j); } } this.nrinstclassified+=1; if(m_userankstoclass) { return ARAMm_Ranking2Class(ranking); } // long endMilli = System.currentTimeMillis(); return ranking; } public double[] ARAMm_Ranking2Class(double[] rankings) { int columns=rankings.length; double[] classes= new double[columns ]; SortPair[] sortedRanks = new SortPair[columns]; for (int j=0;j s1=new HashSet(); //Set s1=Data.keySet(); // long startMilli = System.currentTimeMillis(); for (int i = 0; i < numCategories-1; i++) { // long startMilliss = System.nanoTime(); double sumvector = 0; // double sumweight = 0; int count=0; List s2=new ArrayList(upweightsA[i]); //List s2=new ArrayList(weightsA[i].keySet()); //for (Integer j: s1) { //double da=(Double)Data.get(j); long st3 =0; long st4 =0; for (int tj=0; tj Data, HashMap labels) { String s = labels.keySet().toString(); Vector lclasses = (Vector)hmclasses.get(s); SortPair2[] catacti = null; if (lclasses==null||lclasses.size()==0){ catacti=new SortPair2[1]; catacti[0] = new SortPair2(1,numCategories-1,1); return catacti; } catacti = new SortPair2[lclasses.size()]; // double[] catacti=new double[numCategories]; for (int i = 0; i < lclasses.size(); i++) { double sumvector = 0; // double sumweight = 0; int k = ((Integer)lclasses.get(i)).intValue(); List s2=new ArrayList(upweightsA[k]); int counter=0; //double dt = instance.value(num_classes+j); for (Map.Entry entry : Data.entrySet()) { int j=entry.getKey(); double da=(Double)entry.getValue(); // for (Integer tj=0; tj max) { maxIndex = i; max = dist[i]; } } if (max > 0) { return maxIndex; } else { //return Instance.missingValue(); } case Attribute.NUMERIC: return dist[0]; default: return -1; } } // ****ANY OPTIONS/PARAMETERS GO HERE**** /** * Returns an enumeration describing the available options. * * @return an enumeration of all the available options. */ public Enumeration

* * -K
* Use kernel estimation for modelling numeric attributes rather than * a single normal distribution.

* * -D
* Use supervised discretization to process numeric attributes. * * @param options the list of options as an array of strings * @exception Exception if an option is not supported */ public void setOptions(String[] options) throws Exception { //These are just examples, modify to suit your algorithm // boolean k = Utils.getFlag('K', options); // boolean d = Utils.getFlag('D', options); // if (k && d) { // throw new IllegalArgumentException( // "Can't use both kernel density estimation and discretization!"); // } // setUseSupervisedDiscretization(d); // setUseKernelEstimator(k); roa = (Utils.getOptionPos("P",options) >= 0) ? Double.parseDouble(Utils.getOption("P", options)) : roa; m_userankstoclass= (Utils.getOptionPos("K",options) >= 0); super.setOptions(options); } //****MORE OPTION PARSING STUFF**** /** * Gets the current settings of the classifier. * * @return an array of strings suitable for passing to setOptions */ public String [] getOptions() { //These are just examples, modify to suit your algorithm String [] options = new String [3]; try{ options =weka.core.Utils.splitOptions("-P 0.9 -K"); }catch (Exception ex) { System.out.println(ex.getMessage()); } return options; } //****ANY INFORMATION LIKE NO. OF UNITS ETC PRINTED HERE /** * Returns a description of the classifier. * * @return a description of the classifier as a string. */ public String toString() { //These are just examples, modify to suit your algorithm StringBuffer text = new StringBuffer(); text.append("ML ARAM classifier"); // if (m_Instances == null) { // text.append(": No model built yet."); // } else { // try { // for (int i = 0; i < m_Distributions[0].length; i++) { // text.append("\n\nClass " + m_Instances.classAttribute().value(i) + // ": Prior probability = " + Utils. // doubleToString(m_ClassDistribution.getProbability(i), // 4, 2) + "\n\n"); // Enumeration enumAtts = m_Instances.enumerateAttributes(); // int attIndex = 0; // while (enumAtts.hasMoreElements()) { // Attribute attribute = (Attribute) enumAtts.nextElement(); // text.append(attribute.name() + ": " // + m_Distributions[attIndex][i]); // attIndex++; // } // } // } catch (Exception ex) { // text.append(ex.getMessage()); // } // } return text.toString(); } /** * Main method for testing this class. * * @param argv the options */ private double ARAMm_Update_Weights(HashMap data, HashMap labels, int category) { double weightChange = 0; sweightsA[category]=0; Set s1=new TreeSet(data.keySet()); Set s2=new HashSet(weightsA[category].keySet()); int count=0; for (Integer i: s1) { if (i>=snumFeatures){ continue; } double da=data.get(i); Double wa=(Double)weightsA[category].get(i); if(wa!=null){ if (da < wa ){ wa = (learningRate * da) + (1 - learningRate) * wa; if(wa==0){ weightsA[category].remove(i); }else{ weightsA[category].put(i, wa); } } sweightsA[category]+=wa; s2.remove(i); } double dat=1-da; //} // for (Integer i: s1) { int j1= i+snumFeatures; // double dat=1-data.get(j1-snumFeatures); Double wat=(Double)weightsA[category].get(j1); // Double wat=(Double)weightsA[category].get(j1); if(wat!=null){ wat=1-wat; if (dat < wat ){ wat = ((learningRate * dat) + (1 - learningRate) * wat); if (wat==1){ weightsA[category].remove(j1); upweightsA[category].remove(j1); }else{ weightsA[category].put(j1, 1-wat); upweightsA[category].add(j1); count+=1; } }else{ if (wat!=1){ count+=1; } } sweightsA[category]+=wat; s2.remove(j1); }else{ wat=(learningRate * dat); if (wat==1){ weightsA[category].remove(j1); upweightsA[category].remove(j1); }else{ weightsA[category].put((Integer)j1,(Double) (1-wat)); upweightsA[category].add(j1); count+=1; } sweightsA[category]+=wat; } } for (Integer i: s2) { if (i(); weightsB[numCategories] = new HashMap(); upweightsA[numCategories] = new HashSet(); sweightsA[numCategories]=sweightsA0; numCategories += 1; } private double sumArray(double[] arr) { int num = arr.length; double result = 0; for (int i = 0; i < num; i++) { result += arr[i]; } return result; } public static void main(String [] argv) { try { Evaluation.runExperiment(((MultiLabelClassifier) new WvARAM()), argv); } catch (Exception e) { e.printStackTrace(); System.err.println(e.getMessage()); } } public double[][] distributionForInstanceM(Instances i) throws Exception { // TODO Auto-generated method stub return null; } class SortPair2 implements Comparable { private int originalIndex; private double value; private double rawvalue; public SortPair2(double value, int originalIndex, double rawvalue) { this.value = value; this.originalIndex = originalIndex; this.rawvalue = rawvalue; } public int compareTo(SortPair2 o) { return Double.compare(o.getValue(), value); } public int getOriginalIndex() { return originalIndex; } public double getValue() { return value; } public double getRawValue() { return rawvalue; } } @Override public boolean isThreaded() { // TODO Auto-generated method stub return false; } @Override public void setThreaded(boolean setv) { // TODO Auto-generated method stub } @Override public String getModel() { // TODO Auto-generated method stub return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy