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

📄 corn.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
*/


#ifdef _MSC_VER
  #define NOMINMAX
  #define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
  #include <windows.h>
#endif

#include "c2py.hpp"
#include "pywrapper.hpp"
#include "stladdon.hpp"
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
#include <string>
using namespace std;

#include "corn.hpp"
#include "c2py.hpp"

/* *********** MODULE INITIALIZATION ************/

#define PyTRY try {

#define PYNULL ((PyObject *)NULL)
#define PyCATCH   PyCATCH_r(PYNULL)
#define PyCATCH_1 PyCATCH_r(-1)

#define PyCATCH_r(r) \
  } \
catch (pyexception err)   { err.restore(); return r; } \
catch (exception err) { PYERROR(PyExc_CornKernel, err.what(), r); }


PyObject *PyExc_CornKernel;
PyObject *PyExc_CornWarning;

CORN_API void initcorn()
{ if (   ((PyExc_CornKernel = makeExceptionClass("corn.KernelException", "An error occurred in corn's C++ code")) == NULL)
      || ((PyExc_CornWarning = makeExceptionClass("corn.Warning", "corn warning", PyExc_Warning)) == NULL))
    return;

  PyObject *me;
  me = Py_InitModule("corn", corn_functions);
}


#ifdef _MSC_VER
BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{ switch (ul_reason_for_call)
	{ case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break; }
  return TRUE;
}
#endif

/* *********** EXCEPTION CATCHING ETC. ************/


#include <exception>
#include <string>

using namespace std;

#ifdef _MSC_VER

#define cornexception exception

#else

class cornexception : public exception {
public:
   string err_desc;
   cornexception(const string &desc)
   : err_desc(desc)
   {}

   ~cornexception() throw()
   {}

   virtual const char* what () const throw()
   { return err_desc.c_str(); };
};

#endif


exception CornException(const string &anerr)
{ return cornexception(anerr.c_str()); }

exception CornException(const string &anerr, const string &s)
{ char buf[255];
  sprintf(buf, anerr.c_str(), s.c_str());
  return cornexception(buf);
}

exception CornException(const string &anerr, const string &s1, const string &s2)
{ char buf[255];
  sprintf(buf, anerr.c_str(), s1.c_str(), s2.c_str());
  return cornexception(buf);
}

exception CornException(const string &anerr, const string &s1, const string &s2, const string &s3)
{ char buf[255];
  sprintf(buf, anerr.c_str(), s1.c_str(), s2.c_str(), s3.c_str());
  return cornexception(buf);
}

exception CornException(const string &anerr, const long i)
{ char buf[255];
  sprintf(buf, anerr.c_str(), i);
  return cornexception(buf);
}

#undef min
#undef max

#define PyTRY try {
#define PYNULL ((PyObject *)NULL)


int getIntegerAttr(PyObject *self, char *name)
{ 
  PyObject *temp = PyObject_GetAttrString(self, name);
  
  if (!temp)
    throw CornException("no attribute '%s'", name);
  if (!PyInt_Check(temp)) {
    Py_DECREF(temp);
    throw CornException("error in attribute '%s': integer expected", name);
  }
  
  int res = (int)PyInt_AsLong(temp);
  Py_DECREF(temp);
  return res;
}

float getFloatAttr(PyObject *self, char *name)
{ 
  PyObject *temp = PyObject_GetAttrString(self, name);

  if (!temp)
    throw CornException("no attribute '%s'", name);
  if (!PyFloat_Check(temp)) {
    Py_DECREF(temp);
    throw CornException("error in attribute '%s': float expected", name);
  }

  float res = (float)PyFloat_AsDouble(temp);
  Py_DECREF(temp);
  return res;
}



class TestedExample {
public:
  int actualClass;
  int iterationNumber;
  vector<int> classes;
  vector<vector<float> > probabilities;
  float weight;

  TestedExample(const int &ac, const int &it, const vector<int> &c, const vector<vector<float> > &p, const float &w = 1.0);
  TestedExample(PyObject *);
};


class ExperimentResults {
public:
  int numberOfIterations, numberOfLearners, numberOfClasses;
  vector<TestedExample> results;
  bool weights;
  int baseClass;

  ExperimentResults(const int &ni, const int &nl, const int &nc, const bool &);
  ExperimentResults(PyObject *);
};



TestedExample::TestedExample(const int &ac, const int &it, const vector<int> &c, const vector<vector<float> > &p, const float &w)
: actualClass(ac),
  iterationNumber(it),
  classes(c),
  probabilities(p),
  weight(w)
{}


TestedExample::TestedExample(PyObject *obj)
: actualClass(getIntegerAttr(obj, "actualClass")),
  iterationNumber(getIntegerAttr(obj, "iterationNumber")),
  weight(getFloatAttr(obj, "weight"))

{ 
  PyObject *temp = PYNULL;

  try {
    temp = PyObject_GetAttrString(obj, "classes");
    if (!temp || !PyList_Check(temp))
      throw CornException("error in 'classes' attribute");

    int i,e;
    for(i = 0, e = PyList_Size(temp); i<e; i++) {
      PyObject *cp = PyList_GetItem(temp, i);
      if (!cp || !PyInt_Check(cp))
        throw CornException("error in attribute 'classes'");
      classes.push_back((int)PyInt_AsLong(cp));
    }
    Py_DECREF(temp);
    temp = PYNULL;

    temp = PyObject_GetAttrString(obj, "probabilities");
    if (!temp || !PyList_Check(temp))
      throw CornException("error in attribute 'probabilities'");
  
    for(i = 0, e = PyList_Size(temp); i<e; i++) {
      PyObject *slist = PyList_GetItem(temp, i);
      if (!slist || !PyList_Check(slist))
        throw CornException("error in 'probabilities' attribute");
      
      probabilities.push_back(vector<float>());
      for(int ii = 0, ee = PyList_Size(slist); ii<ee; ii++) {
        PyObject *fe = PyList_GetItem(slist, ii);
        if (!fe || !PyFloat_Check(fe))
          throw CornException("error in 'probabilities' attribute");
        probabilities.back().push_back((float)PyFloat_AsDouble(fe));
      }
    }

    Py_DECREF(temp);
    temp = PYNULL;
  }
  catch (...) {
    Py_XDECREF(temp);
  }
}
        
      

ExperimentResults::ExperimentResults(const int &ni, const int &nl, const int &nc, const bool &w)
: numberOfIterations(ni),
  numberOfLearners(nl),
  numberOfClasses(nc),
  weights(w)
{}


ExperimentResults::ExperimentResults(PyObject *obj)
: numberOfIterations(getIntegerAttr(obj, "numberOfIterations")),
  numberOfLearners(getIntegerAttr(obj, "numberOfLearners"))
{ 
  PyObject *temp = PyObject_GetAttrString(obj, "weights");
  weights = temp && (PyObject_IsTrue(temp)!=0);
  Py_DECREF(temp);

  temp = PyObject_GetAttrString(obj, "baseClass");
  baseClass = temp ? PyInt_AsLong(temp) : -1;
  Py_DECREF(temp);

  temp = PyObject_GetAttrString(obj, "classValues");
  if (!temp)
    throw CornException("no 'classValues' attribute");
  numberOfClasses = PySequence_Size(temp);
  Py_DECREF(temp);
  if (numberOfClasses == -1)
    throw CornException("'classValues' should contain a list of class names");

  PyObject *pyresults = PyObject_GetAttrString(obj, "results");
  if (!pyresults)
    throw CornException("no 'results' attribute");

  if (!PyList_Check(pyresults)) {
    Py_DECREF(pyresults);
    throw CornException("'results' is no a list");
  }

  for(int i = 0, e = PyList_Size(pyresults); i<e; i++) {
    PyObject *testedExample = PyList_GetItem(pyresults, i);
    results.push_back(TestedExample(testedExample));
  }

  Py_DECREF(pyresults);
}



inline float diff2(const float &abnormal, const float &normal)
{ if (normal<abnormal)
    return 1;
  if (normal>abnormal)
    return 0;
  return 0.5;
}




class pp {
public:
  float normal, abnormal;

  inline pp()
  : normal(0.0),
    abnormal(0.0)
  {}

  inline void add(const bool &b, const float &w = 1.0)
  { *(b ? &abnormal : &normal) += w; }

  pp &operator +=(const pp &other)
  { normal += other.normal;
    abnormal += other.abnormal;
    return *this;
  }

  pp &operator -=(const pp &other)
  { normal -= other.normal;
    abnormal -= other.abnormal;
    return *this;
  }
};

typedef map<float, pp> TCummulativeROC;

void C_computeROCCumulative(const ExperimentResults &results, int classIndex, pp &totals, vector<TCummulativeROC> &cummlists, bool useWeights)
{
  if (classIndex<0)
    classIndex = results.baseClass;
  if (classIndex<0)
    classIndex = 1;
  if (classIndex >= results.numberOfClasses)
    throw CornException("classIndex out of range");

  totals = pp();
  cummlists = vector<TCummulativeROC>(results.numberOfLearners);

  const_ITERATE(vector<TestedExample>, i, results.results) {
    bool ind = (*i).actualClass==classIndex;
    float weight = useWeights ? (*i).weight : 1.0;
    totals.add(ind, weight);

    vector<TCummulativeROC>::iterator ci(cummlists.begin());
    const_ITERATE(vector<vector<float> >, pi, (*i).probabilities) {
      const float &tp = (*pi)[classIndex];
      (*ci)[tp];
      (*ci)[tp].add(ind, weight);
      ci++;
    }
  }
}


void C_computeROCCumulativePair(const ExperimentResults &results, int classIndex1, int classIndex2, pp &totals, vector<TCummulativeROC> &cummlists, bool useWeights)
{
  if ((classIndex1 >= results.numberOfClasses) || (classIndex2 >= results.numberOfClasses))
    throw CornException("classIndex out of range");

  totals = pp();
  cummlists = vector<TCummulativeROC>(results.numberOfLearners);

  const_ITERATE(vector<TestedExample>, i, results.results) {
    bool ind = (*i).actualClass==classIndex1;
    if (!ind && ((*i).actualClass!=classIndex2))
      continue;

    float weight = useWeights ? (*i).weight : 1.0;
    totals.add(ind, weight);

    vector<TCummulativeROC>::iterator ci(cummlists.begin());
    const_ITERATE(vector<vector<float> >, pi, (*i).probabilities) {
      const float &c1 = (*pi)[classIndex1];
      const float c_sum = c1 + (*pi)[classIndex2];
      const float tp = (c_sum > 1e-10) ? c1 / c_sum : 0.5;
      (*ci)[tp];
      (*ci)[tp].add(ind, weight);
      ci++;
    }
  }
}


class TCDT {
public:

⌨️ 快捷键说明

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