📄 contingency.cpp
字号:
else
add_gen(gen, attrNo, weightID);
}
TContingencyClassAttr::TContingencyClassAttr(PVariable attrVar, PVariable classVar)
: TContingencyClass(classVar, attrVar)
{}
TContingencyClassAttr::TContingencyClassAttr(PExampleGenerator gen, const int &attrNo, const long &weightID)
{
const TDomain &domain = gen->domain.getReference();
if (!domain.classVar)
raiseError("classless domain");
if (attrNo>=int(domain.attributes->size()))
raiseError("attribute index %i out of range", attrNo, domain.attributes->size()-1);
PVariable attribute = domain.getVar(attrNo, false);
if (!attribute)
raiseError("attribute not found");
constructFromGenerator(domain.classVar, attribute, gen, weightID, attrNo);
}
TContingencyClassAttr::TContingencyClassAttr(PExampleGenerator gen, PVariable var, const long &weightID)
{
if (!gen->domain->classVar)
raiseError("classless domain");
const int attrNo = gen->domain->getVarNum(var, false);
constructFromGenerator(gen->domain->classVar, var, gen, weightID, attrNo);
}
PVariable TContingencyClassAttr::getClassVar()
{ return outerVariable; }
PVariable TContingencyClassAttr::getAttribute()
{ return innerVariable; }
void TContingencyClassAttr::add_gen(PExampleGenerator gen, const long &weightID)
{ checkProperty(innerVariable);
int attrNo = gen->domain->getVarNum(innerVariable, false);
if (attrNo != ILLEGAL_INT)
PEITERATE(ei, gen)
add((*ei).getClass(), (*ei)[attrNo], WEIGHT(*ei));
else {
if (!innerVariable->getValueFrom)
raiseError("attribute '%s' is not in the domain and its 'getValueFrom' is not defined", innerVariable->name.c_str());
TVariable &vfe = innerVariable.getReference();
PEITERATE(ei, gen)
add((*ei).getClass(), vfe.computeValue(*ei), WEIGHT(*ei));
}
}
void TContingencyClassAttr::add_gen(PExampleGenerator gen, const int &attrNo, const long &weightID)
{ PEITERATE(ei, gen)
add((*ei).getClass(), (*ei)[attrNo], WEIGHT(*ei));
}
void TContingencyClassAttr::add_attrclass(const TValue &varValue, const TValue &classValue, const float &p)
{ add(classValue, varValue, p); }
float TContingencyClassAttr::p_attr(const TValue &varValue, const TValue &classValue) const
{ return p(classValue)->p(varValue); }
PDistribution TContingencyClassAttr::p_attrs(const TValue &classValue) const
{ return p(classValue); }
TContingencyAttrClass::TContingencyAttrClass(PVariable attrVar, PVariable classVar)
: TContingencyClass(attrVar, classVar)
{}
TContingencyAttrClass::TContingencyAttrClass(PExampleGenerator gen, PVariable var, const long &weightID)
{
if (!gen->domain->classVar)
raiseError("classless domain");
const int attrNo = gen->domain->getVarNum(var, false);
constructFromGenerator(var, gen->domain->classVar, gen, weightID, attrNo);
}
TContingencyAttrClass::TContingencyAttrClass(PExampleGenerator gen, const int &attrNo, const long &weightID)
{
const TDomain &domain = gen->domain.getReference();
if (!domain.classVar)
raiseError("classless domain");
if (attrNo>=int(gen->domain->attributes->size()))
raiseError("attribute index %i out of range", attrNo, gen->domain->attributes->size()-1);
PVariable attribute = domain.getVar(attrNo);
if (!attribute)
raiseError("attribute not found");
constructFromGenerator(attribute, domain.classVar, gen, weightID, attrNo);
}
PVariable TContingencyAttrClass::getClassVar()
{ return innerVariable; }
PVariable TContingencyAttrClass::getAttribute()
{ return outerVariable; }
void TContingencyAttrClass::add_gen(PExampleGenerator gen, const long &weightID)
{ int attrNo = gen->domain->getVarNum(outerVariable, false);
if (attrNo != ILLEGAL_INT)
PEITERATE(ei, gen)
add((*ei)[attrNo], (*ei).getClass(), WEIGHT(*ei));
else {
if (!outerVariable->getValueFrom)
raiseError("attribute '%s' is not in the domain and its value cannot be computed", outerVariable->name.c_str());
TVariable &vfe = outerVariable.getReference();
PEITERATE(ei, gen)
add(vfe.computeValue(*ei), (*ei).getClass(), WEIGHT(*ei));
}
}
void TContingencyAttrClass::add_gen(PExampleGenerator gen, const int &attrNo, const long &weightID)
{ PEITERATE(ei, gen)
add((*ei)[attrNo], (*ei).getClass(), WEIGHT(*ei));
}
void TContingencyAttrClass::add_attrclass(const TValue &varValue, const TValue &classValue, const float &p)
{ add(varValue, classValue, p); }
float TContingencyAttrClass::p_class(const TValue &varValue, const TValue &classValue) const
{ try {
return p(varValue)->p(classValue);
}
catch (mlexception exc) {
// !!! This is extremely ugly. Correct it by asking p not to raise exceptions!
if (!strcmp(exc.what(), "TDistribution: index out of range."))
return 0.0;
else
throw;
}
}
PDistribution TContingencyAttrClass::p_classes(const TValue &varValue) const
{ return p(varValue); }
TContingencyAttrAttr::TContingencyAttrAttr(PVariable variable, PVariable innervar)
: TContingency(variable, innervar)
{}
TContingencyAttrAttr::TContingencyAttrAttr(PVariable variable, PVariable innervar, PExampleGenerator gen, const long weightID)
: TContingency(variable, innervar)
{ if (gen)
operator()(gen, weightID);
}
TContingencyAttrAttr::TContingencyAttrAttr(const int &var, const int &innervar, PExampleGenerator gen, const long weightID)
: TContingency(gen->domain->getVar(var), gen->domain->getVar(innervar))
{ operator()(gen, weightID); }
void TContingencyAttrAttr::operator()(PExampleGenerator gen, const long weightID)
{ int var=gen->domain->getVarNum(outerVariable, false);
int invar=gen->domain->getVarNum(innerVariable, false);
if (var == ILLEGAL_INT)
if (invar == ILLEGAL_INT)
PEITERATE(ei, gen) {
TValue val = outerVariable->computeValue(*ei);
add(val, innerVariable->computeValue(*ei), WEIGHT(*ei));
}
else // var == ILLEGAL_INT, invar is not
PEITERATE(ei, gen) {
TValue val = outerVariable->computeValue(*ei);
add(val, (*ei)[invar], WEIGHT(*ei));
}
else
if (invar<0) // invar == ILLEGAL_INT, var is not
PEITERATE(ei, gen)
add((*ei)[var], innerVariable->computeValue(*ei), WEIGHT(*ei));
else // both OK
PEITERATE(ei, gen)
add((*ei)[var], (*ei)[invar], WEIGHT(*ei));
}
float TContingencyAttrAttr::p_attr(const TValue &outerValue, const TValue &innerValue) const
{ return p(outerValue)->p(innerValue); }
PDistribution TContingencyAttrAttr::p_attrs(const TValue &outerValue) const
{ return p(outerValue); }
TDomainContingency::TDomainContingency(bool acout)
: classIsOuter(acout)
{}
// Extract TContingency values for all attributes, by iterating through all examples from the generator
TDomainContingency::TDomainContingency(PExampleGenerator gen, const long weightID, bool acout)
: classIsOuter(acout)
{ computeMatrix(gen, weightID); }
// Extract TContingency values for all attributes, by iterating through all examples from the generator
TDomainContingency::TDomainContingency(PExampleGenerator gen, const long weightID, const vector<bool> &attributes, bool acout)
: classIsOuter(acout)
{ computeMatrix(gen, weightID, &attributes); }
void TDomainContingency::computeMatrix(PExampleGenerator gen, const long &weightID, const vector<bool> *attributes, PDomain newDomain)
// IMPORTANT NOTE: When weightID and newDomain are specified, weights are computed from the original examples
// (this is to avoid the need to copy the meta-attributes)
{ PDomain myDomain = newDomain ? newDomain : gen->domain;
PVariable classVar = myDomain->classVar;
if (!classVar)
raiseError("classless domain");
classes = TDistribution::create(classVar);
char classType = classVar->varType;
// Prepare a TContingency for each attribute that has discrete or continuous values
TValue lastClassValue;
if (classVar->varType==TValue::INTVAR)
lastClassValue = TValue(classVar->noOfValues()-1);
vector<bool>::const_iterator ai, ae;
if (attributes) {
ai = attributes->begin();
ae = attributes->end();
}
PITERATE(TVarList, vli, myDomain->attributes) {
if (attributes) {
if (ai == ae)
break;
if (!*ai++) {
push_back(NULL);
continue;
}
}
if (classIsOuter)
push_back(mlnew TContingencyClassAttr(*vli, myDomain->classVar));
else
push_back(mlnew TContingencyAttrClass(*vli, myDomain->classVar));
// if variable and class types are discrete, it initializes distributions to full length
// (which will help the copy constructor with estimation below)
if (((*vli)->varType==TValue::INTVAR) && (classType==TValue::INTVAR))
for(int i=0, e=(*vli)->noOfValues(); i!=e; i++)
back()->add_attrclass(TValue(i), lastClassValue, 0);
}
iterator si;
int Na = myDomain->attributes->size();
TExample newExample(myDomain);
TExample::iterator vi, cli;
PEITERATE(fi, gen) {
if (newDomain) {
newDomain->convert(newExample, *fi);
vi=newExample.begin();
}
else
vi=(*fi).begin();
cli=vi+Na;
float xmplWeight=WEIGHT(*fi);
classes->add(*cli, xmplWeight);
for(si=begin(); vi!=cli; vi++, si++)
if (*si)
(*si)->add_attrclass(*vi, *cli, xmplWeight);
}
}
/*
TDomainContingency::TDomainContingency(const TDomainContingency &old, PProbabilityEstimator estimator)
: classIsOuter(old.classIsOuter)
{
if (!estimator)
classes = estimator->operator()(old.classes);
else {
classes = CLONE(TDistribution, old.classes);
classes->normalize();
}
if (classIsOuter)
const_ITERATE(TDomainContingency, di, old)
push_back(mlnew TContingencyClassAttr(*di, estimator));
else
const_ITERATE(TDomainContingency, di, old)
push_back(mlnew TContingencyAttrClass(*di, estimator));
}
*/
void TDomainContingency::normalize()
{ classes->normalize();
this_ITERATE(ti)
(*ti)->normalize();
}
PDomainDistributions TDomainContingency::getDistributions()
{ PDomainDistributions ddist;
if (classIsOuter)
this_ITERATE(ti)
ddist->push_back((*ti)->innerDistribution);
else
this_ITERATE(ti)
ddist->push_back((*ti)->outerDistribution);
return ddist;
}
TComputeDomainContingency::TComputeDomainContingency(bool acout)
: classIsOuter(acout)
{}
PDomainContingency TComputeDomainContingency::operator()(PExampleGenerator eg, const long &weightID)
{ return mlnew TDomainContingency(eg, weightID); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -