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

📄 callback.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 "values.hpp"
#include "vars.hpp"
#include "domain.hpp"
#include "examples.hpp"
#include "table.hpp"
#include "contingency.hpp"
#include "distance.hpp"

#include "cls_example.hpp"
#include "cls_value.hpp"
#include "cls_orange.hpp"

#include "lib_kernel.hpp"
#include "externs.px"

#include "callback.ppp"


PyObject *callCallback(PyObject *self, PyObject *args)
{ PyObject *result;
  
  if (PyObject_HasAttrString(self, "__callback")) {
    PyObject *callback = PyObject_GetAttrString(self, "__callback");
    result = PyObject_CallObject(callback, args);
    Py_DECREF(callback);
  }
  else 
    result = PyObject_CallObject(self, args);

  if (!result)
    throw pyexception();

  return result;
}


PyObject *setCallbackFunction(PyObject *self, PyObject *args)
{ PyObject *func;
  if (!PyArg_ParseTuple(args, "O", &func)) {
    PyErr_Format(PyExc_TypeError, "callback function for '%s' expected", self->ob_type->tp_name);
    Py_DECREF(self);
    return PYNULL;
  }
  else if (!PyCallable_Check(func)) {
    PyErr_Format(PyExc_TypeError, "'%s' object is not callable", func->ob_type->tp_name);
    Py_DECREF(self);
    return PYNULL;
  }

  PyObject_SetAttrString(self, "__callback", func);
  return self;
}


PyObject *callbackReduce(PyObject *self, TOrangeType &basetype)
{
  if (self->ob_type == (PyTypeObject *)&basetype) {
    PyObject *packed = packOrangeDictionary(self);
    PyObject *callback = PyDict_GetItemString(packed, "__callback");
    if (!callback)
      PYERROR(PyExc_AttributeError, "cannot pickle an invalid callback object ('__callback' attribute is missing)", NULL);

    PyDict_DelItemString(packed, "__callback");
    return Py_BuildValue("O(O)N", self->ob_type, callback, packed);
  }
  else
    return Py_BuildValue("O()N", self->ob_type, packOrangeDictionary(self));
}


bool TFilter_Python::operator()(const TExample &ex)
{ 
  PyObject *args = Py_BuildValue("(N)", Example_FromExampleCopyRef(ex));
  PyObject *result = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  bool res = bool(PyObject_IsTrue(result)!=0);
  Py_DECREF(result);
  return res;
}

PFilter TFilter_Python::deepCopy() const
{
  PyObject *result = PyObject_CallMethod((PyObject *)myWrapper,"deepCopy",NULL);
  if (!result) 
    raiseError("An exception has been thrown in method deepCopy!");
  if (!PyOrFilter_Check(result)) 
    raiseError("deepCopy is expected to return something derived from Filter");
  
  PFilter fil = PyOrange_AsFilter(result);
  Py_DECREF(result);
  return fil;
}


void TTransformValue_Python::transform(TValue &val)
{
  PyObject *args = Py_BuildValue("(N)", Value_FromValue(val));
  PyObject *result = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  PVariable var;
  bool succ = convertFromPython(result, val, var);
  Py_DECREF(result);

  if (!succ)
    raiseError("TransformValue.__call__'s result cannot be converted to a Value");
}


TMeasureAttribute_Python::TMeasureAttribute_Python()
: TMeasureAttribute(TMeasureAttribute::DomainContingency, true, true)
{}


float TMeasureAttribute_Python::callMeasure(PyObject *args)
{
  PyObject *res = callCallback((PyObject *)myWrapper, args);
  PyObject *resf = PyNumber_Float(res);
  Py_DECREF(res);

  if (!resf)
    raiseError("invalid result from __call__");

  float mres = (float)PyFloat_AsDouble(resf);  
  Py_DECREF(resf);
  return mres;
}


float TMeasureAttribute_Python::operator()(PContingency cont, PDistribution classDistribution, PDistribution apriorClass)
{ return callMeasure(Py_BuildValue("(NNN)", WrapOrange(cont),
                                            WrapOrange(classDistribution),
                                            WrapOrange(apriorClass))); }


float TMeasureAttribute_Python::operator()(int attrNo, PDomainContingency dcont, PDistribution apriorClass)
{ return callMeasure(Py_BuildValue("(iNN)", attrNo, 
                                            WrapOrange(dcont),
                                            WrapOrange(apriorClass))); }



PClassifier TLearner_Python::operator()(PExampleGenerator eg, const int &weight)
{ if (!eg)
    raiseError("invalid example generator");

  PyObject *args = Py_BuildValue("(Ni)", WrapOrange(POrange(eg)), weight);
  PyObject *res = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (!PyOrClassifier_Check(res)) 
    raiseError("__call__ is expected to return something derived from Classifier");

  PClassifier clsf = PyOrange_AsClassifier(res);
  Py_DECREF(res);
  return clsf;
}


#include "vectortemplates.hpp"
#include "converts.hpp"
PAttributedFloatList TLogRegFitter_Python::operator()(PExampleGenerator eg, const int &weightID, PAttributedFloatList &beta_se, float &likelihood, int &status, PVariable &attribute)
{
  if (!eg)
    raiseError("invalid example generator");

  PyObject *args = Py_BuildValue("(Ni)", WrapOrange(POrange(eg)), weightID);
  PyObject *res = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (!PyTuple_Check(res) || (PyTuple_Size(res)<2) || !PyInt_Check(PyTuple_GET_ITEM(res, 0)))
    raiseError("invalid result from __call__");

  status = (int)PyInt_AsLong(PyTuple_GET_ITEM(res, 0));
  if (status <= TLogRegFitter::Divergence) {
    if (PyTuple_Size(res) != 4)
      raiseError("invalid result from __call__");

    PFloatList beta = ListOfUnwrappedMethods<PAttributedFloatList, TAttributedFloatList, float>::P_FromArguments(PyTuple_GET_ITEM(res, 1));
    beta_se = ListOfUnwrappedMethods<PAttributedFloatList, TAttributedFloatList, float>::P_FromArguments(PyTuple_GET_ITEM(res, 2));
    Py_DECREF(res);
    if (!beta || !beta_se || !PyNumber_ToFloat(PyTuple_GET_ITEM(res, 3), likelihood))
      throw pyexception();

    attribute = PVariable();
    return beta;
  }
  else {
    if (PyTuple_Size(res) != 2)
      raiseError("invalid result from __call__");

    attribute = PyOrange_AsVariable(PyTuple_GET_ITEM(res, 1));
    beta_se = PAttributedFloatList();
    return PAttributedFloatList();
  }
}


TValue TClassifier_Python::operator ()(const TExample &ex)
{ 
  PyObject *args = Py_BuildValue("(Ni)", Example_FromExampleCopyRef(ex), 0);
  PyObject *result = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (result==Py_None) {
    Py_DECREF(result);
    return classVar ? classVar->DK() : TValue(TValue::INTVAR, valueDK);
  }
  
  TValue value;
  if (!convertFromPython(result, value, classVar)) {
    Py_DECREF(result);
    raiseError("invalid result from __call__");
  }

  Py_DECREF(result);
  return value;
}


PDistribution TClassifier_Python::classDistribution(const TExample &ex)
{ 
  PyObject *args = Py_BuildValue("(Ni)", Example_FromExampleCopyRef(ex), 1);
  PyObject *result=callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (result==Py_None) {
    Py_DECREF(result);
    return PDistribution(classVar);
  }

  if (PyOrDistribution_Check(result)) {
    PDistribution dist = PyOrange_AsDistribution(result);
    Py_DECREF(result);
    return dist;
  }

  raiseError("invalid result from __call__");
  return PDistribution();
}


void TClassifier_Python::predictionAndDistribution(const TExample &ex, TValue &val, PDistribution &dist)
{ 
  PyObject *args = Py_BuildValue("(Ni)", Example_FromExampleCopyRef(ex), 2);
  PyObject *result=callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (result==Py_None) {
    Py_DECREF(result);
    if (classVar) {
      val = classVar->DK();
      dist = PDistribution(classVar);
    }
    else {
      val = TValue(TValue::INTVAR, valueDK);
      dist = PDistribution();
    }
    return;
  }

  PyObject *obj1;
  if (   !PyArg_ParseTuple(result, "OO&", &obj1, cc_Distribution, &dist)
      || !convertFromPython(obj1, val, classVar)) {
    Py_DECREF(result);
    raiseError("invalid result from __call__");
  }

  Py_DECREF(result);
}



PStringList PStringList_FromArguments(PyObject *arg);

PClassifier TTreeSplitConstructor_Python::operator()(
   PStringList &descriptions, PDiscDistribution &subsetSizes, float &quality, int &spentAttribute,
   PExampleGenerator gen, const int &weightID, PDomainContingency dcont, PDistribution apriorClass, const vector<bool> &candidates, PClassifier nodeClassifier)

{ if (!gen)
    raiseError("invalid example generator");
  
  PyObject *pycandidates = PYNULL;
  if (candidates.size()) {
    pycandidates = PyList_New(candidates.size());
    int it = 0;
    const_ITERATE(vector<bool>, ci, candidates)
      PyList_SetItem(pycandidates, it++, PyInt_FromLong(*ci ? 1 : 0));
  }
  else {
    int as = gen->domain->attributes->size();
    pycandidates = PyList_New(as);
    while (as--)
      PyList_SetItem(pycandidates, as, PyInt_FromLong(1));
  }

  PyObject *args = Py_BuildValue("(NiNNNN)", WrapOrange(gen), weightID, WrapOrange(dcont), WrapOrange(apriorClass), pycandidates, WrapOrange(nodeClassifier));
  PyObject *res = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (res==Py_None) {
    Py_DECREF(res);
    return PClassifier();
  }

  PClassifier classifier;
  PyObject *pydesc = NULL;
  spentAttribute = -1;
  quality = 0.0;
  subsetSizes = PDistribution();
  if (!PyArg_ParseTuple(res, "O&|OO&fi", ccn_Classifier, &classifier, &pydesc, ccn_DiscDistribution, &subsetSizes, &quality, &spentAttribute)) {
    Py_DECREF(res);
    throw pyexception();
  }

  if (classifier && pydesc)
    if (PyOrStringList_Check(pydesc))
      descriptions = PyOrange_AsStringList(pydesc);
    else {
      descriptions = PStringList_FromArguments(pydesc);
      if (!descriptions) {
        Py_DECREF(res);
        throw pyexception();
      }
    }
  else
    descriptions = PStringList();

  Py_DECREF(res);
  return classifier;
}



PExampleGeneratorList PExampleGeneratorList_FromArguments(PyObject *args);

PExampleGeneratorList TTreeExampleSplitter_Python::operator()(PTreeNode node, PExampleGenerator gen, const int &weightID, vector<int> &newWeights)
{ if (!gen)
    raiseError("invalid example generator");
  
  PyObject *args = Py_BuildValue("(NNi)", WrapOrange(node), WrapOrange(gen), weightID);
  PyObject *res = callCallback((PyObject *)myWrapper, args);
  Py_DECREF(args);

  if (res == Py_None) {
    Py_DECREF(res);
    return PExampleGeneratorList();
  }

  PyObject *pygen;
  PyObject *pyweights = NULL;
  if (!PyArg_ParseTuple(res, "O|O", &pygen, &pyweights))
    raiseError("invalid result from __call__ (a list of list of examples and, optionally a list of weight ID's expected)");

  PExampleGeneratorList eglist = PExampleGeneratorList_FromArguments(pygen);
  if (!eglist)
    raiseError("invalid result from __call__ (a list of list of examples and, optionally a list of weight ID's expected)");

⌨️ 快捷键说明

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