⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contingency.cpp

📁 orange源码 数据挖掘技术
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
    This file is part of Orange.

    Orange is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Orange is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Orange; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Authors: Janez Demsar, Blaz Zupan, 1996--2002
    Contact: janez.demsar@fri.uni-lj.si
*/


#include "stladdon.hpp"

#include "vars.hpp"
#include "domain.hpp"
#include "examples.hpp"
#include "examplegen.hpp"
#include "classify.hpp"
#include "estimateprob.hpp"

#include "learn.hpp"

#include "contingency.ppp"

DEFINE_TOrangeVector_classDescription(PContingencyClass, "TContingencyClassList", true, ORANGE_API)

#define NOTSPEC(v) if (v.isSpecial()) throw mlexception("unknown variable value");
#define NEEDS(ptype) if(varType!=ptype) throw mlexception("invalid variable type");


// Initializes type field and discrete/continuous field, whichever appropriate.
TContingency::TContingency(PVariable var, PVariable innervar)
: outerVariable(var),
  innerVariable(innervar),
  varType(var ? var->varType : TValue::NONE),
  outerDistribution(TDistribution::create(var)),
  discrete((TDistributionVector *)NULL),
  innerDistribution(TDistribution::create(innervar)),
  innerDistributionUnknown(TDistribution::create(innervar))
{ 
  if (varType==TValue::INTVAR) {
    discrete = mlnew TDistributionVector();
    for(int i=0, e=outerVariable->noOfValues(); i!=e; i++)
      discrete->push_back(TDistribution::create(innervar));
  }
  else if (varType==TValue::FLOATVAR)
    continuous = mlnew TDistributionMap();
}


TContingency::TContingency(const TContingency &old)
: outerVariable(old.outerVariable),
  innerVariable(old.innerVariable),
  varType(old.varType),
  discrete((TDistributionVector *)NULL),
  outerDistribution(CLONE(TDistribution, old.outerDistribution)),
  innerDistribution(CLONE(TDistribution, old.innerDistribution)),
  innerDistributionUnknown(CLONE(TDistribution, old.innerDistributionUnknown))
{ if (varType==TValue::INTVAR)
    discrete = mlnew TDistributionVector(*old.discrete);
  else if (varType==TValue::FLOATVAR)
    continuous = mlnew TDistributionMap(*old.continuous);
}


int TContingency::traverse(visitproc visit, void *arg) const
{ TRAVERSE(TOrange::traverse);

  if (varType==TValue::INTVAR) {
    PITERATE(TDistributionVector, di, discrete)
      PVISIT(*di);
  }
  else if (varType==TValue::FLOATVAR) {
    PITERATE(TDistributionMap, di, continuous)
      PVISIT((*di).second);
  }

  return 0;
}

int TContingency::dropReferences()
{ DROPREFERENCES(TOrange::dropReferences);

  if (varType==TValue::INTVAR)
    mldelete discrete;
  else if (varType==TValue::FLOATVAR)
    mldelete continuous;

  return 0;
}


TContingency &TContingency::operator =(const TContingency &old)
{ outerVariable = old.outerVariable;
  innerVariable = old.innerVariable;
  varType = old.varType;
  innerDistribution = CLONE(TDistribution, old.innerDistribution);
  outerDistribution = CLONE(TDistribution, old.outerDistribution);
  innerDistributionUnknown = CLONE(TDistribution, old.innerDistributionUnknown);

  if (varType==TValue::INTVAR)
    discrete=mlnew TDistributionVector(*old.discrete);
  else if (varType==TValue::FLOATVAR)
    continuous=mlnew TDistributionMap(*old.continuous);
  else discrete=NULL;

  return *this;
}


TContingency::~TContingency()
{ if (varType==TValue::INTVAR)
    mldelete discrete;
  else if (varType==TValue::FLOATVAR)
    mldelete continuous;
}


PDistribution TContingency::operator [](const int &i)                
{ NEEDS(TValue::INTVAR); 
  while (int(discrete->size())<=i) {
    discrete->push_back(TDistribution::create(innerVariable));
    if (innerVariable->varType==TValue::INTVAR)
      discrete->back()->addint(innerVariable->noOfValues()-1, 0);
  }
  return (*discrete)[i];
}


const PDistribution TContingency::operator [](const int &i) const
{ NEEDS(TValue::INTVAR);
  if (!discrete->size())
    raiseError("empty contingency");
  if (i>=int(discrete->size()))
    raiseError("index %i is out of range 0-%i", i, discrete->size()-1);
  return (*discrete)[i];
}


PDistribution TContingency::operator [](const float &i)
{ NEEDS(TValue::FLOATVAR); 
  TDistributionMap::iterator mi=continuous->find(i);
  if (mi==continuous->end()) {
    PDistribution ret = (*continuous)[i] = TDistribution::create(innerVariable);
    if (innerVariable->varType==TValue::INTVAR)
      ret->addint(innerVariable->noOfValues()-1, 0);
    return ret;
  }
  else
    return (*mi).second;
}

    
const PDistribution TContingency::operator [](const float &i) const
{ NEEDS(TValue::FLOATVAR); 
  TDistributionMap::iterator mi = continuous->find(float(i));
  if (mi==continuous->end())
    raiseError("index out of range.");
  return (*mi).second;
}


PDistribution TContingency::operator [](const TValue &i)             
{ NOTSPEC(i);
  return (varType==TValue::INTVAR) ? operator[](int(i)) : operator[](float(i));
}


PDistribution const TContingency::operator [](const TValue &i) const // same, but calls 'const' version of operators[]
{ NOTSPEC(i);
  return (varType==TValue::INTVAR) ? operator[](int(i)) : operator[](float(i)); 
}


PDistribution TContingency::operator [](const string &i)             
{ TValue val;
  checkProperty(outerVariable);
  outerVariable->str2val(i, val);
  return operator[](val);
}


PDistribution const TContingency::operator [](const string &i) const // same, but calls 'const' version of operators[]
{ TValue val;
  checkProperty(outerVariable);
  outerVariable.getReference().str2val(i, val);
  return operator[](val);
}


void TContingency::add(const TValue &outvalue, const TValue &invalue, const float p)
{
  outerDistribution->add(outvalue, p);

  if (outvalue.isSpecial()) {
    innerDistributionUnknown->add(invalue, p);
  }
  else {
    innerDistribution->add(invalue, p);

    switch(outvalue.varType) {
      case TValue::INTVAR:
        if (!outvalue.svalV) {
          (*this)[outvalue]->add(invalue, p);
          return;
        }
        else {
          const TDiscDistribution &dv=dynamic_cast<const TDiscDistribution &>(outvalue.svalV.getReference());
          int i=0;
          float dp=p/dv.abs;
          const_ITERATE(TDiscDistribution, vi, dv)
            (*this)[i++]->add(invalue, dp*(*vi));
          return;
        }

      case TValue::FLOATVAR:
        if (!outvalue.svalV) {
          (*this)[outvalue]->add(invalue, p);
          return;
        }
        else {
          const TContDistribution &dv=dynamic_cast<const TContDistribution &>(outvalue.svalV.getReference());
          float dp=p/dv.abs;
          const_ITERATE(TContDistribution, vi, dv)
            (*this)[(*vi).first]->add(invalue, dp*(*vi).second);
          return;
        }
      default:
        raiseError("unknown value type");
    }
  }
}

       
PDistribution TContingency::p(const int &i) const
{ return operator[](i); }


PDistribution TContingency::p(const string &s) const
{ return operator[](s); }


PDistribution TContingency::p(const TValue &val) const
{ NOTSPEC(val);
  return (varType==TValue::INTVAR) ? p(int(val)) : p(float(val));
}


PDistribution TContingency::p(const float &f) const
{
  NEEDS(TValue::FLOATVAR);
  TDistributionMap::const_iterator i1=continuous->lower_bound(f);
  if (i1==continuous->end())
    if (continuous->size()==0)
      raiseError("empty contingency");
    else
      return CLONE(TDistribution, (*(--i1)).second);
  else if (((*i1).first == f) || (i1==continuous->begin()))
    return CLONE(TDistribution, (*i1).second);

  TDistributionMap::const_iterator i2 = i1;
  i1--;

  const float &x1 = (*i1).first;
  const float &x2 = (*i2).first;
  const PDistribution &y1 = (*i1).second;
  const PDistribution &y2 = (*i2).second;

  const float r = (x1==x2) ? 0.5 : (f-x1)/(x2-x1);

  // We want to compute y1*(1-r) + y2*r
  // We know that r!=0, so we can compute (y1*(1-r)/r + y2) * r
  TDistribution *res = CLONE(TDistribution, y1);
  PDistribution wres = res;
  *res *= (1-r)/r;
  *res += y2;
  *res *= r;

  return wres;
}


void TContingency::normalize()
{ if (varType==TValue::INTVAR)
    ITERATE(TDistributionVector, ci, *discrete)
      (*ci)->normalize();
  else if (varType==TValue::FLOATVAR)
    ITERATE(TDistributionMap, ci, *continuous)
      (*ci).second->normalize();
}




TContingencyClass::TContingencyClass(PVariable outer, PVariable inner)
: TContingency(outer, inner)
{}


float TContingencyClass::p_attr(const TValue &, const TValue &) const
{ raiseError("cannot compute p(value|class)"); 
  return 0.0;
}


float TContingencyClass::p_class(const TValue &, const TValue &) const
{ raiseError("cannot compute p(class|value)");
  return 0.0;
}

PDistribution TContingencyClass::p_attrs(const TValue &) const
{ raiseError("cannot compute p(.|class)"); 
  return PDistribution();
}


PDistribution TContingencyClass::p_classes(const TValue &) const
{ raiseError("cannot compute p(class|.)");
  return PDistribution();
}


void TContingencyClass::constructFromGenerator(PVariable outer, PVariable inner, PExampleGenerator gen, const long &weightID, const int &attrNo)
{
  outerVariable = outer;
  innerVariable = inner;

  outerDistribution = TDistribution::create(outerVariable);
  innerDistribution = TDistribution::create(innerVariable);
  innerDistributionUnknown = TDistribution::create(innerVariable);

  varType = outerVariable->varType;
  if (varType==TValue::INTVAR) {
    discrete = mlnew TDistributionVector();
    for(int i=0, e=outerVariable->noOfValues(); i!=e; i++)
      discrete->push_back(TDistribution::create(innerVariable));
  } 
  else {
   _ASSERT(varType==TValue::FLOATVAR);
    continuous = mlnew TDistributionMap();
  }

  if (attrNo == ILLEGAL_INT)
    add_gen(gen, weightID);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -