📄 svm_struct_api.c
字号:
py_words = PyObject_GetAttrString(py_sv, "words"); /* Check whether this is a list of sequences or a list of numbers. */ if ((n=PySequence_Size(py_words)) > 0) { pTemp=PySequence_GetItem(py_words, 0); isNumbers = PyNumber_Check(pTemp); Py_DECREF(pTemp); } words = (WORD*)my_malloc((n+1)*(sizeof(WORD))); if (isNumbers) { /* This is a list of numbers! */ for (i=pStartingIndex; i<n; ++i) { words[i].wnum = i+1-pStartingIndex; pTemp = PySequence_GetItem(py_words, i); words[i].weight = PyFloat_AsDouble(pTemp); Py_DECREF(pTemp); } } else { PyObject *pFirst, *pSecond; /* This is a list of sequences, presumably! */ for (i=0; i<n; ++i) { pTemp=PySequence_GetItem(py_words, i); pFirst=PySequence_GetItem(pTemp, 0); pSecond=PySequence_GetItem(pTemp, 1); if (pSecond && pFirst) { words[i].wnum = PyInt_AsLong(pFirst)+1-pStartingIndex; words[i].weight = PyFloat_AsDouble(pSecond); Py_DECREF(pFirst); Py_DECREF(pSecond); } else { Py_XDECREF(pFirst); Py_XDECREF(pSecond); return NULL; } Py_DECREF(pTemp); } } words[i].wnum = words[i].weight = 0; Py_DECREF(py_words); /* Other attributes are easier, happily. Get the factor, kernel_id, and userdefined. */ pythonGetF(py_sv, "factor", &factor); pythonGetI(py_sv, "kernel_id", &kernel_id); if (PyObject_HasAttrString(py_sv, "userdefined")) { pTemp = PyObject_GetAttrString(py_sv, "userdefined"); if (!pTemp || !PyString_Check(pTemp)) { free(words); Py_XDECREF(pTemp); return NULL; } userdefined = PyString_AsString(pTemp); } /* Create the S-vector. */ sv = create_svector(words, userdefined, factor); free(words); Py_DECREF(pTemp); sv->kernel_id = kernel_id; return sv; }/* Given a Python object supposedly containing an support vector, return an SVECTOR, or NULL if an error occurred. */SVECTOR* pythonObjectToSV(PyObject *py_sv) { /* Create the Psi vector from the returned value. */ if (PySequence_Check(py_sv)) { SVECTOR *sv, *temp_sv; PyObject *pTemp = NULL; int n, i; /* It's a list of SVs. */ if ((n=PySequence_Size(py_sv))<1) { return NULL; } pTemp = PySequence_GetItem(py_sv, 0); sv = pythonObjectToSingleSV(pTemp); Py_DECREF(pTemp); if (sv == NULL) return NULL; temp_sv = sv; sv->next = NULL; for (i=1; i<n; ++i) { pTemp = PySequence_GetItem(py_sv, i); temp_sv->next = pythonObjectToSingleSV(pTemp); if (temp_sv->next == NULL) { free_svector(sv); return NULL; } Py_DECREF(pTemp); temp_sv = temp_sv->next; temp_sv->next = NULL; } return sv; } else { return pythonObjectToSingleSV(py_sv); }}/* Given a document, create an equivalent Python object. */PyObject* docToPythonObject(DOC *doc) { PyObject *py_doc, *py_svec; py_doc = pythonCreateBlank(); /* Add the feature vector. */ py_svec = svToPythonObject(doc->fvec); PyObject_SetAttrString(py_doc, "fvec", py_svec); Py_DECREF(py_svec); /* Add the other attributes. */ pythonSetI(py_doc, "docnum", doc->docnum); pythonSetI(py_doc, "slackid", doc->slackid); pythonSetF(py_doc, "costfactor", doc->costfactor); return py_doc;}/* Given a Python object supposedly containing a document, return a newly allocated document, or NULL if an error occurred. */DOC *pythonObjectToDoc(PyObject *py_doc) { DOC *doc; PyObject *py_svec; /* Variables from the document. */ SVECTOR *svec; long docnum, slackid; double costfactor; if (!PyObject_HasAttrString(py_doc, "fvec")) { /* We should at least have the feature vector. */ return NULL; } py_svec = PyObject_GetAttrString(py_doc, "fvec"); //PyObject_Print(py_svec, stdout, 0); printf("\n"); if (!py_svec || !(svec = pythonObjectToSV(py_svec)) || !svec) { return NULL; } Py_DECREF(py_svec); /* Well, we have a support vector. Try to get the rest. */ if (!pythonGetI(py_doc, "docnum", &docnum)) docnum = 0xdeadbeef; if (!pythonGetI(py_doc, "slackid", &slackid)) slackid = 0xdeadbeef; if (!pythonGetF(py_doc, "costfactor", &costfactor)) costfactor = 1.0; /* Create the document. */ doc = create_example(docnum, 0, slackid, costfactor, svec); return doc;}/* Given a sparm, this returns the python object associated with this sparm, or sets the python object associated with this sparm if none is not yet associated. */PyObject* sparmToPythonObject(STRUCT_LEARN_PARM *sparm) { PyObject *py_sparm, *argv, *argd, *obj; int i; char *lastKeyString=NULL; py_sparm = (PyObject*)sparm->py_sparm; if (!py_sparm) { /* Initialize the struct learning parameter's python object. */ sparm->py_sparm = py_sparm = pythonCreateBlank(); /* Synchronize the sparm to the object. */ pythonSetF(py_sparm, "epsilon", sparm->epsilon); pythonSetF(py_sparm, "new_const_retrain", sparm->newconstretrain); pythonSetF(py_sparm, "c", sparm->C); pythonSetI(py_sparm, "slack_norm", sparm->slack_norm); pythonSetI(py_sparm, "loss_type", sparm->loss_type); pythonSetI(py_sparm, "loss_function", sparm->loss_function); /* Don't forget the user's command line arguments! */ argd = PyDict_New(); argv = PyList_New(sparm->custom_argc); for (i=0; i<sparm->custom_argc; ++i) { obj = PyString_FromString(sparm->custom_argv[i]); if (sparm->custom_argv[i][0]=='-') { lastKeyString = sparm->custom_argv[i]+2; } else { assert(lastKeyString); PyMapping_SetItemString(argd, lastKeyString, obj); } PyList_SetItem(argv, i, obj); } PyObject_SetAttrString(py_sparm, "argv", argv); PyObject_SetAttrString(py_sparm, "argd", argd); } else { } Py_INCREF(py_sparm); return py_sparm;}PyObject* smToPythonObject(STRUCTMODEL *sm) { PyObject *py_sm, *array=NULL, *svectors, *cobject; int i, array_size[1]; py_sm = (PyObject*)sm->py_sm; if (!py_sm) { /* Initialize the structure model's python object. */ sm->py_sm = py_sm = pythonCreateBlank(); /* Synchronize the sm's unchanging fields to the object. */ pythonSetI(py_sm, "size_psi", sm->sizePsi); } /* We keep the py_sm object around in the sm structure for a while. */ Py_INCREF(py_sm); if (!sm->dirty) return py_sm; sm->dirty = 0; /* Set the pointer back to the holding sm. */ cobject = PyCObject_FromVoidPtr(sm, NULL); PyObject_SetAttrString(py_sm, "cobj", cobject); Py_DECREF(cobject); /* Set that sm.w array! */ array_size[0] = sm->sizePsi+pStartingIndex;#if defined(NUMERIC)||defined(NUMARRAY) /* Represent it as a Numeric.array. This avoids copying!! */ array = PyArray_FromDimsAndData(1, array_size, PyArray_DOUBLE, (char*)(sm->w+1-pStartingIndex));#else /* Represent it as a tuple. Unfortunately we have to copy sm.w... */ array = PyTuple_New(array_size[0]); if (sm->sizePsi > 0) { for (i=1-pStartingIndex; i<=sm->sizePsi; ++i) { PyTuple_SET_ITEM(array, i-1+pStartingIndex, PyFloat_FromDouble(sm->w[i])); } }#endif PyObject_SetAttrString(py_sm, "w", array); Py_DECREF(array); /* Set some more attributes. */ if (!sm->svm_model) { return py_sm; } /* Add the simple scalar attributes. */ pythonSetI(py_sm, "sv_num", sm->svm_model->sv_num); pythonSetI(py_sm, "at_upper_bound",sm->svm_model->at_upper_bound); pythonSetF(py_sm, "b", sm->svm_model->b); pythonSetI(py_sm, "totwords", sm->svm_model->totwords); pythonSetI(py_sm, "totdoc", sm->svm_model->totdoc); pythonSetF(py_sm, "loo_error", sm->svm_model->loo_error); pythonSetF(py_sm, "loo_recall", sm->svm_model->loo_recall); pythonSetF(py_sm, "loo_precision", sm->svm_model->loo_precision); pythonSetF(py_sm, "xa_error", sm->svm_model->xa_error); pythonSetF(py_sm, "xa_recall", sm->svm_model->xa_recall); pythonSetF(py_sm, "xa_precision", sm->svm_model->xa_precision); pythonSetF(py_sm, "maxdiff", sm->svm_model->maxdiff); /* Add the simple C scalar attributes from the kernel parameter. */ pythonSetI(py_sm, "kernel_type", sm->svm_model->kernel_parm.kernel_type); pythonSetI(py_sm, "poly_degree", sm->svm_model->kernel_parm.poly_degree); pythonSetF(py_sm, "rbf_gamma", sm->svm_model->kernel_parm.rbf_gamma); pythonSetF(py_sm, "coef_lin", sm->svm_model->kernel_parm.rbf_gamma); pythonSetF(py_sm, "coef_const", sm->svm_model->kernel_parm.coef_const); pythonSetS(py_sm, "custom", sm->svm_model->kernel_parm.custom); /* Add the alpha array. */ array_size[0] = sm->svm_model->sv_num+1; //totdoc+2;#if defined (NUMERIC)||defined(NUMARRAY) array = PyArray_FromDimsAndData(1, array_size, PyArray_DOUBLE, (char*)(sm->svm_model->alpha));#else array = PyTuple_New(array_size[0]); for (i=0; i<array_size[0]; ++i) PyTuple_SET_ITEM(array, i, PyFloat_FromDouble(sm->svm_model->alpha[i]));#endif PyObject_SetAttrString(py_sm, "alpha", array); Py_DECREF(array); /* Add the index array. */ if (sm->svm_model->index) { array_size[0] = sm->svm_model->totdoc+2;#if defined(NUMERIC)||defined(NUMARRAY) array = PyArray_FromDimsAndData(1, array_size, PyArray_LONG, (char*)(sm->svm_model->index));#else array = PyTuple_New(array_size[0]); for (i=0; i<array_size[0]; ++i) PyTuple_SET_ITEM(array, i, PyFloat_FromDouble(sm->svm_model->index[i]));#endif PyObject_SetAttrString(py_sm, "index", array); Py_DECREF(array); } else { PyObject_SetAttrString(py_sm, "index", Py_None); } /* Make the list of support vectors. */ i=sm->svm_model->sv_num-1; i = i<0 ? 0 : i; svectors = PyTuple_New(i); for (i=sm->svm_model->sv_num-2; i>=0; --i) { PyObject *sv = docToPythonObject(sm->svm_model->supvec[i+1]); //PyObject_Print(sv, stdout, 0); printf("\n"); PyTuple_SET_ITEM(svectors, i, sv); } //PyObject_Print(svectors, stdout, 0); printf("\n"); PyObject_SetAttrString(py_sm, "supvec", svectors); Py_DECREF(svectors); return py_sm;}/************* PYTHON SVM MODULE FUNCTIONS *********/static PyObject* emb_classify_example(PyObject *self, PyObject *args) { PyObject *pSm, *pSv, *cobject, *score; STRUCTMODEL *sm; DOC doc; PyArg_ParseTuple(args, "OO", &pSm, &pSv); /* Get the REAL struct model. */ if (!PyObject_HasAttrString(pSm, "cobj")) { fprintf(stderr, "First arg does not appear to be a struct model, " "or the cobj gone.\n"); Py_Exit(1); } cobject = PyObject_GetAttrString(pSm, "cobj"); if (!PyCObject_Check(cobject)) { fprintf(stderr, "The cobj attribute is not a CObject.\n"); Py_Exit(1); } sm = (STRUCTMODEL*)PyCObject_AsVoidPtr(cobject); Py_DECREF(cobject); if (!sm->svm_model) { fprintf(stderr, "Classify_example called before svm model created!\n"); // Don't fail outright ... just return 0. return PyFloat_FromDouble(0.); } /* Get the support vector. */ if (!(doc.fvec = pythonObjectToSV(pSv))) { fprintf(stderr, "Second arg does not appear to be a feature vector.\n"); Py_Exit(1); } score = PyFloat_FromDouble(classify_example(sm->svm_model, &doc)); free_svector(doc.fvec); return score;}static PyObject* emb_create_svector(PyObject *self, PyObject *args) { PyObject *words, *sv, *item; char *userdefined=""; double factor=1.0; long kernel_id=0; int i, n, isNumbers=0; if (!PyArg_ParseTuple(args,"O|sdl:create_svector", &words,&userdefined,&factor,kernel_id)) { return NULL; } sv = pythonCreateBlank(); //PyObject_SetAttrString(sv, "words", words); if ((n=PySequence_Size(words)) > 0) { item = PySequence_GetItem(words, 0); isNumbers = PyNumber_Check(item); Py_DECREF(item);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -