Greetings again,
Perhaps a good example would be a real one. I'm starting with some simple functions, such as obtaining the model name, algorithm, etc, from the attached XML example. Can anyone provide an exemplary method for doing this? Below is my naive attempt, which are all failing miserably:
(defun algorithm-name (model) "Returns the algorithm for the model" (stp:filter-recursively (stp:of-name "algorithmName" (stp:namespace-uri model)) model))
I know this one will (if it were working) return a list, but since I can't get past the namespace problem haven't bothered to go any further. That function, I assume, is a rather trivial one for someone with some good examples or knowledge to work from. Here's a slightly more difficult function:
(defun model-coefficient-list (model) "Returns a nested list of the following structure: (<model-name>-coefficients (coefficient1 coefficient1-value) (coefficient1 coefficient2-value) ... (coefficientn coefficientn-value))" ...)
Something like this would be good to put on the STP website.
Regards, - Steve
On Jun 11, 2012, at 05:50 , Steven Nunez wrote:
(defun algorithm-name (model) "Returns the algorithm for the model" (stp:filter-recursively (stp:of-name "algorithmName" (stp:namespace-uri model)) model))
I'd do something like the following:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun algorithm-name (model) (xpath:with-namespaces ((nil "http://www.dmg.org/PMML-4_0")) (xpath:string-value (xpath:evaluate "//RegressionModel/@algorithmName" model))))
(defun model-coefficient-list (model) (xpath:with-namespaces ((nil "http://www.dmg.org/PMML-4_0")) (let ((regression-model-node (xpath:first-node (xpath:evaluate "//RegressionModel" model))) (*read-eval* nil)) `(,(xpath:string-value (xpath:evaluate "@modelName" regression-model-node)) ,@(xpath:map-node-set->list (lambda (node) (list (xpath:string-value (xpath:evaluate "@name" node)) ;; note: xpath:number-value may work here, depending on ;; your implementation... does not work with Lispworks ;; 6.1 under Mac OS X (read-from-string (xpath:string-value (xpath:evaluate "@coefficient" node))))) (xpath:evaluate "RegressionTable/NumericPredictor" regression-model-node))))))
#|| (defparameter *model* (cxml:parse #p"/Users/raw/Desktop/polynomial-regression.xml" (cxml-stp:make-builder)))
(cxml-stp:serialize *model* (cxml:make-string-sink :indentation 4))
(algorithm-name *model*)
(model-coefficient-list *model*) ||# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Notes:
1) I'm not sure that model-coefficient-list does what you need.
2) It might be appropriate to use cxml-stp:attribute-value instead of xpath:string-value/xpath:evaluate.
3) Since there are multiple coefficients with the same name (where some have an "exponent" attribute), I guess you'd either need to filter out some of the coefficients, build names that somehow incorporate the exponent, or add the exponent to the list structure returned.
Hope this helps.
Hi Ray,
Thanks. It does seems easier with xpath. Perhaps it's my stubbornness that keeps me hammering away at cxml-stp. If no one comes up with a good example for STP, I think I'll take the path of least resistance and do as you suggest.
Cheers, - Steve
________________________________ From: Raymond Wiker rwiker@gmail.com To: Steven Nunez steve_nunez@yahoo.com Cc: "cxml-devel@common-lisp.net" cxml-devel@common-lisp.net Sent: Monday, June 11, 2012 5:14 PM Subject: Re: [cxml-devel] Real-world example: with attachment
On Jun 11, 2012, at 05:50 , Steven Nunez wrote: (defun algorithm-name (model)
"Returns the algorithm for the model" (stp:filter-recursively (stp:of-name "algorithmName" (stp:namespace-uri model)) model))
I'd do something like the following:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun algorithm-name (model) (xpath:with-namespaces ((nil "http://www.dmg.org/PMML-4_0")) (xpath:string-value (xpath:evaluate "//RegressionModel/@algorithmName" model))))
(defun model-coefficient-list (model) (xpath:with-namespaces ((nil "http://www.dmg.org/PMML-4_0")) (let ((regression-model-node (xpath:first-node (xpath:evaluate "//RegressionModel" model))) (*read-eval* nil)) `(,(xpath:string-value (xpath:evaluate "@modelName" regression-model-node)) ,@(xpath:map-node-set->list (lambda (node) (list (xpath:string-value (xpath:evaluate "@name" node)) ;; note: xpath:number-value may work here, depending on ;; your implementation... does not work with Lispworks ;; 6.1 under Mac OS X (read-from-string (xpath:string-value (xpath:evaluate "@coefficient" node))))) (xpath:evaluate "RegressionTable/NumericPredictor" regression-model-node))))))
#|| (defparameter *model* (cxml:parse #p"/Users/raw/Desktop/polynomial-regression.xml" (cxml-stp:make-builder)))
(cxml-stp:serialize *model* (cxml:make-string-sink :indentation 4))
(algorithm-name *model*)
(model-coefficient-list *model*) ||# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Notes:
1) I'm not sure that model-coefficient-list does what you need.
2) It might be appropriate to use cxml-stp:attribute-value instead of xpath:string-value/xpath:evaluate.
3) Since there are multiple coefficients with the same name (where some have an "exponent" attribute), I guess you'd either need to filter out some of the coefficients, build names that somehow incorporate the exponent, or add the exponent to the list structure returned.
Hope this helps.