📄 trindex.cpp
字号:
/*
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
*/
// to include Python.h before STL defines a template set (doesn't work with VC 6.0)
#include "garbage.hpp"
#include <math.h>
#include <algorithm>
#include <set>
#include "stladdon.hpp"
#include "random.hpp"
#include "vars.hpp"
#include "domain.hpp"
#include "examples.hpp"
#include "examplegen.hpp"
#include "trindex.ppp"
class rsrgen {
public:
PRandomGenerator randomGenerator;
rsrgen(const int &seed)
: randomGenerator(PRandomGenerator(mlnew TRandomGenerator((unsigned long)(seed>=0 ? seed : 0))))
{}
rsrgen(PRandomGenerator rgen)
: randomGenerator(rgen ? rgen : PRandomGenerator(mlnew TRandomGenerator()))
{}
rsrgen(PRandomGenerator rgen, const int &seed)
: randomGenerator(rgen ? rgen : PRandomGenerator(mlnew TRandomGenerator((unsigned long)(seed>=0 ? seed : 0))))
{}
int operator()(int n)
{ return randomGenerator->randint(n); }
};
TMakeRandomIndices::TMakeRandomIndices(const int &astratified, const int &arandseed)
: stratified(astratified),
randseed(arandseed),
randomGenerator()
{}
TMakeRandomIndices::TMakeRandomIndices(const int &astratified, PRandomGenerator randgen)
: stratified(astratified),
randseed(-1),
randomGenerator(randgen)
{}
TMakeRandomIndices2::TMakeRandomIndices2(const float &ap0, const int &astratified, const int &arandseed)
: TMakeRandomIndices(astratified, arandseed),
p0(ap0)
{}
TMakeRandomIndices2::TMakeRandomIndices2(const float &ap0, const int &astratified, PRandomGenerator randgen)
: TMakeRandomIndices(astratified, randgen),
p0(ap0)
{}
PRandomIndices TMakeRandomIndices2::operator()(const int &n)
{ return operator()(n, p0); }
PRandomIndices TMakeRandomIndices2::operator()(const int &n, const float &p0)
{ if (stratified==TMakeRandomIndices::STRATIFIED)
raiseError("cannot prepare stratified indices (no class values)");
if (!randomGenerator && (randseed<0))
raiseCompatibilityWarning("object always returns the same indices unless either 'randomGenerator' or 'randseed' is set");
PRandomIndices indices(mlnew TFoldIndices(n, 1));
TFoldIndices::iterator ii(indices->begin());
int no= (p0<=1.0) ? int(p0*n+0.5) : int(p0+0.5);
if (no>n) no=n;
while(no--)
*(ii++)=0;
rsrgen rg(randomGenerator, randseed);
or_random_shuffle(indices->begin(), indices->end(), rg);
return indices;
}
PRandomIndices TMakeRandomIndices2::operator()(PExampleGenerator gen)
{ return operator()(gen, p0); }
PRandomIndices TMakeRandomIndices2::operator()(PExampleGenerator gen, const float &ap0)
{
if (!gen)
raiseError("invalid example generator");
if (!randomGenerator && (randseed<0))
raiseCompatibilityWarning("object always returns the same indices unless either 'randomGenerator' or 'randseed' is set");
if (stratified==TMakeRandomIndices::NOT_STRATIFIED)
return operator()(gen->numberOfExamples(), ap0);
if (!gen->domain->classVar)
if (stratified==TMakeRandomIndices::STRATIFIED_IF_POSSIBLE)
return operator()(gen->numberOfExamples(), ap0);
else
raiseError("invalid example generator or class-less domain");
if (gen->domain->classVar->varType!=TValue::INTVAR)
if (stratified==TMakeRandomIndices::STRATIFIED_IF_POSSIBLE)
return operator()(gen->numberOfExamples(), ap0);
else
raiseError("cannot prepare stratified indices (non-discrete class values)");
TExampleIterator ri=gen->begin();
if (!ri)
return PRandomIndices(mlnew TFoldIndices());
typedef pair<int, int> pii; // index of example, class value
vector<pii> ricv;
for(int in=0; ri; ++ri)
if ((*ri).getClass().isSpecial()) {
if (stratified==TMakeRandomIndices::STRATIFIED_IF_POSSIBLE)
return operator()(gen->numberOfExamples(), ap0);
else
raiseError("cannot prepare stratified indices (undefined class value(s))");
}
else
ricv.push_back(pii(in++, (*ri).getClass()));
random_sort(ricv.begin(), ricv.end(),
predOn2nd<pair<int, int>, less<int> >(), predOn2nd<pair<int, int>, equal_to<int> >(),
rsrgen(randomGenerator, randseed));
float p0;
if (ap0>1.0) {
if (ap0>ricv.size())
raiseError("p0 is greater than the number of examples");
else
p0 = ap0/float(ricv.size());
}
else
p0 = ap0;
float p1 = 1-p0;
float rem = 0;
PRandomIndices indices(mlnew TFoldIndices());
indices->resize(ricv.size());
ITERATE(vector<pii>, ai, ricv)
if (rem<=0) {
indices->at((*ai).first) = 1;
rem += p0;
}
else {
indices->at((*ai).first) = 0;
rem -= p1;
}
// E.g., if p0 is two times p1, two 0's will cancel one 1.
return indices;
}
TMakeRandomIndicesN::TMakeRandomIndicesN(const int &astrat, const int &randseed)
: TMakeRandomIndices(astrat, randseed)
{}
TMakeRandomIndicesN::TMakeRandomIndicesN(const int &astrat, PRandomGenerator randgen)
: TMakeRandomIndices(astrat, randgen)
{}
TMakeRandomIndicesN::TMakeRandomIndicesN(PFloatList ap, const int &astrat, const int &randseed)
: TMakeRandomIndices(astrat, randseed),
p(ap)
{}
TMakeRandomIndicesN::TMakeRandomIndicesN(PFloatList ap, const int &astrat, PRandomGenerator randgen)
: TMakeRandomIndices(astrat, randgen),
p(ap)
{}
/* Prepares a vector of given size and with given distribution of elements. Distribution is given as a vector of
floats and the constructor prepares a vector with elements from 0 to p.size() (therefore p.size()+1 elements
with the last one having probability 1-sum(p)). */
PRandomIndices TMakeRandomIndicesN::operator()(const int &n)
{ checkProperty(p); // although it is checked later, a better diagnostics can be given here
return operator()(n, p); }
PRandomIndices TMakeRandomIndicesN::operator()(PExampleGenerator gen)
{ checkProperty(p); // although it is checked later, a better diagnostics can be given here
return operator()(gen->numberOfExamples(), p); }
PRandomIndices TMakeRandomIndicesN::operator()(PExampleGenerator gen, PFloatList ap)
{ return operator()(gen->numberOfExamples(), ap); }
PRandomIndices TMakeRandomIndicesN::operator()(const int &n, PFloatList ap)
{
if (!ap || !ap->size())
raiseError("'p' not defined or empty");
if (!randomGenerator && (randseed<0))
raiseCompatibilityWarning("object always returns the same indices unless either 'randomGenerator' or 'randseed' is set");
float sum = 0;
bool props = true;
for(TFloatList::const_iterator pis(ap->begin()), pie(ap->end()); pis!=pie; pis++) {
sum += *pis;
if (*pis > 1.0)
props = false;
}
if (props) {
if (sum>=1.0)
raiseError("elements of 'p' sum to 1 or more");
}
else {
if (sum>n)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -