Commit 82807fc9 authored by Bruno López Trigo's avatar Bruno López Trigo

Comezada actualización de configuración de experto desde interface

parent 466aad85
......@@ -248,10 +248,23 @@ public class ClassifierManagerImpl implements ClassifierManager {
@Override
public NumericAttribute updateAttributeConfig(String token, String dataset, String attribute, NumericAttribute attributeConfig, String lang) throws NotFoundEx, IOException, FormatEx {
File configFileEn, configFileEs, configFileGl;
File configFileEn, configFileEs, configFileGl,
treeFileJ48 = null, treeFileREPTree = null, treeFileRandomTree = null,
logJ48 = null, logREPTree = null, logRandomTree = null;
DatasetConfig configEn, configEs, configGl;
NumericAttribute attEn, attEs, attGl;
try {
treeFileJ48 = this.fmanager.getTree(token, dataset, "J48");
logJ48 = this.fmanager.getLog(token, dataset, "J48");
treeFileREPTree = this.fmanager.getTree(token, dataset, "REPTree");
logREPTree = this.fmanager.getLog(token, dataset, "REPTree");
treeFileRandomTree = this.fmanager.getTree(token, dataset, "RandomTree");
logRandomTree = this.fmanager.getLog(token, dataset, "RandomTree");
} catch (NotFoundEx ex) {
}
configFileEn = this.fmanager.getConfig(token, dataset, "en");
configFileEs = this.fmanager.getConfig(token, dataset, "es");
configFileGl = this.fmanager.getConfig(token, dataset, "gl");
......@@ -340,16 +353,43 @@ public class ClassifierManagerImpl implements ClassifierManager {
throw new FormatEx("Invalid language " + lang + " provided");
}
try {
if (logJ48 != null && treeFileJ48 != null) {
this.treeBuilder = new TreeBuilder(logJ48, configFileEn, treeFileJ48);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logREPTree, configFileEn, treeFileREPTree);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logRandomTree, configFileEn, treeFileRandomTree);
this.treeBuilder.buildTree(true);
}
} catch (ConflictEx ex) {
throw new IOException();
}
return attributeConfig;
}
@Override
public NumericAttribute updateAttributeConfig(String token, String dataset, String attribute, NumericProperty property, String lang) throws NotFoundEx, IOException, FormatEx {
File configFileEn, configFileEs, configFileGl;
File configFileEn, configFileEs, configFileGl, treeFileJ48 = null, treeFileREPTree = null, treeFileRandomTree = null, logJ48 = null, logREPTree = null, logRandomTree = null;
DatasetConfig configEn, configEs, configGl;
NumericAttribute attEn, attEs, attGl;
try {
treeFileJ48 = this.fmanager.getTree(token, dataset, "J48");
logJ48 = this.fmanager.getLog(token, dataset, "J48");
treeFileREPTree = this.fmanager.getTree(token, dataset, "REPTree");
logREPTree = this.fmanager.getLog(token, dataset, "REPTree");
treeFileRandomTree = this.fmanager.getTree(token, dataset, "RandomTree");
logRandomTree = this.fmanager.getLog(token, dataset, "RandomTree");
} catch (NotFoundEx ex) {
}
configFileEn = this.fmanager.getConfig(token, dataset, "en");
configFileEs = this.fmanager.getConfig(token, dataset, "es");
configFileGl = this.fmanager.getConfig(token, dataset, "gl");
......@@ -386,6 +426,23 @@ public class ClassifierManagerImpl implements ClassifierManager {
attGl.getProperties().add(property);
this.mapper.writeJSON(configGl, configFileGl);
try {
if (logJ48 != null && treeFileJ48 != null) {
this.treeBuilder = new TreeBuilder(logJ48, configFileEn, treeFileJ48);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logREPTree, configFileEn, treeFileREPTree);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logRandomTree, configFileEn, treeFileRandomTree);
this.treeBuilder.buildTree(true);
}
} catch (ConflictEx ex) {
throw new IOException();
}
switch (lang) {
case "en":
return attEn;
......@@ -396,19 +453,30 @@ public class ClassifierManagerImpl implements ClassifierManager {
default:
throw new FormatEx("Invalid language " + lang + " provided");
}
}
@Override
public Property removePropertyConfig(String token, String dataset, String attribute, int property, String lang) throws NotFoundEx, IOException, FormatEx, NotAllowedEx {
File configFileEn, configFileEs, configFileGl;
File configFileEn, configFileEs, configFileGl, treeFileJ48 = null, treeFileREPTree = null, treeFileRandomTree = null, logJ48 = null, logREPTree = null, logRandomTree = null;
DatasetConfig configEn, configEs, configGl;
Attribute attEn, attEs, attGl;
try {
treeFileJ48 = this.fmanager.getTree(token, dataset, "J48");
logJ48 = this.fmanager.getLog(token, dataset, "J48");
treeFileREPTree = this.fmanager.getTree(token, dataset, "REPTree");
logREPTree = this.fmanager.getLog(token, dataset, "REPTree");
treeFileRandomTree = this.fmanager.getTree(token, dataset, "RandomTree");
logRandomTree = this.fmanager.getLog(token, dataset, "RandomTree");
} catch (NotFoundEx ex) {
}
configFileEn = this.fmanager.getConfig(token, dataset, "en");
configFileEs = this.fmanager.getConfig(token, dataset, "es");
configFileGl = this.fmanager.getConfig(token, dataset, "gl");
configEn = this.mapper.readConfigJSON(configFileEn);
configEs = this.mapper.readConfigJSON(configFileEs);
configGl = this.mapper.readConfigJSON(configFileGl);
......@@ -416,14 +484,14 @@ public class ClassifierManagerImpl implements ClassifierManager {
attEn = configEn.getAttributeById(attribute);
attEs = configEs.getAttributeById(attribute);
attGl = configGl.getAttributeById(attribute);
Property propEn, propEs, propGl;
if (attEn != null) {
propEn = attEn.getPropertyById(property);
propEs = attEs.getPropertyById(property);
propGl = attGl.getPropertyById(property);
if (propEn != null) {
if (attEn.getProperties().size() == 1) {
throw new NotAllowedEx("Cannot remove property " + property + ": attribute needs at least one property");
......@@ -458,16 +526,33 @@ public class ClassifierManagerImpl implements ClassifierManager {
((NumericProperty) attEs.getProperties().get(i)).setId(i - 1);
((NumericProperty) attGl.getProperties().get(i)).setId(i - 1);
}
attEn.getProperties().remove(property);
attEs.getProperties().remove(property);
attGl.getProperties().remove(property);
this.mapper.writeJSON(configEn, configFileEn);
this.mapper.writeJSON(configEs, configFileEs);
this.mapper.writeJSON(configGl, configFileGl);
switch(lang){
try {
if (logJ48 != null && treeFileJ48 != null) {
this.treeBuilder = new TreeBuilder(logJ48, configFileEn, treeFileJ48);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logREPTree, configFileEn, treeFileREPTree);
this.treeBuilder.buildTree(true);
}
if (logREPTree != null && treeFileREPTree != null) {
this.treeBuilder = new TreeBuilder(logRandomTree, configFileEn, treeFileRandomTree);
this.treeBuilder.buildTree(true);
}
} catch (ConflictEx ex) {
throw new IOException();
}
switch (lang) {
case "en":
return propEn;
case "es":
......@@ -477,7 +562,7 @@ public class ClassifierManagerImpl implements ClassifierManager {
default:
throw new FormatEx("Invalid language " + lang + " provided");
}
} else {
throw new NotFoundEx("Property " + property + " was not found");
}
......
......@@ -42,7 +42,7 @@ public class FormatChecker {
printWriter.println(line.split("'")[0] + "'" + newAtt + "'" + line.split("'" + newAtt + "'")[1]);
}
else if(!line.endsWith("}")){
att = line.split(" ")[1];
att = line.split("\\s+")[1];
newAtt = att.replaceAll("[ !#$%&\\()*+,./:;<=>?@\\[\\]^`{|}~`]", "-");
printWriter.println(line.split(" ")[0] + " " + newAtt + " " + line.split(newAtt)[1]);
}
......@@ -52,7 +52,7 @@ public class FormatChecker {
printWriter.println(line.split("'")[0] + "'" + newAtt + "' " + line.split("'" + newAtt + "'")[1]);
}
else {
att = line.split(" ")[1];
att = line.split("\\s+")[1];
newAtt = att.replaceAll("[ !#$%&\\()*+,./:;<=>?@\\[\\]^`{|}~`]", "-");
printWriter.println(line.split(" ")[0] + " " + newAtt + " " + line.split(newAtt)[1]);
}
......
......@@ -12,6 +12,9 @@ public class CategoricNode extends Node {
private Attribute attribute;
private HashMap<String, Node> children;
public CategoricNode() {
}
public CategoricNode(Attribute attribute) {
this.attribute = attribute;
this.children = new HashMap();
......
......@@ -254,8 +254,8 @@ public class ClassifierService {
}
@Operation(
summary = "Get property from specific attribute",
description = "Get property from specific attribute",
summary = "Get property from specific numeric attribute",
description = "Get property from specific numeric attribute",
responses = {
@ApiResponse(
responseCode = "200",
......@@ -290,7 +290,7 @@ public class ClassifierService {
)
@SecurityRequirement(name = "token")
@GET
@Path("/config/{dataset}/attribute/{attribute}/{property}")
@Path("/config/{dataset}/numattribute/{attribute}/{property}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getClassifierConfigProperty(@Context HttpHeaders httpheaders,
......@@ -324,8 +324,8 @@ public class ClassifierService {
}
@Operation(
summary = "Delete property from specific attribute",
description = "Delete property from specific attribute",
summary = "Delete property from specific numeric attribute",
description = "Delete property from specific numeric attribute",
responses = {
@ApiResponse(
responseCode = "200",
......@@ -374,7 +374,7 @@ public class ClassifierService {
)
@SecurityRequirement(name = "token")
@DELETE
@Path("/config/{dataset}/attribute/{attribute}/{property}")
@Path("/config/{dataset}/numattribute/{attribute}/{property}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@TokenNeeded
......@@ -409,8 +409,8 @@ public class ClassifierService {
}
@Operation(
summary = "Update attribute config",
description = "Update attribute config by modifying names or intervals",
summary = "Update attribute numeric config",
description = "Update numeric attribute config by modifying names or intervals",
responses = {
@ApiResponse(
responseCode = "200",
......@@ -452,7 +452,7 @@ public class ClassifierService {
)
@SecurityRequirement(name = "token")
@PUT
@Path("/config/{dataset}/attribute/{attribute}")
@Path("/config/{dataset}/numattribute/{attribute}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@TokenNeeded
......@@ -485,8 +485,8 @@ public class ClassifierService {
}
@Operation(
summary = "Add new property to attribute",
description = "Add new property to attribute at the end of properties list",
summary = "Add new property to numeric attribute",
description = "Add new property to numeric attribute at the end of properties list",
responses = {
@ApiResponse(
responseCode = "201",
......@@ -528,7 +528,7 @@ public class ClassifierService {
)
@SecurityRequirement(name = "token")
@POST
@Path("/config/{dataset}/attribute/{attribute}")
@Path("/config/{dataset}/numattribute/{attribute}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@TokenNeeded
......
=== Run information ===
Scheme: trees.J48 -C 0.25 -M 2
Relation: iris
Instances: 150
Attributes: 5
sepallength
sepalwidth
petallength
petalwidth
class
Test mode: 10-fold cross-validation
=== Classifier model (full training set) ===
J48 pruned tree
------------------
petalwidth <= 0.6: Iris-setosa (50.0)
petalwidth > 0.6
| petalwidth <= 1.7
| | petallength <= 4.9: Iris-versicolor (48.0/1.0)
| | petallength > 4.9
| | | petalwidth <= 1.5: Iris-virginica (3.0)
| | | petalwidth > 1.5: Iris-versicolor (3.0/1.0)
| petalwidth > 1.7: Iris-virginica (46.0/1.0)
Number of Leaves : 5
Size of the tree : 9
=== Summary ===
Correctly Classified Instances 144 96 %
Incorrectly Classified Instances 6 4 %
Kappa statistic 0.94
K&B Relative Info Score 14004.9837 %
K&B Information Score 221.9737 bits 1.4798 bits/instance
Class complexity | order 0 237.7444 bits 1.585 bits/instance
Class complexity | scheme 3238.3794 bits 21.5892 bits/instance
Complexity improvement (Sf) -3000.6351 bits -20.0042 bits/instance
Mean absolute error 0.035
Root mean squared error 0.1586
Relative absolute error 7.8705 %
Root relative squared error 33.6353 %
Total Number of Instances 150
=== Confusion Matrix ===
a b c <-- classified as
49 1 0 | a = Iris-setosa
0 47 3 | b = Iris-versicolor
0 2 48 | c = Iris-virginica
{
"type" : "numericNode",
"attribute" : {
"type" : "numericAtt",
"id" : "petalwidth",
"name" : "petalwidth",
"properties" : [ {
"type" : "numericProp",
"name" : "Low",
"id" : 0,
"interval" : {
"left" : 0.1,
"right" : 0.8999999999999999
}
}, {
"type" : "numericProp",
"name" : "Medium",
"id" : 1,
"interval" : {
"left" : 0.8999999999999999,
"right" : 1.7
}
}, {
"type" : "numericProp",
"name" : "High",
"id" : 2,
"interval" : {
"left" : 1.7,
"right" : 2.5
}
} ],
"interval" : {
"left" : 0.1,
"right" : 2.5
},
"value" : 0.0
},
"splitValue" : 0.6,
"comparisonSymbol" : "<=",
"leftChild" : {
"type" : "consequentNode",
"consequent" : {
"matrixPosition" : 1,
"id" : "Iris-setosa",
"name" : "Iris-setosa",
"percentageNode" : 100.0
}
},
"rightChild" : {
"type" : "numericNode",
"attribute" : {
"type" : "numericAtt",
"id" : "petalwidth",
"name" : "petalwidth",
"properties" : [ {
"type" : "numericProp",
"name" : "Low",
"id" : 0,
"interval" : {
"left" : 0.1,
"right" : 0.8999999999999999
}
}, {
"type" : "numericProp",
"name" : "Medium",
"id" : 1,
"interval" : {
"left" : 0.8999999999999999,
"right" : 1.7
}
}, {
"type" : "numericProp",
"name" : "High",
"id" : 2,
"interval" : {
"left" : 1.7,
"right" : 2.5
}
} ],
"interval" : {
"left" : 0.1,
"right" : 2.5
},
"value" : 0.0
},
"splitValue" : 1.7,
"comparisonSymbol" : "<=",
"leftChild" : {
"type" : "numericNode",
"attribute" : {
"type" : "numericAtt",
"id" : "petallength",
"name" : "petallength",
"properties" : [ {
"type" : "numericProp",
"name" : "Low",
"id" : 0,
"interval" : {
"left" : 1.0,
"right" : 2.966666666666667
}
}, {
"type" : "numericProp",
"name" : "Medium",
"id" : 1,
"interval" : {
"left" : 2.966666666666667,
"right" : 4.933333333333334
}
}, {
"type" : "numericProp",
"name" : "High",
"id" : 2,
"interval" : {
"left" : 4.933333333333334,
"right" : 6.9
}
} ],
"interval" : {
"left" : 1.0,
"right" : 6.9
},
"value" : 0.0
},
"splitValue" : 4.9,
"comparisonSymbol" : "<=",
"leftChild" : {
"type" : "consequentNode",
"consequent" : {
"matrixPosition" : 2,
"id" : "Iris-versicolor",
"name" : "Iris-versicolor",
"percentageNode" : 97.91666666666666
}
},
"rightChild" : {
"type" : "numericNode",
"attribute" : {
"type" : "numericAtt",
"id" : "petalwidth",
"name" : "petalwidth",
"properties" : [ {
"type" : "numericProp",
"name" : "Low",
"id" : 0,
"interval" : {
"left" : 0.1,
"right" : 0.8999999999999999
}
}, {
"type" : "numericProp",
"name" : "Medium",
"id" : 1,
"interval" : {
"left" : 0.8999999999999999,
"right" : 1.7
}
}, {
"type" : "numericProp",
"name" : "High",
"id" : 2,
"interval" : {
"left" : 1.7,
"right" : 2.5
}
} ],
"interval" : {
"left" : 0.1,
"right" : 2.5
},
"value" : 0.0
},
"splitValue" : 1.5,
"comparisonSymbol" : "<=",
"leftChild" : {
"type" : "consequentNode",
"consequent" : {
"matrixPosition" : 3,
"id" : "Iris-virginica",
"name" : "Iris-virginica",
"percentageNode" : 100.0
}