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...
}