#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Optimization.Operators.LCS; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Encodings.DecisionList { [StorableClass] [Item("DecisionListSolution", "Represents a DecisionList solution.")] public class DecisionListSolution : ResultCollection, IDecisionListSolution { private const string ModelResultName = "Model"; private const string ProblemDataResultName = "ProblemData"; private const string TrainingAccuracyResultName = "Accuracy (training)"; private const string TestAccuracyResultName = "Accuracy (test)"; private const string TrainingNumberOfAliveRulesName = "Number of alive rules (training)"; private const string TrainingAliveRulesName = "Alive Rules (training)"; //private const string TestNumberOfAliveRules = "Number of alive rules (test)"; private const string TrainingTheoryLengthName = "Theory Length (training)"; private const string TrainingExceptionsLengthName = "Exceptions Length (training)"; public double TrainingAccuracy { get { return ((PercentValue)this[TrainingAccuracyResultName].Value).Value; } private set { ((PercentValue)this[TrainingAccuracyResultName].Value).Value = value; } } public double TestAccuracy { get { return ((PercentValue)this[TestAccuracyResultName].Value).Value; } private set { ((PercentValue)this[TestAccuracyResultName].Value).Value = value; } } public int TrainingNumberOfAliveRules { get { return ((IntValue)this[TrainingNumberOfAliveRulesName].Value).Value; } private set { ((IntValue)this[TrainingNumberOfAliveRulesName].Value).Value = value; } } public ItemSet TrainingAliveRules { get { return (ItemSet)this[TrainingAliveRulesName].Value; } private set { this[TrainingAliveRulesName].Value = value; } } public double TrainingTheoryLength { get { return ((DoubleValue)this[TrainingTheoryLengthName].Value).Value; } private set { ((DoubleValue)this[TrainingTheoryLengthName].Value).Value = value; } } public double TrainingExceptionsLength { get { return ((DoubleValue)this[TrainingExceptionsLengthName].Value).Value; } private set { ((DoubleValue)this[TrainingExceptionsLengthName].Value).Value = value; } } public int Classes { get { return ProblemData.Classes; } } IGAssistModel IGAssistSolution.Model { get { return Model; } } public DecisionList Model { get { return (DecisionList)this[ModelResultName].Value; ; } protected set { if (this[ModelResultName].Value != value) { if (value != null) { this[ModelResultName].Value = value; OnModelChanged(); } } } } public IGAssistProblemData ProblemData { get { return (IGAssistProblemData)this[ProblemDataResultName].Value; } set { if (this[ProblemDataResultName].Value != value) { if (value != null) { ProblemData.Changed -= new EventHandler(ProblemData_Changed); this[ProblemDataResultName].Value = value; ProblemData.Changed += new EventHandler(ProblemData_Changed); OnProblemDataChanged(); } } } } [StorableConstructor] protected DecisionListSolution(bool deserializing) : base(deserializing) { } protected DecisionListSolution(DecisionListSolution original, Cloner cloner) : base(original, cloner) { name = original.Name; description = original.Description; } public DecisionListSolution(DecisionList model, IGAssistProblemData problemData) : base() { name = ItemName; description = ItemDescription; Add(new Result(ModelResultName, "Decision List.", model)); Add(new Result(ProblemDataResultName, "The problem data.", problemData)); Add(new Result(TrainingAccuracyResultName, "Accuracy of the model on the training partition (percentage of correctly classified instances).", new PercentValue())); Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue())); Add(new Result(TrainingNumberOfAliveRulesName, "", new IntValue())); Add(new Result(TrainingAliveRulesName, "", new ItemSet())); Add(new Result(TrainingTheoryLengthName, "", new DoubleValue())); Add(new Result(TrainingExceptionsLengthName, "", new DoubleValue())); problemData.Changed += new EventHandler(ProblemData_Changed); RecalculateResults(); } public override IDeepCloneable Clone(Cloner cloner) { return new DecisionListSolution(this, cloner); } private void RecalculateResults() { var originalTrainingCondition = ProblemData.FetchInput(ProblemData.TrainingIndices); var originalTestCondition = ProblemData.FetchInput(ProblemData.TestIndices); ItemSet aliveRules; double theoryLength; var estimatedTraining = Model.Evaluate(originalTrainingCondition, out aliveRules, out theoryLength); TrainingNumberOfAliveRules = aliveRules.Count + (Model.DefaultAction != null ? 1 : 0); TrainingAliveRules = aliveRules; TrainingTheoryLength = theoryLength; var estimatedTest = Model.Evaluate(originalTestCondition); var originalTrainingAction = ProblemData.FetchAction(ProblemData.TrainingIndices); var originalTestAction = ProblemData.FetchAction(ProblemData.TestIndices); TrainingAccuracy = CalculateAccuracy(originalTrainingAction, estimatedTraining); TestAccuracy = CalculateAccuracy(originalTestAction, estimatedTest); TrainingExceptionsLength = 105.0 - TrainingAccuracy * 100.0; } public static double CalculateAccuracy(IEnumerable original, IEnumerable estimated) { double correctClassified = 0; double rows = original.Count(); var originalEnumerator = original.GetEnumerator(); var estimatedActionEnumerator = estimated.GetEnumerator(); while (originalEnumerator.MoveNext() && estimatedActionEnumerator.MoveNext()) { if (originalEnumerator.Current != null && estimatedActionEnumerator.Current != null && originalEnumerator.Current.SameNiche(estimatedActionEnumerator.Current)) { correctClassified++; } } return correctClassified / rows; } private void ProblemData_Changed(object sender, EventArgs e) { OnProblemDataChanged(); } public event EventHandler ModelChanged; protected virtual void OnModelChanged() { RecalculateResults(); var listeners = ModelChanged; if (listeners != null) listeners(this, EventArgs.Empty); } public event EventHandler ProblemDataChanged; protected virtual void OnProblemDataChanged() { RecalculateResults(); var listeners = ProblemDataChanged; if (listeners != null) listeners(this, EventArgs.Empty); } #region INamedItem Members [Storable] protected string name; public string Name { get { return name; } set { if (!CanChangeName) throw new NotSupportedException("Name cannot be changed."); if (!(name.Equals(value) || (value == null) && (name == string.Empty))) { CancelEventArgs e = value == null ? new CancelEventArgs(string.Empty) : new CancelEventArgs(value); OnNameChanging(e); if (!e.Cancel) { name = value == null ? string.Empty : value; OnNameChanged(); } } } } public virtual bool CanChangeName { get { return true; } } [Storable] protected string description; public string Description { get { return description; } set { if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed."); if (!(description.Equals(value) || (value == null) && (description == string.Empty))) { description = value == null ? string.Empty : value; OnDescriptionChanged(); } } } public virtual bool CanChangeDescription { get { return true; } } public override string ToString() { return Name; } public event EventHandler> NameChanging; protected virtual void OnNameChanging(CancelEventArgs e) { var handler = NameChanging; if (handler != null) handler(this, e); } public event EventHandler NameChanged; protected virtual void OnNameChanged() { var handler = NameChanged; if (handler != null) handler(this, EventArgs.Empty); OnToStringChanged(); } public event EventHandler DescriptionChanged; protected virtual void OnDescriptionChanged() { var handler = DescriptionChanged; if (handler != null) handler(this, EventArgs.Empty); } #endregion } }