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

📄 corn.cpp

📁 orange源码 数据挖掘技术
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  float C, D, T;
  TCDT()
  : C(0.0),
    D(0.0),
    T(0.0)
  {}
};

void C_computeCDT(const vector<TCummulativeROC> &cummlists, vector<TCDT> &cdts)
{
  cdts = vector<TCDT>(cummlists.size());
  
  vector<TCDT>::iterator cdti (cdts.begin());
  for (vector<TCummulativeROC>::const_iterator ci(cummlists.begin()), ce(cummlists.end()); ci!=ce; ci++, cdti++) {
    pp low;
    for (map<float, pp>::const_iterator cri((*ci).begin()), cre((*ci).end()); cri!=cre; cri++) {
      const pp &thi = (*cri).second;
      (*cdti).C += low.normal   * thi.abnormal;
      (*cdti).D += low.abnormal * thi.normal;
      (*cdti).T += thi.normal   * thi.abnormal;
      low += thi;
    }
  }
}


PyObject *py_ROCCumulativeList(vector<TCummulativeROC> &cummlists, pp &totals)
{
  PyObject *pyresults = PyList_New(cummlists.size());
  int lrn = 0;
  ITERATE(vector<TCummulativeROC>, ci, cummlists) {
    PyObject *pclist = PyList_New((*ci).size());
    int prb = 0;
    ITERATE(TCummulativeROC, si, *ci)
      PyList_SetItem(pclist, prb++, Py_BuildValue("f(ff)", (*si).first, (*si).second.normal, (*si).second.abnormal));
    PyList_SetItem(pyresults, lrn++, pclist);
  }

  return Py_BuildValue("N(ff)", pyresults, totals.normal, totals.abnormal);
}


PyObject *py_computeROCCumulative(PyObject *, PyObject *arg)
{ 
  PyTRY
    PyObject *pyresults;
    int classIndex = -1;
    PyObject *pyuseweights = NULL;
    if (!PyArg_ParseTuple(arg, "O|iO", &pyresults, &classIndex, &pyuseweights))
      PYERROR(PyExc_TypeError, "computeROCCummulative: results and optionally the classIndex and 'useWeights' flag expected", PYNULL);

    bool useweights = pyuseweights && PyObject_IsTrue(pyuseweights)!=0;

    ExperimentResults results(pyresults);
    if (results.numberOfIterations>1)
      PYERROR(PyExc_SystemError, "computeCDT: cannot compute CDT for experiments with multiple iterations", PYNULL);


    pp totals;
    vector<TCummulativeROC> cummlists;
    C_computeROCCumulative(results, classIndex, totals, cummlists, useweights);
    return py_ROCCumulativeList(cummlists, totals);
  PyCATCH
}


PyObject *py_computeROCCumulativePair(PyObject *, PyObject *arg)
{ 
  PyTRY
    PyObject *pyresults;
    int classIndex1, classIndex2;
    PyObject *pyuseweights = NULL;
    if (!PyArg_ParseTuple(arg, "Oii|O", &pyresults, &classIndex1, &classIndex2, &pyuseweights))
      PYERROR(PyExc_TypeError, "computeROCCummulative: results and classIndices, and optional 'useWeights' flag expected", PYNULL);

    bool useweights = pyuseweights && PyObject_IsTrue(pyuseweights)!=0;

    ExperimentResults results(pyresults);
    if (results.numberOfIterations>1)
      PYERROR(PyExc_SystemError, "computeCDT: cannot compute CDT for experiments with multiple iterations", PYNULL);


    pp totals;
    vector<TCummulativeROC> cummlists;
    C_computeROCCumulativePair(results, classIndex1, classIndex2, totals, cummlists, useweights);
    return py_ROCCumulativeList(cummlists, totals);
  PyCATCH
}


PyObject *computeCDTList(vector<TCummulativeROC> &cummlists)
{
  PyObject *res = NULL, *orngStatModule = NULL;

  try {
    vector<TCDT> cdts;
    C_computeCDT(cummlists, cdts);

    PyObject *orngStatModule = PyImport_ImportModule("orngStat");
    if (!orngStatModule)
      return PYNULL;

    // PyModule_GetDict and PyDict_GetItemString return borrowed references
    PyObject *orngStatModuleDict = PyModule_GetDict(orngStatModule);
    Py_DECREF(orngStatModule);
    orngStatModule = NULL;

    PyObject *CDTType = PyDict_GetItemString(orngStatModuleDict, "CDT");

    if (!CDTType)
      PYERROR(PyExc_AttributeError, "orngStat does not define CDT class", PYNULL);

    PyObject *res = PyList_New(cdts.size());
    int i = 0;
    ITERATE(vector<TCDT>, cdti, cdts) {
      PyObject *inargs = Py_BuildValue("fff", (*cdti).C, (*cdti).D, (*cdti).T);
      PyObject *indict = PyDict_New();
      PyObject *PyCDT = PyInstance_New(CDTType, inargs, indict);
      Py_DECREF(inargs);
      Py_DECREF(indict);

      if (!PyCDT) {
        Py_XDECREF(res);
        return PYNULL;
      }
      PyList_SetItem(res, i++, PyCDT);
    }

    return res;
  }
  catch (...) {
    Py_XDECREF(res);
    Py_XDECREF(orngStatModule);
    throw;
  }
}


PyObject *py_computeCDT(PyObject *, PyObject *arg)
{
  PyTRY
    PyObject *pyresults;
    int classIndex = -1;
    PyObject *pyuseweights = PYNULL;
    if (!PyArg_ParseTuple(arg, "O|iO", &pyresults, &classIndex, &pyuseweights))
      PYERROR(PyExc_TypeError, "computeROCCummulative: results and optionally the classIndex expected", PYNULL);

    bool useweights = pyuseweights && PyObject_IsTrue(pyuseweights)!=0;

    ExperimentResults results(pyresults);

    pp totals;
    vector<TCummulativeROC> cummlists;
    C_computeROCCumulative(results, classIndex, totals, cummlists, useweights);

    return computeCDTList(cummlists);
  PyCATCH
}


PyObject *py_computeCDTPair(PyObject *, PyObject *arg)
{
  PyTRY
    PyObject *pyresults;
    int classIndex1, classIndex2;
    PyObject *pyuseweights = PYNULL;
    if (!PyArg_ParseTuple(arg, "Oii|O", &pyresults, &classIndex1, &classIndex2, &pyuseweights))
      PYERROR(PyExc_TypeError, "computeROCCummulative: results, two class indices and optional flag for using weights", PYNULL);

    bool useweights = pyuseweights && PyObject_IsTrue(pyuseweights)!=0;

    ExperimentResults results(pyresults);

    pp totals;
    vector<TCummulativeROC> cummlists;
    C_computeROCCumulativePair(results, classIndex1, classIndex2, totals, cummlists, useweights);

    return computeCDTList(cummlists);
  PyCATCH
}


PyObject *py_compare2ROCs(PyObject *, PyObject *arg)
{ PyTRY
    PyObject *pyresults;
    int roc1, roc2, classIndex = -1;
    PyObject *pyuseweights;
    if (!PyArg_ParseTuple(arg, "OiiiO", &pyresults, &roc1, &roc2, &classIndex, &pyuseweights))
      PYERROR(PyExc_TypeError, "compare2ROCs: results and two integer indices (optionally also classIndex) expected", PYNULL);

    bool useweights = PyObject_IsTrue(pyuseweights)!=0;
    if (useweights)
      PYERROR(PyExc_SystemError, "compare2ROCs: cannot use weights (weights not implemented yet)", PYNULL);

    ExperimentResults results(pyresults);
    if (results.numberOfIterations>1)
      PYERROR(PyExc_SystemError, "computeCDT: cannot compute CDT for experiments with multiple iterations", PYNULL);

    if (classIndex<0)
      classIndex = results.baseClass;
    if (classIndex<0)
      classIndex = 1;

    float e11[] = {0, 0}, e10[] = {0, 0}, e01[] = {0, 0};
    float e11r = 0, e10r = 0, e01r = 0;
    float th[] ={0, 0};
    int m = 0, n = 0;
    /* m is number of examples with class == classIndex, n are others
       X_* represent example with class == classIndex, Y_* are others
    */

    for (vector<TestedExample>::const_iterator i(results.results.begin()), e(results.results.end()); i!=e; i++)
      if ((*i).actualClass != classIndex) {
        n++;
      }
      else { // (*i).actualClass == classIndex
        m++;

        float X_i[] = {(*i).probabilities[roc1][classIndex], (*i).probabilities[roc2][classIndex]};

        for (vector<TestedExample>::const_iterator j = i+1; j!=e; j++)
          if ((*j).actualClass!=classIndex) {

            float Y_j[] = {(*j).probabilities[roc1][classIndex], (*j).probabilities[roc2][classIndex]};
            float diffs[] = { diff2(X_i[0], Y_j[0]), diff2(X_i[1], Y_j[1]) };

            th[0] += diffs[0];
            th[1] += diffs[1];

            e11[0] += sqr(diffs[0]);
            e11[1] += sqr(diffs[1]);
            e11r   += diffs[0]*diffs[1];

            for (vector<TestedExample>::const_iterator k = j+1; k!=e; k++)
              if ((*k).actualClass == classIndex) { // B_XXY
                float X_k[] = { (*k).probabilities[roc1][classIndex], (*k).probabilities[roc2][classIndex] };
                float diffsk[] = { diff2(X_k[0], Y_j[0]), diff2(X_k[1], Y_j[1]) };
                e01[0] += diffs[0]*diffsk[0];
                e01[1] += diffs[1]*diffsk[1];
                e01r   += diffs[0]*diffsk[1] + diffs[1]*diffsk[0];
              }
              else { // B_XYY
                float Y_k[] = { (*k).probabilities[roc1][classIndex], (*k).probabilities[roc2][classIndex] };
                float diffsk[] = { diff2(X_i[0], Y_k[0]), diff2(X_i[1], Y_k[1]) };
                e10[0] += diffs[0]*diffsk[0];
                e10[1] += diffs[1]*diffsk[1];
                e10r   += diffs[0]*diffsk[1] + diffs[1]*diffsk[0];
              }
          }
      }

    float n11 = float(m)*float(n), n01 = float(m)*float(n)*float(m-1)/2.0, n10 = float(m)*float(n)*float(n-1)/2.0;
  
    th[0] /= n11;
    th[1] /= n11;
    
    e11[0] = e11[0]/n11 - sqr(th[0]);
    e11[1] = e11[1]/n11 - sqr(th[1]);
    e11r   = e11r  /n11 - th[0]*th[1];

    e10[0] = e10[0]/n10 - sqr(th[0]);
    e10[1] = e10[1]/n10 - sqr(th[1]);
    e10r   = e10r  /n10 - th[0]*th[1];

    e01[0] = e01[0]/n01 - sqr(th[0]);
    e01[1] = e01[1]/n01 - sqr(th[1]);
    e01r   = e01r  /n01 - th[0]*th[1];

    float var[] = { ((n-1)*e10[0] + (m-1)*e01[0] + e11[0])/n11, ((n-1)*e10[1] + (m-1)*e01[1] + e11[1])/n11};
    float SE[]  = { sqrt(var[0]), sqrt(var[1]) };

    float covar = ((n-1)*e10r + (m-1)*e01r + e11r) / n11;
    float SEr   = sqrt(var[0]+var[1]-2*covar*SE[0]*SE[1]);

    return Py_BuildValue("(ff)(ff)(ff)", th[0], SE[0], th[1], SE[1], th[0]-th[1], SEr);
  PyCATCH
}


inline float cmphalf(const float &x, const float &y)
{
  if (x<y)   return 0;
  if (x==y)  return 0.25;
  return 0.5;
}

PyObject *py_mAUC(PyObject *, PyObject *arg)
{ PyTRY
    PyObject *pyresults;
    PyObject *pyuseweights = PYNULL;
    if (!PyArg_ParseTuple(arg, "O|O:corn.mAUC", &pyresults, &pyuseweights))
      PYERROR(PyExc_TypeError, "mAUC: results and optionally use weights flag expected", PYNULL);

    bool useweights = pyuseweights && (PyObject_IsTrue(pyuseweights)!=0);
    if (useweights)
      PYERROR(PyExc_SystemError, "mAUC: cannot use weights (weights not implemented yet)", PYNULL);

    ExperimentResults results(pyresults);
/*    if (results.numberOfIterations>1)
      PYERROR(PyExc_SystemError, "mAUC: cannot compute CDT for experiments with multiple iterations", PYNULL);
*/

    const int nLearners = results.numberOfLearners;
    vector<float> correctPairs(nLearners, 0.0);
    int usefulPairs = 0;

    for (vector<TestedExample>::const_iterator i1(results.results.begin()), e(results.results.end()); i1!=e; i1++)
      for (vector<TestedExample>::const_iterator i2(i1); i2!=e; i2++) {
        const int cls1 = (*i1).actualClass;
        const int cls2 = (*i2).actualClass;
        if (cls1 != cls2) {
          usefulPairs++;
          vector<float>::iterator cpi(correctPairs.begin());
          vector<vector<float> >::const_iterator ep1i((*i1).probabilities.begin()), ep2i((*i2).probabilities.begin());
          for(int cfr = nLearners; cfr--; cpi++, ep1i++, ep2i++)
            *cpi +=  cmphalf((*ep1i)[cls1], (*ep2i)[cls1])
                   + cmphalf((*ep2i)[cls2], (*ep1i)[cls2]);
        }
      }

    PyObject *res = PyList_New(nLearners);
    for(int cfr = 0; cfr<nLearners; cfr++)
      PyList_SetItem(res, cfr, PyFloat_FromDouble(correctPairs[cfr]/usefulPairs));
    return res;
  PyCATCH
}

/* *********** AUXILIARY ROUTINES *************/

class CompCallbackLess {
public:
  PyObject *py_compare;

  CompCallbackLess(PyObject *apyc)
    : py_compare(apyc)
    { Py_XINCREF(apyc); }

  ~CompCallbackLess()
    { Py_XDECREF(py_compare); }

  int operator()(PyObject *obj1, PyObject *obj2)
    { PyObject *args = Py_BuildValue("OO", obj1, obj2);
      PyObject *result = PyEval_CallObject(py_compare, args);
      Py_DECREF(args);

      if (!result) 
        throw pyexception();

      bool res = PyInt_AsLong(result)<0;
      Py_DECREF(result);
      return res;
    }
};


class CompCallbackEqual {
public:
  PyObject *py_compare;

  CompCallbackEqual(PyObject *apyc)
    : py_compare(apyc)
    { Py_XINCREF(apyc); }

  ~CompCallbackEqual()
    { Py_XDECREF(py_compare); }

  int operator()(PyObject *obj1, PyObject *obj2)
    { PyObject *args = Py_BuildValue("OO", obj1, obj2);
      PyObject *result = PyEval_CallObject(py_compare, args);
      Py_DECREF(args);

      if (!result) 
        throw pyexception();

      bool res = (PyInt_AsLong(result)==0);
      Py_DECREF(result);
      return res;
    }
};

    

/* *********** EXPORT DECLARATIONS ************/

#define DECLARE(name) \
 {#name, (binaryfunc)py_##name, METH_VARARGS},

PyMethodDef corn_functions[] = {
     DECLARE(compare2ROCs)
     DECLARE(computeROCCumulative)
     DECLARE(computeROCCumulativePair)
     DECLARE(computeCDT)
     DECLARE(computeCDTPair)
     DECLARE(mAUC)


     {NULL, NULL}
};

#undef DECLARE

#undef PyTRY
#undef PyCATCH
#undef PYNULL

⌨️ 快捷键说明

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