removed timestamp from event id

This commit is contained in:
Luong Hoang 2016-06-03 10:54:39 -04:00
Родитель d591682f76
Коммит 64cfb9bd25
10 изменённых файлов: 80 добавлений и 88 удалений

Просмотреть файл

@ -33,6 +33,7 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DocumentationFile>..\bin\AnyCPU\Release\Microsoft.Research.MultiWorldTesting.ExploreLibrary.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="BaseExplorer.cs" />
@ -55,12 +56,15 @@
<Compile Include="MultiActionHelper.cs" />
<Compile Include="TopSlotExplorer.cs" />
<Compile Include="UniformRandomExploration.cs" />
<Compile Include="UniqueEventID.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="GitLink, Version=2.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\gitlink.2.2.0\lib\net45\GitLink.exe</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
/// <param name="uniqueKey">A user-defined identifer for the decision.</param>
/// <param name="modelId">Optional; The Id of the model used to make predictions/decisions, if any exists at decision time.</param>
/// <param name="isExplore">Optional; Indicates whether the decision was generated purely from exploration (vs. exploitation).</param>
void Record(TContext context, TAction value, object explorerState, object mapperState, UniqueEventID uniqueKey);
void Record(TContext context, TAction value, object explorerState, object mapperState, string uniqueKey);
}
public interface IExplorer<TAction, TPolicyValue>

Просмотреть файл

@ -111,6 +111,13 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
}
}
public TAction ChooseAction(string uniqueKey, TContext context, IContextMapper<TContext, TPolicyValue> defaultPolicy)
{
var policy = this.Policy;
var policyDecision = (policy ?? defaultPolicy).MapContext(context);
return ChooseActionInternal(uniqueKey, context, policyDecision);
}
/// <summary>
/// Choose an action (or decision to take) given the exploration algorithm and context.
/// </summary>
@ -119,46 +126,35 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
/// <param name="context">The context upon which a decision is made. See SimpleContext above for an example.</param>
/// <param name="numActionsVariable">Optional; Number of actions available which may be variable across decisions.</param>
/// <returns>An unsigned 32-bit integer representing the 1-based chosen action.</returns>
public TAction ChooseAction(UniqueEventID uniqueKey, TContext context, TAction initialAction)
public TAction ChooseAction(string uniqueKey, TContext context, TPolicyValue defaultPolicyDecision)
{
// Note: thread-safe atomic reference access
var policy = this.Policy;
if (policy == null)
{
// policy not ready & initial action provided
this.Log(uniqueKey,
context,
ExplorerDecision.Create(initialAction, new GenericExplorerState { Probability = 1 }, true));
return initialAction;
}
ulong saltedSeed = MurMurHash3.ComputeIdHash(uniqueKey.Key) + this.appId;
PRG random = new PRG(saltedSeed);
var policyDecision = policy.MapContext(context);
var explorerDecision = this.Explorer.MapContext(random, policyDecision.Value, this.numActionsProvider.GetNumberOfActions(context));
this.Log(uniqueKey, context, explorerDecision, policyDecision);
return explorerDecision.Value;
var policyDecision = (policy != null) ? policy.MapContext(context) : defaultPolicyDecision;
return ChooseActionInternal(uniqueKey, context, policyDecision);
}
public TAction ChooseAction(UniqueEventID uniqueKey, TContext context)
public TAction ChooseAction(string uniqueKey, TContext context)
{
ulong saltedSeed = MurMurHash3.ComputeIdHash(uniqueKey.Key) + this.appId;
ulong saltedSeed = MurMurHash3.ComputeIdHash(uniqueKey) + this.appId;
PRG random = new PRG(saltedSeed);
var policy = this.Policy;
ExplorerDecision<TAction> explorerDecision;
PolicyDecision<TPolicyValue> policyDecision = null;
int numActionsVariable = this.numActionsProvider.GetNumberOfActions(context);
if (numActionsVariable <= 0)
{
throw new Exception("Could not determine number of actions from the provided context.");
}
if (policy == null)
explorerDecision = this.InitialExplorer.Explore(random, this.numActionsProvider.GetNumberOfActions(context));
explorerDecision = this.InitialExplorer.Explore(random, numActionsVariable);
else
{
policyDecision = policy.MapContext(context);
explorerDecision = this.Explorer.MapContext(random, policyDecision.Value, this.numActionsProvider.GetNumberOfActions(context));
explorerDecision = this.Explorer.MapContext(random, policyDecision.Value, numActionsVariable);
}
this.Log(uniqueKey, context, explorerDecision, policyDecision != null ? policyDecision.MapperState : null);
@ -166,14 +162,6 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
return explorerDecision.Value;
}
private void Log(UniqueEventID uniqueKey, TContext context, ExplorerDecision<TAction> explorerDecision, object policyState = null)
{
if (explorerDecision.ShouldRecord)
{
this.recorder.Record(context, explorerDecision.Value, explorerDecision.ExplorerState, policyState, uniqueKey);
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
@ -183,6 +171,32 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
GC.SuppressFinalize(this);
}
private TAction ChooseActionInternal(string uniqueKey, TContext context, PolicyDecision<TPolicyValue> policyDecision)
{
ulong saltedSeed = MurMurHash3.ComputeIdHash(uniqueKey) + this.appId;
PRG random = new PRG(saltedSeed);
int numActionsVariable = this.numActionsProvider.GetNumberOfActions(context);
if (numActionsVariable <= 0)
{
throw new Exception("Could not determine number of actions from the provided context.");
}
var explorerDecision = this.Explorer.MapContext(random, policyDecision.Value, numActionsVariable);
this.Log(uniqueKey, context, explorerDecision, policyDecision);
return explorerDecision.Value;
}
private void Log(string uniqueKey, TContext context, ExplorerDecision<TAction> explorerDecision, object policyState = null)
{
if (explorerDecision.ShouldRecord)
{
this.recorder.Record(context, explorerDecision.Value, explorerDecision.ExplorerState, policyState, uniqueKey);
}
}
private void Dispose(bool disposing)
{
if (disposing)

Просмотреть файл

@ -26,5 +26,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.3")]
[assembly: AssemblyFileVersion("1.0.0.3")]
[assembly: AssemblyVersion("1.0.0.4")]
[assembly: AssemblyFileVersion("1.0.0.4")]

Просмотреть файл

@ -25,11 +25,11 @@ namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary.SingleAction
/// <param name="action">Chosen by an exploration algorithm given context.</param>
/// <param name="probability">The probability of the chosen action given context.</param>
/// <param name="uniqueKey">A user-defined identifer for the decision.</param>
public void Record(TContext context, int value, object explorerState, object mapperState, UniqueEventID uniqueKey)
public void Record(TContext context, int value, object explorerState, object mapperState, string uniqueKey)
{
recordingBuilder.Append(value.ToString(CultureInfo.InvariantCulture));
recordingBuilder.Append(' ');
recordingBuilder.Append(uniqueKey.Key);
recordingBuilder.Append(uniqueKey);
recordingBuilder.Append(' ');
recordingBuilder.Append(((GenericExplorerState)explorerState).Probability.ToString("0.00000", CultureInfo.InvariantCulture));

Просмотреть файл

@ -1,27 +0,0 @@
using System;
namespace Microsoft.Research.MultiWorldTesting.ExploreLibrary
{
/// <summary>
/// Represents a unique identifier for an event.
/// </summary>
public class UniqueEventID
{
/// <summary>
/// The key for the event.
/// </summary>
/// <remarks>
/// This key is used as a seed to the randomization, which
/// ensures consistent experience within same event, but
/// random across events.
/// </remarks>
public string Key { get; set; }
/// <summary>
/// The time stamp of the event which, together with the key,
/// uniquely identify an event. Events with same key
/// must have the same time stamp.
/// </summary>
public DateTime TimeStamp { get; set; }
}
}

Просмотреть файл

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" />
<package id="gitlink" version="2.2.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" />
</packages>

Просмотреть файл

@ -20,7 +20,7 @@ namespace cs_test
/// </summary>
class MyRecorder : IRecorder<MyContext, int>
{
public void Record(MyContext context, int value, object explorerState, object mapperState, UniqueEventID uniqueKey)
public void Record(MyContext context, int value, object explorerState, object mapperState, string uniqueKey)
{
// Stores the tuple internally in a vector that could be used later for other purposes.
interactions.Add(new Interaction<MyContext>()
@ -28,7 +28,7 @@ namespace cs_test
Context = context,
Action = (uint)value,
Probability = ((GenericExplorerState)explorerState).Probability,
UniqueKey = uniqueKey.Key
UniqueKey = uniqueKey
});
}
@ -134,7 +134,7 @@ namespace cs_test
// Performs exploration by passing an instance of the Epsilon-Greedy exploration algorithm into MwtExplorer
// using a sample string to uniquely identify this event
string uniqueKey = "eventid";
int action = mwtt.ChooseAction(new UniqueEventID { Key = uniqueKey, TimeStamp = DateTime.UtcNow }, context);
int action = mwtt.ChooseAction(uniqueKey, context);
Console.WriteLine(recorder.GetRecording());
@ -151,7 +151,7 @@ namespace cs_test
//MwtExplorer<MyContext> mwtt = new MwtExplorer<MyContext>("mwt", recorder);
var mwtt = MwtExplorer.Create("mwt", numActions, recorder, new TauFirstExplorer(tau), new MyPolicy());
int action = mwtt.ChooseAction(new UniqueEventID { Key = "key", TimeStamp = DateTime.UtcNow }, new MyContext());
int action = mwtt.ChooseAction("key", new MyContext());
Console.WriteLine(String.Join(",", recorder.GetAllInteractions().Select(it => it.Action)));
return;
}

Просмотреть файл

@ -315,7 +315,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());
@ -358,7 +358,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
int numActionsVariable = isVariableActionContext ? ((IVariableActionContext)contextList[i]).GetNumberOfActions() : int.MaxValue;
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());
@ -401,7 +401,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
int numActionsVariable = isVariableActionContext ? ((IVariableActionContext)contextList[i]).GetNumberOfActions() : int.MaxValue;
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());
@ -422,7 +422,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
int numActionsVariable = isVariableActionContext ? ((IVariableActionContext)contextList[i]).GetNumberOfActions() : int.MaxValue;
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());
@ -464,7 +464,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
int numActionsVariable = isVariableActionContext ? ((IVariableActionContext)contextList[i]).GetNumberOfActions() : int.MaxValue;
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());
@ -486,7 +486,7 @@ namespace BlackBoxTests
for (int i = 0; i < experimentalUnitIdList.Length; i++)
{
int numActionsVariable = isVariableActionContext ? ((IVariableActionContext)contextList[i]).GetNumberOfActions() : int.MaxValue;
mwt.ChooseAction(new UniqueEventID { Key = experimentalUnitIdList[i] }, contextList[i]);
mwt.ChooseAction(experimentalUnitIdList[i], contextList[i]);
}
File.AppendAllText(outputFile, recorder.GetRecording());

Просмотреть файл

@ -44,7 +44,7 @@ namespace ExploreTests.SingleAction
where TContext : RegularTestContext
{
string uniqueKey = "ManagedTestId";
var uniqueId = new UniqueEventID { Key = uniqueKey, TimeStamp = DateTime.UtcNow };
var uniqueId = uniqueKey;
TestRecorder<TContext> recorder = new TestRecorder<TContext>();
//MwtExplorer<TContext> mwtt = new MwtExplorer<TContext>("mwt", recorder);
var mwtt = MwtExplorer.Create("mwt", numActions, recorder, explorer, policy);
@ -98,7 +98,7 @@ namespace ExploreTests.SingleAction
where TContext : RegularTestContext
{
string uniqueKey = "ManagedTestId";
var uniqueId = new UniqueEventID { Key = uniqueKey, TimeStamp = DateTime.UtcNow };
var uniqueId = uniqueKey;
var recorder = new TestRecorder<TContext>();
@ -240,7 +240,7 @@ namespace ExploreTests.SingleAction
Random rand = new Random();
for (uint i = 0; i < contexts.Length; i++)
{
var uniqueId = new UniqueEventID { Key = rand.NextDouble().ToString(), TimeStamp = DateTime.UtcNow };
var uniqueId = rand.NextDouble().ToString();
int chosenAction = mwtt.ChooseAction(uniqueId, contexts[i]);
actions[chosenAction - 1]++; // action id is one-based
}
@ -273,9 +273,9 @@ namespace ExploreTests.SingleAction
var mwtt = MwtExplorer.Create("mwt", numActions, recorder, explorer, scorer);
Random rand = new Random();
mwtt.ChooseAction(new UniqueEventID { Key = rand.NextDouble().ToString() }, new RegularTestContext() { Id = 100 });
mwtt.ChooseAction(new UniqueEventID { Key = rand.NextDouble().ToString() }, new RegularTestContext() { Id = 101 });
mwtt.ChooseAction(new UniqueEventID { Key = rand.NextDouble().ToString() }, new RegularTestContext() { Id = 102 });
mwtt.ChooseAction(rand.NextDouble().ToString(), new RegularTestContext() { Id = 100 });
mwtt.ChooseAction(rand.NextDouble().ToString(), new RegularTestContext() { Id = 101 });
mwtt.ChooseAction(rand.NextDouble().ToString(), new RegularTestContext() { Id = 102 });
var interactions = recorder.GetAllInteractions();
@ -305,7 +305,7 @@ namespace ExploreTests.SingleAction
explorer.EnableExplore(false);
for (int i = 0; i < 1000; i++)
{
int chosenAction = mwtt.ChooseAction(new UniqueEventID { Key = rand.NextDouble().ToString() }, new RegularTestContext() { Id = (int)i });
int chosenAction = mwtt.ChooseAction(rand.NextDouble().ToString(), new RegularTestContext() { Id = (int)i });
Assert.AreEqual(highestScoreAction, chosenAction);
}
}
@ -339,7 +339,7 @@ namespace ExploreTests.SingleAction
//var mwtt = new MwtExplorer<TContext>("mwt", recorder);
var mwtt = MwtExplorer.Create("mwt", numActions, recorder, explorer, scorer);
int chosenAction = mwtt.ChooseAction(new UniqueEventID { Key = uniqueKey }, testContext);
int chosenAction = mwtt.ChooseAction(uniqueKey, testContext);
var interactions = recorder.GetAllInteractions();
Assert.AreEqual(1, interactions.Count);
@ -367,14 +367,14 @@ namespace ExploreTests.SingleAction
class TestRecorder<Ctx> : IRecorder<Ctx, int>
{
public void Record(Ctx context, int value, object explorerState, object mapperState, UniqueEventID uniqueKey)
public void Record(Ctx context, int value, object explorerState, object mapperState, string uniqueKey)
{
interactions.Add(new TestInteraction<Ctx>()
{
Context = context,
Action = (uint)value,
Probability = ((GenericExplorerState)explorerState).Probability,
UniqueKey = uniqueKey.Key
UniqueKey = uniqueKey
});
}