InvalidFeatureException in jpmml while trying to load in java - pmml

my pmml file link. generated by R-Tool
pmml file on google drive
here is my java code..
PMML model = null;
File inputFilePath = new File("/home/equation/iris_rf.pmml");
try (InputStream is = new FileInputStream(inputFilePath)) {
model = org.jpmml.model.PMMLUtil.unmarshal(is);
} catch (Exception e) {
throw e;
}
// construct a tree predictor based on the PMML
ModelEvaluator<TreeModel> modelEvaluator = new TreeModelEvaluator(model);
System.out.println(modelEvaluator.getSummary());
exception ---
Exception in thread "main" org.jpmml.evaluator.InvalidFeatureException: PMML
at org.jpmml.evaluator.ModelEvaluator.selectModel(ModelEvaluator.java:528)
at org.jpmml.evaluator.tree.TreeModelEvaluator.<init>(TreeModelEvaluator.java:64)
at com.girnarsoft.Pmml.main(Pmml.java:24)
any idea? why getting this error ?

You must instantiate org.jpmml.evaluator.ModelEvaluator subclass that matches the top-level Model element of your PMML file.
Currently, you're instantiating org.jpmml.evaluator.tree.TreeModelEvaluator, which corresponds to the TreeModel element. However, you should be instantiating org.jpmml.evaluator.mining.MiningModelEvaluator instead, as the top-level Model element in your PMML file is the MiningModel element.
In general, you should construct ModelEvaluator instances using the ModelEvaluatorFactory#newModelEvaluator(PMML) factory method.

Related

Load custom file type in Spark

I've generated a model using OpenNLP and now i want to read the model in Spark (with Scala) as an RDD then use it to predict some values.
Is there a way to load other file types in Scala other than .txt, .csv, .parquet?
Thanks.
What you you want to load is a model, not data. If the model you have built is serializable, you can define a global singleton object with the model and a function which does the prediction and use the function in a RRD map. For example:
object OpenNLPModel {
val model = //load the OpenNLP model here
def predict(s: String): String = { model.predict(s) }
}
myRdd.map(OpenNLPModel.predict)
Read the Spark programming guide for more information.
I've just found out the answer.
public DoccatModel read(String path) throws IOException {
Configuration conf = new Configuration();
//Get the filesystem - HDFS
FileSystem fs = FileSystem.get(URI.create(path), conf);
FSDataInputStream in = null;
DoccatModel model = null;
try {
//Open the path mentioned in HDFS
in = fs.open(new Path(path));
model = new DoccatModel(in);
} finally {
IOUtils.closeStream(in);
}
return model;
}
You have to use the FileSystem class to read a file from HDFS.
Cheers!

Web Api Entity Framework

I've an error: "ExceptionMessage": "Self referencing loop detected for property 'Posto' with type 'UfficioServer.Posto'. Path '[0].Dipendente[0]'.",
when i call my web api, i need a list of Posti whit the association with Dipendente...
public List<Posto> GetAllPosti()
{
try
{
List<Posto> p = new List<Posto>();
UfficioPostiEntities1 db = new UfficioPostiEntities1();
db.Configuration.ProxyCreationEnabled = false;
var posto = db.Posto.Include("Dipendente").ToList();
var x = db.Posto.ToList();
return x;
}
can someone help me?
To avoid this error you should add the following to the Application_Start in Global.asax:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter
.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
This is because (as per documentation)
ReferenceLoopHandling.Ignore: Json.NET will ignore objects in
reference loops and not serialize them. The first time an object is
encountered it will be serialized as usual but if the object is
encountered as a child object of itself the serializer will skip
serializing it.

An exception of using dozer to copy data from map to java bean

I want to copy data from map(request.getParameterMap()) to java bean. For example:
Map<String,Object> map = new HashMap<>();
map.put("payment_code", "1420956468542a2");
//...
public class PaymentLogDTO {
#Mapping("payment_code")
private String paymentCode;
//...
}
but when I execute map method in unit test,
DozerBeanMapper dozer = new DozerBeanMapper();
dozer.map(map, PaymentLogDTO.class);
it failed. The exception message is:
org.dozer.MappingException: No such field found java.util.HashMap.payment_code
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:322)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:320)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:320)
at org.dozer.util.ReflectionUtils.getFieldFromBean(ReflectionUtils.java:309)
at org.dozer.propertydescriptor.FieldPropertyDescriptor$ChainedPropertyDescriptor.<init>(FieldPropertyDescriptor.java:104)
at org.dozer.propertydescriptor.FieldPropertyDescriptor.<init>(FieldPropertyDescriptor.java:51)
at org.dozer.propertydescriptor.PropertyDescriptorFactory.getPropertyDescriptor(PropertyDescriptorFactory.java:64)
at org.dozer.fieldmap.FieldMap.getSrcPropertyDescriptor(FieldMap.java:385)
at org.dozer.fieldmap.FieldMap.getSrcFieldValue(FieldMap.java:86)
at org.dozer.MappingProcessor.mapField(MappingProcessor.java:294)
at org.dozer.MappingProcessor.map(MappingProcessor.java:267)
at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
at org.dozer.MappingProcessor.mapGeneral(MappingProcessor.java:170)
at org.dozer.MappingProcessor.map(MappingProcessor.java:104)
at org.dozer.MappingProcessor.map(MappingProcessor.java:99)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120)
at org.springside.modules.mapper.BeanMapper.map(BeanMapper.java:36)
Is there any method can solve this problem? That is I don't need to create a java bean using the same name of query paramter name as it's properties' names.
The #Mapping annotation tells the source/destination field, it has nothing related to the Map class...
So with #Mapping("payment_code"), it looks for a field "payement_code", and not for an element in your map collection.

How to use the sqoop generated class in MapReduce?

A sqoop query generates a java file that contains a class that contains the code to get access in mapreduce to the columns data for each row. (the Sqoop import was done in text without the --as-sequencefile option, and with 1 line per record and commas between the columns)
But how do we actually use it?
I found a public method parse() in this class that takes Text as an input and populates all the members of the class , so to practice I modified the wordcount application to convert a line of text from the TextInputFormat in the mapper into an instnace of the class generated by sqoop. But that causes an "unreported exception.com.cloudera.sqoop.lib.RecordParser.ParseError; must be caught or declared to be thrown" when I call the parse() method.
Can it be done this way or is a custom InputFormat necessary to populate the class with the data from each record ?
Ok this seems obvious once you find out but as a java beginner this can take time.
First configure your project:
just add the sqoop generated .java file in your source folder.
I use eclipse to import it in my class source folder.
Then just make sure you configured your project's java build path correctly:
Add the following jar files in the project's properties/java build path/libraries/add external jar:
(for hadoop cdh4+) :
/usr/lib/hadoop/hadoop-common.jar
/usr/lib/hadoop-[version]-mapreduce/hadoop-core.jar
/usr/lib/sqoop/sqoop-[sqoop-version]-cdh[cdh-version].jar
Then adapt your mapreduce source code:
First configure it:
public int run(String [] args) throws exception
{
Job job = new Job(getConf());
job.setJarByClass(YourClass.class);
job.setMapperClass(SqoopImportMap.class);
job.setReducerClass(SqoopImprtReduce.class);
FileInputFormat.addInputPath((job,"hdfs_path_to_your_sqoop_imported_file"));
FileOutputFormat.setOutputPath((job,"hdfs_output_path"));
// I simply use text as output for the mapper but it can be any class you designed
// as long as you implement it as a Writable
job.setMapOutputKeyClass(Text.Class);
job.setMapOutputValueClass(Text.Class);
job.setOutputKeyClass(Text.Class);
job.setOutputValueClass(Text.Class);
...
Now configure your mapper class.
Let's assume your sqoop imported java file is called Sqimp.java:
and the table you imported had the following columns: id, name, age
your mapper class should look like this:
public static class SqoopImportMap
extends Mapper<LongWritable, Text, Text, Text>
{
public void map(LongWritable k, Text v, Context context)
{
Sqimp s = new Sqimp();
try
{
// this is where the code generated by sqoop is used.
// it automatically casts one line of the imported data into an instance of the generated class,
// to let you access the data inside the columns easily
s.parse(v);
}
catch(ParseError pe) {// do something if there is an error.}
try
{
// now the imported data is accessible:
// e.g
if (s.age>30)
{
// submit the selected data to the mapper's output as a key value pair.
context.write(new Text(s.age),new Text(s.id));
}
}
catch(Exception ex)
{//do something about the error}
}
}

Register Ecore meta-model programmatically

I use a transformation engine to create an Ecore meta-model at runtime and I wonder how we can register that meta-model with EMF so that it can recognize the meta-model?
If you have the code generated by your metamodel:
resourceSet.getPackageRegistry()
.put(org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage.eINSTANCE.getNsURI()
, org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage.eINSTANCE);
(here for the "genmodel" metamodel)
If you only have the .ecore file:
// register globally the Ecore Resource Factory to the ".ecore" extension
// weird that we need to do this, but well...
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"ecore", new EcoreResourceFactoryImpl());
ResourceSet rs = new ResourceSetImpl();
// enable extended metadata
final ExtendedMetaData extendedMetaData = new BasicExtendedMetaData(rs.getPackageRegistry());
rs.getLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA,
extendedMetaData);
Resource r = rs.getResource(uriOfYourModel, true);
EObject eObject = r.getContents().get(0);
if (eObject instanceof EPackage) {
EPackage p = (EPackage)eObject;
rs.getPackageRegistry().put(p.getNsURI(), p);
}
You can find a bit more about this code here with the method named registerEcorePackages(), used to register .ecore file in the workspace (with their workspace fullpath) in our custom package registry. If you want to register your metamodel in EMF global package registry, replace resourceSet.getPackageRegistry() by EPackage.Registry.INSTANCE.
I had to modify the code from #sbegaudeau a bit for it to work:
Replace
rs.getPackageRegistry().put(p.getNsURI(), p);
with
EPackage.Registry.INSTANCE.put(p.getNsURI(), p);
Also, somehow I cannot register the .ecore type. Had to use "*": Resource.Factory.Registry.INSTANCE.
getExtensionToFactoryMap().put("*", new EcoreResourceFactoryImpl());