Commit ab7678f3 authored by Bruno López Trigo's avatar Bruno López Trigo

Engadidas probas a memoria, documentación de funcionalidade e nova version de explicacions na API

parent 817db1a8
......@@ -2,6 +2,7 @@ package brunolopez.expliclas.explainer;
import java.util.ArrayList;
import simplenlg.features.Feature;
import simplenlg.features.NumberAgreement;
import simplenlg.features.Tense;
import simplenlg.format.english.HTMLFormatter;
import simplenlg.framework.CoordinatedPhraseElement;
......@@ -9,6 +10,7 @@ import simplenlg.framework.DocumentElement;
import simplenlg.framework.NLGElement;
import simplenlg.framework.NLGFactory;
import simplenlg.lexicon.Lexicon;
import simplenlg.phrasespec.NPPhraseSpec;
import simplenlg.phrasespec.SPhraseSpec;
import simplenlg.phrasespec.VPPhraseSpec;
import simplenlg.realiser.english.Realiser;
......@@ -25,160 +27,224 @@ public class ClauseBuilder {
this.realiser = new Realiser(this.lexicon);
}
public SPhraseSpec generateClause(String clause){
public SPhraseSpec generateClause(String clause) {
SPhraseSpec s = this.nlgFactory.createClause();
s.addComplement(clause);
return s;
}
public SPhraseSpec generateClause(ArrayList<String> subject, String verb, ArrayList<String> object, boolean plural) {
SPhraseSpec phrase = this.nlgFactory.createClause();
VPPhraseSpec verbPhrase = this.nlgFactory.createVerbPhrase(verb);
CoordinatedPhraseElement subjectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement objectPhrase = this.nlgFactory.createCoordinatedPhrase();
if (subject.size() > 1) {
for (String s : subject) {
subjectPhrase.addCoordinate(s);
}
}
for (String s : object) {
objectPhrase.addCoordinate(s);
}
if (subject.size() > 1) {
phrase.setSubject(subjectPhrase);
} else {
NPPhraseSpec s = this.nlgFactory.createNounPhrase(subject.get(0));
s.setFeature(Feature.NUMBER, plural ? NumberAgreement.PLURAL : NumberAgreement.SINGULAR);
phrase.setSubject(s);
}
phrase.setVerb(verbPhrase);
phrase.setObject(objectPhrase);
return phrase;
}
public SPhraseSpec generateClause(ArrayList<String> subject, String verb, ArrayList<String> object, ArrayList<String> complement, boolean plural) {
SPhraseSpec phrase = this.nlgFactory.createClause();
VPPhraseSpec verbPhrase = this.nlgFactory.createVerbPhrase(verb);
CoordinatedPhraseElement subjectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement objectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement complementPhrase = this.nlgFactory.createCoordinatedPhrase();
for(String s: subject){
for (String s : subject) {
subjectPhrase.addCoordinate(s);
}
for(String s: object){
for (String s : object) {
objectPhrase.addCoordinate(s);
}
for(String s: complement){
for (String s : complement) {
complementPhrase.addCoordinate(s);
}
phrase.setSubject(subjectPhrase);
phrase.setVerb(verbPhrase);
phrase.setObject(objectPhrase);
phrase.setComplement(complementPhrase);
phrase.setPlural(plural);
return phrase;
}
public SPhraseSpec generateClauseObjectOr(ArrayList<String> subject, String verb, ArrayList<String> object, ArrayList<String> complement, boolean plural) {
SPhraseSpec phrase = this.nlgFactory.createClause();
VPPhraseSpec verbPhrase = this.nlgFactory.createVerbPhrase(verb);
CoordinatedPhraseElement subjectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement objectPhrase = this.nlgFactory.createCoordinatedPhrase();
objectPhrase.setConjunction("or");
CoordinatedPhraseElement complementPhrase = this.nlgFactory.createCoordinatedPhrase();
for (String s : subject) {
subjectPhrase.addCoordinate(s);
}
for (String s : object) {
objectPhrase.addCoordinate(s);
}
for (String s : complement) {
complementPhrase.addCoordinate(s);
}
phrase.setSubject(subjectPhrase);
phrase.setVerb(verbPhrase);
phrase.setObject(objectPhrase);
phrase.setComplement(complementPhrase);
phrase.setPlural(plural);
return phrase;
}
public SPhraseSpec generateClause(SPhraseSpec phrase1, CoordinatedPhraseElement phrase2, String union){
public SPhraseSpec generateClause(SPhraseSpec phrase1, CoordinatedPhraseElement phrase2, String union) {
phrase2.addPreModifier(union);
phrase1.addModifier(phrase2);
return phrase1;
}
public SPhraseSpec generateClause(SPhraseSpec phrase1, SPhraseSpec phrase2, String union){
public SPhraseSpec generateClause(SPhraseSpec phrase1, SPhraseSpec phrase2, String union) {
phrase2.setFeature(Feature.COMPLEMENTISER, union);
phrase2.setFeature(Feature.TENSE, Tense.PRESENT);
phrase1.addComplement(phrase2);
return phrase1;
}
public SPhraseSpec generateModalClause(ArrayList<String> subject, String verb, String modal, ArrayList<String> object, boolean plural){
public SPhraseSpec generateModalClause(ArrayList<String> subject, String verb, String modal, ArrayList<String> object, boolean plural) {
SPhraseSpec phrase = this.nlgFactory.createClause();
VPPhraseSpec verbPhrase = this.nlgFactory.createVerbPhrase(verb);
verbPhrase.setFeature(Feature.MODAL, modal);
CoordinatedPhraseElement subjectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement objectPhrase = this.nlgFactory.createCoordinatedPhrase();
for(String s: subject){
for (String s : subject) {
subjectPhrase.addCoordinate(s);
}
for(String s: object){
for (String s : object) {
objectPhrase.addCoordinate(s);
}
phrase.setSubject(subjectPhrase);
phrase.setVerb(verbPhrase);
phrase.setObject(objectPhrase);
phrase.setPlural(plural);
return phrase;
}
public SPhraseSpec generatePassiveClause(ArrayList<String> subject, String verb, ArrayList<String> object, boolean plural){
public SPhraseSpec generateComplentiserClause(SPhraseSpec phrase1, String compliment, SPhraseSpec phrase2) {
phrase2.setFeature(Feature.COMPLEMENTISER, compliment);
phrase1.addComplement(phrase2);
return phrase1;
}
public SPhraseSpec generatePassiveClause(ArrayList<String> subject, String verb, ArrayList<String> object, boolean plural) {
SPhraseSpec phrase = this.nlgFactory.createClause();
VPPhraseSpec verbPhrase = this.nlgFactory.createVerbPhrase(verb);
verbPhrase.setFeature(Feature.PASSIVE, true);
CoordinatedPhraseElement subjectPhrase = this.nlgFactory.createCoordinatedPhrase();
CoordinatedPhraseElement objectPhrase = this.nlgFactory.createCoordinatedPhrase();
for(String s: subject){
for (String s : subject) {
subjectPhrase.addCoordinate(s);
}
for(String s: object){
for (String s : object) {
objectPhrase.addCoordinate(s);
}
phrase.setSubject(subjectPhrase);
phrase.setVerb(verbPhrase);
phrase.setObject(objectPhrase);
phrase.setPlural(plural);
return phrase;
}
public DocumentElement getParagraph(ArrayList<SPhraseSpec> phrases){
public DocumentElement getParagraph(ArrayList<SPhraseSpec> phrases) {
DocumentElement p = this.nlgFactory.createParagraph();
for(SPhraseSpec s: phrases){
for (SPhraseSpec s : phrases) {
p.addComponent(s);
}
return p;
}
public DocumentElement getParagraph(DocumentElement element){
public DocumentElement getParagraph(DocumentElement element) {
DocumentElement p = this.nlgFactory.createParagraph();
p.addComponent(element);
return p;
}
public DocumentElement generateList(ArrayList<SPhraseSpec> phrases){
public DocumentElement generateList(ArrayList<SPhraseSpec> phrases) {
DocumentElement list = this.nlgFactory.createList();
for(SPhraseSpec s: phrases){
for (SPhraseSpec s : phrases) {
list.addComponent(this.nlgFactory.createListItem(s));
}
return list;
}
public DocumentElement getDocument(ArrayList<DocumentElement> paragraphs, String title){
public DocumentElement getDocument(ArrayList<DocumentElement> paragraphs, String title) {
DocumentElement doc = this.nlgFactory.createDocument(title);
for(DocumentElement p: paragraphs){
for (DocumentElement p : paragraphs) {
doc.addComponent(p);
}
return doc;
}
public String getRealisation(NLGElement element){
public String getRealisation(NLGElement element) {
return this.realiser.realiseSentence(element);
}
public String getRealisation(DocumentElement doc) {
this.realiser.setFormatter(new HTMLFormatter());
return this.realiser.realise(doc).getRealisation();
}
public String getRealisation(SPhraseSpec phrase) {
return this.realiser.realiseSentence(phrase);
}
......
......@@ -2,6 +2,7 @@ package brunolopez.expliclas.explainer;
import brunolopez.expliclas.interpreter.problembuilder.Problem;
import brunolopez.expliclas.interpreter.solutionbuilder.Solution;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
......@@ -52,11 +53,18 @@ public class Explainer implements ExplainerInterface {
subject.clear();
object.clear();
complement.clear();
subject.add("This problem");
object.add(this.extractor.getGlobalPrecision());
phrases.add(this.cbuilder.generateClause(subject, "be", object, complement, false));
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
subject.add("This classifier");
object.add(this.extractor.getGlobalPrecision());
SPhraseSpec tmpPhrase = this.cbuilder.generateClause(subject, "be", object, false);
subject.clear();
object.clear();
subject.add("correctly classified instances");
object.add(df.format(this.extractor.getGlobalPrecisionPercentage()) + "%");
phrases.add(this.cbuilder.generateComplentiserClause(tmpPhrase, "because", this.cbuilder.generateClause(subject, "represent", object, true)));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(0)));
paragraphs.add(this.cbuilder.getParagraph(phrases));
......@@ -76,7 +84,7 @@ public class Explainer implements ExplainerInterface {
percentage = ((float) longest.size()) / this.extractor.getConsequentsSize() * 100;
pairs = (mostConfused.size() > 2) ? "pairs" : "pair";
if (longest.size() > 0) {
if (percentage < 20) {
......@@ -155,7 +163,7 @@ public class Explainer implements ExplainerInterface {
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(0)));
subject.clear();
/*subject.clear();
object.clear();
subject.add("But among all of them the " + pairs + " [" + mostConfused.get(0)
......@@ -169,7 +177,7 @@ public class Explainer implements ExplainerInterface {
phrases.add(this.cbuilder.generateClause(subject, "be", object, complement, subject.size() > 1));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(1)));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(1)));*/
}
}
......@@ -205,16 +213,20 @@ public class Explainer implements ExplainerInterface {
boolean first = true;
String clause = "";
String att = "";
for (String s : usuallyMislead) {
if (first) {
clause = "- Pair [" + s;
subject.add("- Class " + s);
att = s;
first = false;
} else {
clause += "; " + s + "]";
phrases.add(this.cbuilder.generateClause(clause));
object.add("confused with class " + s + " in " + df.format(this.extractor.getPairConfusion(att, s)) + "% of cases");
phrases.add(this.cbuilder.generateClause(subject, "be", object, false));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(phrases.size() - 1)));
first = true;
subject.clear();
object.clear();
}
}
......@@ -242,13 +254,16 @@ public class Explainer implements ExplainerInterface {
for (String s : oftenMislead) {
if (first) {
clause = "- Pair [" + s;
subject.add("- Class " + s);
att = s;
first = false;
} else {
clause += "; " + s + "]";
phrases.add(this.cbuilder.generateClause(clause));
object.add("confused with class " + s + " in " + df.format(this.extractor.getPairConfusion(att, s)) + "% of cases");
phrases.add(this.cbuilder.generateClause(subject, "be", object, false));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(phrases.size() - 1)));
first = true;
subject.clear();
object.clear();
}
}
......@@ -271,13 +286,16 @@ public class Explainer implements ExplainerInterface {
for (String s : eventuallyMislead) {
if (first) {
clause = "- Pair [" + s;
subject.add("- Class " + s);
att = s;
first = false;
} else {
clause += "; " + s + "]";
phrases.add(this.cbuilder.generateClause(clause));
object.add("confused with class " + s + " in " + df.format(this.extractor.getPairConfusion(att, s)) + "% of cases");
phrases.add(this.cbuilder.generateClause(subject, "be", object, false));
explanation.addExplanationClause(this.cbuilder.getRealisation(phrases.get(phrases.size() - 1)));
first = true;
subject.clear();
object.clear();
}
}
......@@ -342,7 +360,7 @@ public class Explainer implements ExplainerInterface {
object.add(s);
}
coord.addCoordinate(this.cbuilder.generateClause(subject, "be", object, complement, false));
coord.addCoordinate(this.cbuilder.generateClauseObjectOr(subject, "be", object, complement, false));
}
......@@ -369,11 +387,17 @@ public class Explainer implements ExplainerInterface {
ArrayList<String> subject = new ArrayList<>();
ArrayList<String> object = new ArrayList<>();
ArrayList<String> complement = new ArrayList<>();
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
String usualValues;
int i = 0;
for (String s : alternatives) {
usualValues = "";
subject.clear();
object.clear();
complement.clear();
if (i == 0) {
subject.add("However, this " + this.extractor.getProblemType());
} else {
......@@ -386,8 +410,11 @@ public class Explainer implements ExplainerInterface {
for (String a : antecedents.get(i)) {
subject.add(a);
usualValues += df.format(this.extractor.usualValue(s, a)) + ", ";
}
complement.add("(" + usualValues.substring(0, usualValues.length()-2) + ")");
if (subject.size() > 1) {
object.add("quite close to the usual " + s + " values");
phrases.add(this.cbuilder.generateClause(tmpPhrase, this.cbuilder.generateClause(subject, "be", object, complement, true), "because"));
......@@ -395,12 +422,13 @@ public class Explainer implements ExplainerInterface {
object.add("quite close to the usual " + s + " value");
phrases.add(this.cbuilder.generateClause(tmpPhrase, this.cbuilder.generateClause(subject, "be", object, complement, false), "because"));
}
exp.addExplanationClause(this.cbuilder.getRealisation(phrases.get(i)));
i++;
}
complement.clear();
paragraphs.add(this.cbuilder.getParagraph(phrases));
phrases.clear();
......@@ -416,7 +444,7 @@ public class Explainer implements ExplainerInterface {
for (String s : (ArrayList<String>) pair.getValue()) {
c.addCoordinate(s);
}
object.add((String) pair.getKey() + " to be " + this.cbuilder.getRealisation(c).toLowerCase());
object.add((String) pair.getKey() + " to be " + this.cbuilder.getRealisation(c));
phrases.add(this.cbuilder.generateClause(subject, "be", object, complement, false));
if (phrases.size() == 1) {
phrases.get(0).addFrontModifier("For these specific values");
......@@ -433,7 +461,9 @@ public class Explainer implements ExplainerInterface {
it = probs_mistake.entrySet().iterator();
SPhraseSpec exception = null;
ArrayList<String> alts = new ArrayList<>();
ArrayList<String> alts2 = new ArrayList<>();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
subject.clear();
......@@ -441,6 +471,7 @@ public class Explainer implements ExplainerInterface {
if (((String) pair.getKey()).equals("an exception")) {
for (String s : (ArrayList<String>) pair.getValue()) {
subject.add(s);
alts.add(s);
}
object.add((String) pair.getKey());
exception = this.cbuilder.generateModalClause(subject, "be", "will", object, false);
......@@ -448,6 +479,7 @@ public class Explainer implements ExplainerInterface {
} else {
for (String s : (ArrayList<String>) pair.getValue()) {
subject.add(s);
alts.add(s);
}
object.add((String) pair.getKey());
phrases.add(this.cbuilder.generateModalClause(subject, "be", "will", object, false));
......@@ -462,9 +494,45 @@ public class Explainer implements ExplainerInterface {
}*/
subject.clear();
object.clear();
subject.add("classifier's global information");
SPhraseSpec s = this.cbuilder.generatePassiveClause(subject, "take into account", object, false);
s.setFeature(Feature.COMPLEMENTISER, "if");
subject.add("class " + this.extractor.getMainSolution());
boolean first = true;
for(String s: alts){
if(first && this.cbuilder.getRealisation(phrases.get(0)).contains(s)){
object.add("confused with " + s);
alts2.add(s);
first = false;
}
else if(this.cbuilder.getRealisation(phrases.get(0)).contains(s)){
object.add(s);
alts2.add(s);
}
}
first = true;
i = 1;
for(String s: alts2){