<commit_before>package edu.cmu.minorthird.classify.algorithms.linear;

import edu.cmu.minorthird.classify.ClassLabel;
import edu.cmu.minorthird.classify.Classifier;
import edu.cmu.minorthird.classify.Example;
import edu.cmu.minorthird.classify.ExampleSchema;
import edu.cmu.minorthird.classify.Explanation;
import edu.cmu.minorthird.classify.Feature;
import edu.cmu.minorthird.classify.Instance;
import edu.cmu.minorthird.classify.MutableInstance;
import edu.cmu.minorthird.classify.OnlineBinaryClassifierLearner;
import edu.cmu.minorthird.classify.algorithms.linear.MaxEntLearner.MyClassifier;
import edu.cmu.minorthird.classify.sequential.BeamSearcher;
import edu.cmu.minorthird.util.gui.SmartVanillaViewer;
import edu.cmu.minorthird.util.gui.TransformedViewer;
import edu.cmu.minorthird.util.gui.Viewer;
import edu.cmu.minorthird.util.gui.Visible;

import java.io.*;

/**
 * Created on Sep 22, 2005
 * 
 * @author <NAME>
 * 
 * Balanced Winnow algorithm as described in "Learning Quickly when Irrelevant
 * Attributes Abound: a new linear-threshold algorithm", <NAME>, Machine
 * Learning, 1988. 
 * 
 * Notation and implementation details based on "Mistake-Driven
 * Learning in Text Categorization", <NAME>, <NAME>, <NAME>, EMNLP, 1997
 *  
 * Additionally, it implements 2 optional features: 
 * 	(a) update when examples don't satisfy a margin requirement (margin parameter)
 *  (b) optionally, classify with a voting scheme. (voted parameter)
 * 
 */


public class BalancedWinnow extends OnlineBinaryClassifierLearner implements Serializable {
	private Hyperplane pos_t, neg_t;//positive and negative hyperplanes 
	private Hyperplane vpos_t, vneg_t;//voted hyperplanes
	private double theta; //threshold parameter (positive value)
	private double alpha;//promotion parameter (positive value, bigger than 1)
	private double beta; //demotion parameter (positive value, between 0 and 1)
	private int excount;//number of examples presented to the learner so far
	private int numActiveFeatures;//number of active features in first example
	private double margin = 0.0;
	private boolean voted;

	public BalancedWinnow() {
		//this(4, 2, 0.5, true);
		this(10, 2, 0.5, true);//recommended
		//this(10,1.1,0.9, true);
	}

	/**
	 * If ignoreWeights is true, treat all weights as binary. For backward
	 * compatibility with an older buggy version. - need to confirm with Wcohen
	 */
	public BalancedWinnow(double t, double a, double b, boolean voted) {
		if((t<0)||(a < 1)||(b<0)||(b>1)){
			System.out.println("Error in BalancedWinnow initial parameters");
			System.out.println("Error: (theta<0)||(alpha < 1)||(beta<0)||(beta>1)");
			System.exit(0);
		}
		this.theta = t;
		this.alpha = a;
		this.beta = b;
		this.voted = voted;//improves performance and convergence
		reset();		
	}

	public void reset() {
		pos_t = new Hyperplane();
		neg_t = new Hyperplane();
		if(voted){
			vpos_t = new Hyperplane();
			vneg_t = new Hyperplane();
		}		
	}

	public void addExample(Example example) {
		
		excount++;
		
		//first, initialize the weight of the hyperplane 
		if(excount==1){
			numActiveFeatures = Math.max(example.featureIterator().estimatedSize(),2);
			System.out.println("Balanced Winnow paramenters: Theta/Alpha/Beta = ("+theta+"/"+alpha+"/"+beta+") , numActiveFeatures ="+numActiveFeatures);
		}		
		for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
		    Feature f = j.nextFeature();
		    //we assume sparse feature representation
		    if(!pos_t.hasFeature(f)){//both hyperplanes have exactly the same features
		    	pos_t.increment(f,2*theta/(double)numActiveFeatures);//starting according to EMNLP97's implementation
		    	neg_t.increment(f,1*theta/(double)numActiveFeatures);//starting according to EMNLP97's implementation
		    }
		}
				
		//get label and prediction
		double y_t = example.getLabel().numericLabel();
		double y_t_hat = localscore(example.asInstance());
		//update rule
		if(y_t * y_t_hat<margin){//error occurred
			if(example.getLabel().isPositive()){
				for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
				    Feature f = j.nextFeature();
				    pos_t.multiply(f,alpha);
				    neg_t.multiply(f,beta);
				}
			}
			else{
				for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
				    Feature f = j.nextFeature();
				    pos_t.multiply(f,beta);
				    neg_t.multiply(f,alpha);
				}				<commit_msg>*** empty log message ***<commit_after>package edu.cmu.minorthird.classify.algorithms.linear;

import edu.cmu.minorthird.classify.ClassLabel;
import edu.cmu.minorthird.classify.Classifier;
import edu.cmu.minorthird.classify.Example;
import edu.cmu.minorthird.classify.ExampleSchema;
import edu.cmu.minorthird.classify.Explanation;
import edu.cmu.minorthird.classify.Feature;
import edu.cmu.minorthird.classify.Instance;
import edu.cmu.minorthird.classify.MutableInstance;
import edu.cmu.minorthird.classify.OnlineBinaryClassifierLearner;
import edu.cmu.minorthird.classify.algorithms.linear.MaxEntLearner.MyClassifier;
import edu.cmu.minorthird.classify.sequential.BeamSearcher;
import edu.cmu.minorthird.util.gui.SmartVanillaViewer;
import edu.cmu.minorthird.util.gui.TransformedViewer;
import edu.cmu.minorthird.util.gui.Viewer;
import edu.cmu.minorthird.util.gui.Visible;

import java.io.*;

/**
 * Created on Sep 22, 2005
 * 
 * @author <NAME>
 * 
 * Balanced Winnow algorithm as described in "Learning Quickly when Irrelevant
 * Attributes Abound: a new linear-threshold algorithm", <NAME>, Machine
 * Learning, 1988. 
 * 
 * Notation and implementation details based on "Mistake-Driven
 * Learning in Text Categorization", <NAME>, <NAME>, <NAME>, EMNLP, 1997
 *  
 * Additionally, it implements 2 optional features: 
 * 	(a) update when examples don't satisfy a margin requirement (margin parameter)
 *  (b) optionally, classify with a voting scheme. (voted parameter)
 * 
 */


public class BalancedWinnow extends OnlineBinaryClassifierLearner implements Serializable {
	private Hyperplane pos_t, neg_t;//positive and negative hyperplanes 
	private Hyperplane vpos_t, vneg_t;//voted hyperplanes
	private double theta; //threshold parameter (positive value)
	private double alpha;//promotion parameter (positive value, bigger than 1)
	private double beta; //demotion parameter (positive value, between 0 and 1)
	private int excount;//number of examples presented to the learner so far
	private int numActiveFeatures;//number of active features in first example
	private double margin = 0.0;
	private boolean voted;

	public BalancedWinnow() {
		//this(4, 2, 0.5, true);
		this(10, 2, 0.5, true);//recommended
		//this(10,1.1,0.9, true);
	}

	/**
	 * If ignoreWeights is true, treat all weights as binary. For backward
	 * compatibility with an older buggy version. - need to confirm with Wcohen
	 */
	public BalancedWinnow(double t, double a, double b, boolean voted) {
		if((t<0)||(a < 1)||(b<0)||(b>1)){
			System.out.println("Error in BalancedWinnow initial parameters");
			System.out.println("Error: (theta<0)||(alpha < 1)||(beta<0)||(beta>1)");
			System.exit(0);
		}
		this.theta = t;
		this.alpha = a;
		this.beta = b;
		this.voted = voted;//improves performance and convergence
		reset();		
	}

	public void reset() {
		pos_t = new Hyperplane();
		neg_t = new Hyperplane();
		if(voted){
			vpos_t = new Hyperplane();
			vneg_t = new Hyperplane();
		}		
	}

	public void addExample(Example example) {
		
		excount++;
		
		//first, initialize the weight of the hyperplane 
		if(excount==1){
			numActiveFeatures = Math.max(example.featureIterator().estimatedSize(),2);
			System.out.println("BalancedWinnow parameters: Theta/Alpha/Beta = ("+theta+"/"+alpha+"/"+beta+")");
		}		
		for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
		    Feature f = j.nextFeature();
		    //we assume sparse feature representation
		    if(!pos_t.hasFeature(f)){//both hyperplanes have exactly the same features
		    	pos_t.increment(f,2*theta/(double)numActiveFeatures);//starting according to EMNLP97's implementation
		    	neg_t.increment(f,1*theta/(double)numActiveFeatures);//starting according to EMNLP97's implementation
		    }
		}
				
		//get label and prediction
		double y_t = example.getLabel().numericLabel();
		double y_t_hat = localscore(example.asInstance());
		//update rule
		if(y_t * y_t_hat<margin){//error occurred
			if(example.getLabel().isPositive()){
				for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
				    Feature f = j.nextFeature();
				    pos_t.multiply(f,alpha);
				    neg_t.multiply(f,beta);
				}
			}
			else{
				for (Feature.Looper j=example.featureIterator(); j.hasNext(); ) {
				    Feature f = j.nextFeature();
				    pos_t.multiply(f,beta);
				    neg_t.multiply(f,alpha);
				}				
{'fraction_non_alphanumeric': 0.12597076290543627, 'fraction_numerical': 0.01187756966651439, 'mean_word_length': 4.190871369294606, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3836137', 'n_tokens_mistral': 3216, 'n_tokens_neox': 2834, 'n_words': 689}