0

I'm trying to convert the Python code at PCA-Based Fraud Detection into C# using ML.NET as an example of how to perform untrained anomaly detection using PCA.

I can perform the transform and get my new principal components, but I am struggling to see how to reverse it given that in ML.NET there is no PrincipalComponentAnalysisTransformer.InverseTransform() method.

Can anyone show me in C# how to perform the inverse calculations to get back to the "original" feature values?

Edited to include code so far

    class CreditCardPca
    {
        public class OutputData
        {
            [ColumnName("PcaFeatures")]
            public float[] Features { get; set; }
        }

        public CreditCardPca()
        {
        }

        public void Calculate()
        {
            // Set up the MLContext
            var context = new MLContext();

            // Load data from file
            var dataView = context.Data.LoadFromTextFile<CreditCard>(path: ".\\Data\\creditcard.csv",
                separatorChar: ',',
                hasHeader: true, allowQuoting: true, trimWhitespace: true, allowSparse: false);

            this.PreviewDataView(dataView);

            // Separate the samples by class
            var legitDataView = context.Data.FilterRowsByColumn(dataView, "Class", -0.1, 0.1);
            var fraudDataView = context.Data.FilterRowsByColumn(dataView, "Class", 0.9, 1.1);

            // Define the PCA transformer
            var pipeline = context.Transforms.Concatenate("Features",
                    new[]
                    {
                        "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15",
                        "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28",
                        "Amount"
                    })
                .Append(context.Transforms.NormalizeMinMax("Features"))
                .Append(context.Transforms.ProjectToPrincipalComponents(outputColumnName: "PcaFeatures",
                    inputColumnName: "Features", rank: 26));

            // Fit the pipeline to the legit data
            var model = pipeline.Fit(legitDataView);

            // Transform both sets of data using the trained model
            var legitTransformedData = model.Transform(legitDataView);
            var fraudTansformedData = model.Transform(fraudDataView);

            // Convert the transformed data to the output class
            var predictions = context.Data.CreateEnumerable<OutputData>(legitTransformedData, reuseRowObject: false);

            // Display first 5 results
            var predictionsArray = predictions.ToArray();
            for (int i = 0; i < 5; i++)
            {
                this.TextBox.Log("PCA Features: " + string.Join(", ", predictionsArray[i].Features));
            }

            // Manually perform inverse transformation
            var originalData = predictionsArray.Select(x => new float[] {x.Features[0], x.Features[1], 0}).ToArray();

            // Now I'm stuck...
        
        }
Chris99
  • 1
  • 2

0 Answers0