2016-12-13

After doing a little manual machine learning in Powershell (Github) to compare if differently-formatted strings are similar, I started wondering about ML libraries for Powershell. Aside from MS’s Azure module which at first glance appears to be just an interface to their cloud products, there are some .NET libraries of which Accord (GitHub) seems popular and worth my checking out.

The docs are geared heavily towards Visual Studio users and utility installers, but I was able to download just the libraries. I’ll see if I can use them with Powershell.

2016-12-14

A-ha! I got the .Nearest() to succeed by trying different formats for the input. For some reason this worked (with or without the second element commented out):

$New = @(
#    @(5, 2, 3)
    @( 4, 1, 9)
)

But this didn’t:

$New = @(@(5, 2, 3), @( 4, 1, 9))

Which is odd because those should be identical, I thought.

Anyway, then I noticed there are too many outputs and that I have a one-dimensional cluster I think rather than the three-dimensional cluster I thought I had. So my problem goes back to the original data and its formatting.

It seems that trying to cast as [double[][]] was unnecessary and also not doing me any favors. It may or may not have been enumerating and turning my 2D arrays into 1D arrays, or maybe that was happening elsewhere. In any case, explicit casting was not needed.

For a single-vector 2D array, use e.g. @(, @( 4, 1, 9) ). For a multi-vector 2D array, commas are needed else it becomes 1D:

@(
    @(-5, -2, -1)
    @(-5, -5, -6)
    @( 2,  1,  1)
    @( 1,  1,  2)
    @( 1,  2,  2)
    @( 3,  1,  2)
    @(11,  5,  4)
    @(15,  5,  6)
    @(10,  5,  6)
).Count

# 27

@(
    @(-5, -2, -1),
    @(-5, -5, -6),
    @( 2,  1,  1),
    @( 1,  1,  2),
    @( 1,  2,  2),
    @( 3,  1,  2),
    @(11,  5,  4),
    @(15,  5,  6),
    @(10,  5,  6)
).Count

# 9

While converting to use .Learn() and .Decide() I was still getting errors, but then I noticed the clustering is actually working. I think this long error means it’s having trouble returning the output, but the inner workings worked. (This is thrown from the .Learn() call even if I try to pipe to Out-Null:

$Error[0].Exception | select *


ErrorRecord                 : The following exception occurred while trying to enumerate the collection: "Unable to cast object of type 'SZArrayEnumerator' to type 
                            'System.Collections.Generic.IEnumerator`1[Accord.MachineLearning.KMeansClusterCollection+KMeansCluster]'.".
WasThrownFromThrowStatement : False
Message                     : The following exception occurred while trying to enumerate the collection: "Unable to cast object of type 'SZArrayEnumerator' to type 
                            'System.Collections.Generic.IEnumerator`1[Accord.MachineLearning.KMeansClusterCollection+KMeansCluster]'.".
Data                        : {System.Management.Automation.Interpreter.InterpretedFrameInfo}
InnerException              : System.InvalidCastException: Unable to cast object of type 'SZArrayEnumerator' to type 
                            'System.Collections.Generic.IEnumerator`1[Accord.MachineLearning.KMeansClusterCollection+KMeansCluster]'.
                                at Accord.MachineLearning.ClusterCollection`3.GetEnumerator() in 
                            c:\Projects\Accord.NET\framework\Sources\Accord.MachineLearning\Clustering\ClusterCollection`3.cs:line 425
                                at System.Management.Automation.EnumerableOps.GetGenericEnumerator[T](IEnumerable`1 enumerable)
TargetSite                  : System.Collections.IEnumerator GetGenericEnumerator[T](System.Collections.Generic.IEnumerable`1[T])
StackTrace                  :    at System.Management.Automation.EnumerableOps.GetGenericEnumerator[T](IEnumerable`1 enumerable)
                                at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
                                at System.Management.Automation.LanguagePrimitives.GetEnumerator(Object obj)
                                at System.Management.Automation.Internal.PipelineProcessor.Inject(Object input, Boolean enumerate)
                                at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
                            --- End of stack trace from previous location where exception was thrown ---
                                at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
                                at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] 
                            pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
                                at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
                                at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
HelpLink                    : 
Source                      : System.Management.Automation
HResult                     : -2146233087