BotSharp/BotSharp.NLP/Models/Entropy/AbstractDataIndexer.cs

231 lines
6.7 KiB
C#

// Copyright (C) 2005 Richard J. Northedge
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//This file is based on the AbstractDataIndexer.java source file found in the
//original java implementation of MaxEnt.
using System;
using System.Collections.Generic;
namespace BotSharp.Models
{
/// <summary>
/// Abstract base for DataIndexer implementations.
/// </summary>
/// <author>
/// Tom Morton
/// </author>
/// <author>
/// Richard J. Northedge
/// </author>
public abstract class AbstractDataIndexer : ITrainingDataIndexer
{
private int[][] mContexts;
private int[] mOutcomeList;
private int[] mNumTimesEventsSeen;
private string[] mPredicateLabels;
private string[] mOutcomeLabels;
/// <summary>
/// Gets an array of context data calculated from the training data.
/// </summary>
/// <returns>
/// Array of integer arrays, each containing the context data for an event.
/// </returns>
public virtual int[][] GetContexts()
{
return mContexts;
}
/// <summary>
/// Sets the array of context data calculated from the training data.
/// </summary>
/// <param name="newContexts">
/// Array of integer arrays, each containing the context data for an event.
/// </param>
protected internal void SetContexts(int[][] newContexts)
{
mContexts = newContexts;
}
/// <summary>
/// Gets an array indicating how many times each event is seen.
/// </summary>
/// <returns>
/// Integer array with event frequencies.
/// </returns>
public virtual int[] GetNumTimesEventsSeen()
{
return mNumTimesEventsSeen;
}
/// <summary>
/// Sets an array indicating how many times each event is seen.
/// </summary>
/// <param name="newNumTimesEventsSeen">
/// Integer array with event frequencies.
/// </param>
protected internal void SetNumTimesEventsSeen(int[] newNumTimesEventsSeen)
{
mNumTimesEventsSeen = newNumTimesEventsSeen;
}
/// <summary>
/// Gets an outcome list.
/// </summary>
/// <returns>
/// Integer array of outcomes.
/// </returns>
public virtual int[] GetOutcomeList()
{
return mOutcomeList;
}
/// <summary>
/// Sets an outcome list.
/// </summary>
/// <param name="newOutcomeList">
/// Integer array of outcomes.
/// </param>
protected internal void SetOutcomeList(int[] newOutcomeList)
{
mOutcomeList = newOutcomeList;
}
/// <summary>
/// Gets an array of predicate labels.
/// </summary>
/// <returns>
/// Array of predicate labels.
/// </returns>
public virtual string[] GetPredicateLabels()
{
return mPredicateLabels;
}
/// <summary>
/// Sets an array of predicate labels.
/// </summary>
/// <param name="newPredicateLabels">
/// Array of predicate labels.
/// </param>
protected internal void SetPredicateLabels(string[] newPredicateLabels)
{
mPredicateLabels = newPredicateLabels;
}
/// <summary>
/// Gets an array of outcome labels.
/// </summary>
/// <returns>
/// Array of outcome labels.
/// </returns>
public virtual string[] GetOutcomeLabels()
{
return mOutcomeLabels;
}
/// <summary>
/// Sets an array of outcome labels.
/// </summary>
/// <param name="newOutcomeLabels">
/// Array of outcome labels.
/// </param>
protected internal void SetOutcomeLabels(string[] newOutcomeLabels)
{
mOutcomeLabels = newOutcomeLabels;
}
/// <summary>
/// Sorts and uniques the array of comparable events. This method
/// will alter the eventsToCompare array -- it does an in place
/// sort, followed by an in place edit to remove duplicates.
/// </summary>
/// <param name="eventsToCompare">
/// a List of <code>ComparableEvent</code> values
/// </param>
protected internal virtual void SortAndMerge(List<ComparableEvent> eventsToCompare)
{
eventsToCompare.Sort();
int eventCount = eventsToCompare.Count;
int uniqueEventCount = 1; // assertion: eventsToCompare.length >= 1
if (eventCount <= 1)
{
return; // nothing to do; edge case (see assertion)
}
ComparableEvent comparableEvent = eventsToCompare[0];
for (int currentEvent = 1; currentEvent < eventCount; currentEvent++)
{
ComparableEvent eventToCompare = eventsToCompare[currentEvent];
if (comparableEvent.Equals(eventToCompare))
{
comparableEvent.SeenCount++; // increment the seen count
eventsToCompare[currentEvent] = null; // kill the duplicate
}
else
{
comparableEvent = eventToCompare; // a new champion emerges...
uniqueEventCount++; // increment the # of unique events
}
}
//NotifyProgress("done. Reduced " + eventCount + " events to " + uniqueEventCount + ".");
mContexts = new int[uniqueEventCount][];
mOutcomeList = new int[uniqueEventCount];
mNumTimesEventsSeen = new int[uniqueEventCount];
for (int currentEvent = 0, currentStoredEvent = 0; currentEvent < eventCount; currentEvent++)
{
ComparableEvent eventToStore = eventsToCompare[currentEvent];
if (null == eventToStore)
{
continue; // this was a dupe, skip over it.
}
mNumTimesEventsSeen[currentStoredEvent] = eventToStore.SeenCount;
mOutcomeList[currentStoredEvent] = eventToStore.Outcome;
mContexts[currentStoredEvent] = eventToStore.GetPredicateIndexes();
++currentStoredEvent;
}
}
/// <summary>
/// Utility method for creating a string[] array from a dictionary whose
/// keys are labels (strings) to be stored in the array and whose
/// values are the indices (integers) at which the corresponding
/// labels should be inserted.
/// </summary>
/// <param name="labelToIndexMap">
/// a <code>Dictionary</code> value
/// </param>
/// <returns>
/// a <code>string[]</code> value
/// </returns>
protected internal static string[] ToIndexedStringArray(Dictionary<string, int> labelToIndexMap)
{
string[] indexedArray = new string[labelToIndexMap.Count];
int[] indices = new int[labelToIndexMap.Count];
labelToIndexMap.Keys.CopyTo(indexedArray, 0);
labelToIndexMap.Values.CopyTo(indices, 0);
Array.Sort(indices, indexedArray);
return indexedArray;
}
}
}