Search code examples
javascriptnaivebayes

Restrict Classifier output between "0" and "1"


I'm trying classify arrays by object values using a Naive Bayes algorithm, but my result is returning negative values. I want it to return values between 0 and 1 (representing percentage) Here's my classifier

class Bayes{
  constructor(...categories) {
    this.categories     = {};
    this.categoryCounts = {};
    categories.forEach(category => {
      this.categories[category]     = {};
      this.categoryCounts[category] = 0;
    });
  }

  train(category, dataset) {
    this.categoryCounts[category]++;
    Object.keys(dataset).forEach(key => {
      this.categories[category][key] = (this.categories[category][key] || 0) + dataset[key];
    });
  };

  classify(dataset) {
    let scores = {};
    let trainingCount = Object.values(this.categoryCounts).reduce((a, b) => a + b );
    Object.keys(this.categories).forEach(category => {
      scores[category] = 0;
      let categoryWords = this.categories[category];
      let total = Object.values(categoryWords).reduce((a, b) => a + b );
      Object.keys(dataset).forEach(function (key) {
        let value = dataset[key];
        let s     = categoryWords[key] || 0.1;
        let i     = 0;
        while(i<value){
          scores[category] += Math.log(s / parseFloat(total));
          i++;
        }
      });
      let s = this.categoryCounts[category] || 0.1;
      scores[category] += Math.log(s / trainingCount);
    });
    return scores;
  };

};

var b = new Bayes('good', 'bad');
b.train('good', { dry: 1, wet: 0 });
b.train('bad', { dry: 0, wet: 1 });
b.train('good', { dry: 0, wet: 1, green: 1});
b.train('good', { dry: 1, wet: 0, green: 1});
console.log(b.classify({ dry: 0, wet: 1, green: 2}));

Here's the output:

Object {
  bad: -5.991464547107982,
  good: -3.729701448634191
}

I want to return results in percentage like:

Object {
  bad: 0.30,
  good: 0.70
}

Thanks in advance


Solution

  • I removed the log function in scores[category] += Math.log(s / trainingCount);,

    class Bayes{
      constructor(...categories) {
        this.categories     = {};
        this.categoryCounts = {};
        categories.forEach(category => {
          this.categories[category]     = {};
          this.categoryCounts[category] = 0;
        });
      }
    
      train(category, dataset) {
        this.categoryCounts[category]++;
        Object.keys(dataset).forEach(key => {
          this.categories[category][key] = (this.categories[category][key] || 0) + dataset[key];
        });
      };
    
      classify(dataset) {
        let scores = {};
        let trainingCount = Object.values(this.categoryCounts).reduce((a, b) => a + b );
        Object.keys(this.categories).forEach(category => {
          scores[category] = 0;
          let categoryWords = this.categories[category];
          let total = Object.values(categoryWords).reduce((a, b) => a + b );
          Object.keys(dataset).forEach(function (key) {
            let value = dataset[key];
            let s     = categoryWords[key] || 0.1;
            let i     = 0;
            while(i<value){
              scores[category] += Math.log(s / parseFloat(total));
              i++;
            }
          });
          let s = this.categoryCounts[category] || 0.1;
          scores[category] = (s / trainingCount);
        });
        return scores;
      };
    
    };
    
    var b = new Bayes('good', 'bad');
    b.train('good', { dry: 1, wet: 0 });
    b.train('bad', { dry: 0, wet: 1 });
    b.train('good', { dry: 0, wet: 1, green: 1});
    b.train('good', { dry: 1, wet: 0, green: 1});
    console.log(b.classify({ dry: 0, wet: 1, green: 2}));