📄 tertius.java
字号:
Rule worstResult = (Rule) m_results.getLast();
if (rule.getOptimistic() >= worstResult.getConfirmation()) {
return true;
}
return false;
} else {
return true;
}
}
/**
* Test if a rule can be stored in the agenda.
*
* @param rule The rule to consider.
* @return True if the rule can be stored, false otherwise.
*/
private boolean canStoreInNodes(Rule rule) {
if (rule.getObservedNumber() == 0) {
return false;
}
return true;
}
/**
* Test if it is worth calculating the confirmation of a rule.
*
* @param rule The rule to consider.
* @return True if the confirmation can be calculated, false otherwise.
*/
private boolean canCalculateConfirmation(Rule rule) {
if (rule.getObservedFrequency() > m_noiseThreshold) {
return false;
}
return true;
}
/**
* Test if a rule can be added to the results.
*
* @param rule The rule to consider.
* @return True if the rule can be stored, false otherwise.
*/
private boolean canStoreInResults(Rule rule) {
if (rule.getConfirmation() < m_confirmationThreshold) {
return false;
}
if (m_best != 0) {
if (numValuesInResult() < m_best) {
return true;
}
Rule worstResult = (Rule) m_results.getLast();
if (rule.getConfirmation() >= worstResult.getConfirmation()) {
return true;
}
return false;
} else {
return true;
}
}
/**
* Add a rule in the appropriate place in the list of the results,
* according to the confirmation and
* number of counter-instances of the rule. <p>
* Subsumption tests are performed and the rule may not be added. <p>
* Previous results may also be removed because of sumption.
*/
private void addResult(Rule rule) {
Rule current;
boolean added = false;
/* Iterate the list until we find the right place. */
SimpleLinkedList.LinkedListIterator iter = m_results.iterator();
while (iter.hasNext()) {
current = (Rule) iter.next();
if (Rule.confirmationThenObservedComparator.compare(current, rule) > 0) {
iter.addBefore(rule);
added = true;
break;
}
/* Subsumption tests to see if the rule can be added. */
if ((m_subsumption || m_sameClause || m_equivalent)
&& current.subsumes(rule)) {
if (current.numLiterals() == rule.numLiterals()) {
if (current.equivalentTo(rule)) {
/* Equivalent rules. */
if (m_equivalent) {
return;
}
} else {
/* Same clauses. */
if (m_sameClause
&& Rule.confirmationComparator.compare(current, rule) < 0) {
return;
}
}
} else {
/* Subsumption. */
if (m_subsumption
&& Rule.observedComparator.compare(current, rule) <= 0) {
return;
}
}
}
}
if (added == false) {
/* The rule must be added in the end of the results. */
m_results.add(rule);
}
/* Iterate the results with a lower confirmation
* to see if some of them must be removed. */
SimpleLinkedList.LinkedListInverseIterator inverse
= m_results.inverseIterator();
while (inverse.hasPrevious()) {
current = (Rule) inverse.previous();
if (Rule.confirmationThenObservedComparator.compare(current, rule) < 0) {
break;
}
if (current != rule && rule.subsumes(current)) {
if (current.numLiterals() == rule.numLiterals()) {
if (!current.equivalentTo(rule)) {
/* Same clauses. */
if (m_sameClause
&& Rule.confirmationComparator.compare(current, rule) > 0) {
inverse.remove();
}
}
} else {
/* Subsumption. */
if (m_subsumption
&& Rule.observedComparator.compare(rule, current) <= 0) {
inverse.remove();
}
}
}
}
/* Remove the rules with the worst confirmation value
* if there are too many results. */
if (m_best != 0 && numValuesInResult() > m_best) {
Rule worstRule = (Rule) m_results.getLast();
inverse = m_results.inverseIterator();
while (inverse.hasPrevious()) {
current = (Rule) inverse.previous();
if (Rule.confirmationComparator.compare(current, worstRule) < 0) {
break;
}
inverse.remove();
}
}
/* Print the new current values. */
printValues();
}
/**
* Method that launches the search to find the rules with the highest
* confirmation.
*
* @param instances The instances to be used for generating the rules.
* @exception Exception if rules can't be built successfully.
*/
public void buildAssociations(Instances instances) throws Exception {
Frame valuesFrame = null; /* Frame to display the current values. */
/* Initialization of the search. */
if (m_parts == null) {
m_instances = instances;
} else {
m_instances = new IndividualInstances(instances, m_parts);
}
m_results = new SimpleLinkedList();
m_hypotheses = 0;
m_explored = 0;
m_status = NORMAL;
/* Set class index. */
if (m_classIndex == 0) {
m_instances.setClassIndex(instances.numAttributes() - 1);
} else if ((m_classIndex > instances.numAttributes())
|| (m_classIndex < 0)) {
throw new Exception("Class index has to be between zero "
+ "and the number of attributes!");
} else {
m_instances.setClassIndex(m_classIndex - 1);
}
/* Initialization of the window for current values. */
if (m_printValues == WINDOW) {
m_valuesText = new TextField(37);
m_valuesText.setEditable(false);
m_valuesText.setFont(new Font("Monospaced", Font.PLAIN, 12));
Label valuesLabel = new Label("Best and worst current values:");
Button stop = new Button("Stop search");
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
/* Signal the interruption to the search. */
m_status = STOP;
}
});
valuesFrame = new Frame("Tertius status");
valuesFrame.setResizable(false);
valuesFrame.add(m_valuesText, BorderLayout.CENTER);
valuesFrame.add(stop, BorderLayout.SOUTH);
valuesFrame.add(valuesLabel, BorderLayout.NORTH);
valuesFrame.pack();
valuesFrame.setVisible(true);
} else if (m_printValues == OUT) {
System.out.println("Best and worst current values:");
}
Date start = new Date();
/* Build the predicates and launch the search. */
m_predicates = buildPredicates();
beginSearch();
Date end = new Date();
if (m_printValues == WINDOW) {
valuesFrame.dispose();
}
m_time = new Date(end.getTime() - start.getTime());
}
/**
* Run the search.
*/
public void run() {
try {
search();
} catch (OutOfMemoryError e) {
/* Garbage collect what can be collected to be able to continue. */
System.gc();
m_status = MEMORY;
}
endSearch();
}
/**
* Begin the search by starting a new thread.
*/
private synchronized void beginSearch() throws Exception {
/* This method must be synchronized to be able to
* call the wait() method. */
Thread search = new Thread(this);
search.start();
try {
/* Wait for the end of the thread. */
wait();
} catch (InterruptedException e) {
/* Signal the interruption to the search. */
m_status = STOP;
}
}
/**
* End the search by notifying to the waiting thread that it is finished.
*/
private synchronized void endSearch() {
/* This method must be synchronized to be able to
* call the notify() method. */
notify();
}
/**
* Search in the space of hypotheses the rules that have the highest
* confirmation.
* The search starts with the empty rule, other rules are generated by
* refinement.
*/
public void search() {
SimpleLinkedList nodes = new SimpleLinkedList(); /* The agenda. */
Rule currentNode;
SimpleLinkedList children;
SimpleLinkedList.LinkedListIterator iter;
Rule child;
boolean negBody = (m_negation == BODY || m_negation == ALL);
boolean negHead = (m_negation == HEAD || m_negation == ALL);
/* Start with the empty rule. */
nodes.add(new Rule(m_repeat, m_numLiterals, negBody, negHead,
m_classification, m_horn));
/* Print the current values. */
printValues();
/* Explore the rules in the agenda. */
while (m_status != STOP && !nodes.isEmpty()) {
currentNode = (Rule) nodes.removeFirst();
if (canRefine(currentNode)) {
children = currentNode.refine(m_predicates);
iter = children.iterator();
/* Calculate the optimistic estimate of the children and
* consider them for adding to the agenda and to the results. */
while (iter.hasNext()) {
m_hypotheses++;
child = (Rule) iter.next();
child.upDate(m_instances);
if (canCalculateOptimistic(child)) {
child.calculateOptimistic();
if (canExplore(child)) {
m_explored++;
if (canStoreInNodes(child)) {
} else {
iter.remove();
}
if (canCalculateConfirmation(child)) {
child.calculateConfirmation();
if (canStoreInResults(child)) {
addResult(child);
}
}
} else {
iter.remove();
}
} else {
iter.remove();
}
}
/* Since the agenda is already sorted it is more efficient
* to sort the children only and then merge. */
children.sort(Rule.optimisticThenObservedComparator);
nodes.merge(children, Rule.optimisticThenObservedComparator);
} else {
/* The agenda being sorted, it is not worth considering the following
* nodes. */
break;
}
}
}
/**
* Print the current best and worst values.
*/
private void printValues() {
if (m_printValues == NO) {
return;
} else {
if (m_results.isEmpty()) {
if (m_printValues == OUT) {
System.out.print("0.000000 0.000000 - 0.000000 0.000000");
} else { //m_printValues == WINDOW
m_valuesText.setText("0.000000 0.000000 - 0.000000 0.000000");
}
} else {
Rule best = (Rule) m_results.getFirst();
Rule worst = (Rule) m_results.getLast();
String values = best.valuesToString() + " - " + worst.valuesToString();
if (m_printValues == OUT) {
System.out.print("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+ "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
System.out.print(values);
} else { //m_printValues == WINDOW
m_valuesText.setText(values);
}
}
}
}
/**
* Outputs the best rules found with their confirmation value and number
* of counter-instances.
* Also gives the number of hypotheses considered and explored, and the
* time needed.
*/
public String toString() {
StringBuffer text = new StringBuffer();
SimpleDateFormat dateFormat
= new SimpleDateFormat("mm 'min' ss 's' SSS 'ms'");
SimpleLinkedList.LinkedListIterator iter = m_results.iterator();
int size = m_results.size();
int i = 0;
text.append("\nTertius\n=======\n\n");
while (iter.hasNext()) {
Rule current = (Rule) iter.next();
text.append(Utils.doubleToString((double) i + 1,
(int) (Math.log(size)
/ Math.log(10) + 1),
0)
+ ". ");
text.append("/* ");
if (m_roc) {
text.append(current.rocToString());
} else {
text.append(current.valuesToString());
}
text.append(" */ ");
text.append(current.toString());
text.append("\n");
i++;
}
text.append("\nNumber of hypotheses considered: " + m_hypotheses);
text.append("\nNumber of hypotheses explored: " + m_explored);
text.append("\nTime: " + dateFormat.format(m_time));
if (m_status == MEMORY) {
text.append("\n\nNot enough memory to continue the search");
} else if (m_status == STOP) {
text.append("\n\nSearch interrupted");
}
return text.toString();
}
/**
* Main method for testing this class.
*/
public static void main(String [] options) {
String trainFileString;
Reader reader;
Instances instances;
Tertius tertius = new Tertius();
StringBuffer text = new StringBuffer();
try {
/* Help string giving all the command line options. */
text.append("\n\nTertius options:\n\n");
text.append("-t <name of training file>\n");
text.append("\tSet training file.\n");
Enumeration em = tertius.listOptions();
while (em.hasMoreElements()) {
Option option = (Option) em.nextElement();
text.append(option.synopsis() + "\n");
text.append(option.description() + "\n");
}
/* Training file. */
trainFileString = Utils.getOption('t', options);
if (trainFileString.length() == 0) {
throw new Exception("No training file given!");
}
try {
reader = new BufferedReader(new FileReader(trainFileString));
} catch (Exception e) {
throw new Exception("Can't open file " + e.getMessage() + ".");
}
instances = new Instances(reader);
/* Tertius options. */
tertius.setOptions(options);
Utils.checkForRemainingOptions(options);
/* Build the rules and output the results. */
tertius.buildAssociations(instances);
System.out.println(tertius);
} catch (Exception e) {
System.err.println("\nWeka exception: " + e.getMessage() + text);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -