Skip to content

Commit

Permalink
anomaly detection samples
Browse files Browse the repository at this point in the history
  • Loading branch information
sahithkumar1999 committed Dec 26, 2023
1 parent acef669 commit 782777c
Show file tree
Hide file tree
Showing 20 changed files with 1,851 additions and 0 deletions.
7 changes: 7 additions & 0 deletions source/NeoCortexApi.sln
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{9475B9AE
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GridCell", "GridCell\GridCell.csproj", "{E102D57D-BA8F-4E21-8365-8ABAFB5D2C94}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeoCortexApiAnomaly", "Samples\NeoCortexApiAnomaly\NeoCortexApiAnomaly.csproj", "{7F272910-3A59-4BBB-8888-9A7F695CA754}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -111,6 +113,10 @@ Global
{E102D57D-BA8F-4E21-8365-8ABAFB5D2C94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E102D57D-BA8F-4E21-8365-8ABAFB5D2C94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E102D57D-BA8F-4E21-8365-8ABAFB5D2C94}.Release|Any CPU.Build.0 = Release|Any CPU
{7F272910-3A59-4BBB-8888-9A7F695CA754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F272910-3A59-4BBB-8888-9A7F695CA754}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F272910-3A59-4BBB-8888-9A7F695CA754}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F272910-3A59-4BBB-8888-9A7F695CA754}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -119,6 +125,7 @@ Global
{4D9AD5E0-8F00-494E-8BEF-8041C003F4E6} = {D9879A38-CCF8-4440-B939-D066196AC775}
{15375C28-1424-4A29-B2AF-11ED92F6134C} = {99AE2313-7D07-4905-A0BB-52D304FCC2F7}
{AE2CF42C-DC7D-4F0A-8B43-84A5D81E1D72} = {99AE2313-7D07-4905-A0BB-52D304FCC2F7}
{7F272910-3A59-4BBB-8888-9A7F695CA754} = {99AE2313-7D07-4905-A0BB-52D304FCC2F7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71185BAD-1342-4836-BCDA-6EC97118F92D}
Expand Down
14 changes: 14 additions & 0 deletions source/Samples/NeoCortexApiAnomaly/AnomalyDetectionSample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NeoCortexApi" Version="1.1.4" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions source/Samples/NeoCortexApiAnomaly/AnomalyDetectionSample.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33424.131
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnomalyDetectionSample", "AnomalyDetectionSample.csproj", "{F562704E-658F-410F-BC67-4DE467BE44FC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F562704E-658F-410F-BC67-4DE467BE44FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F562704E-658F-410F-BC67-4DE467BE44FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F562704E-658F-410F-BC67-4DE467BE44FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F562704E-658F-410F-BC67-4DE467BE44FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {802EED87-EAB7-4E5A-B5A5-1ABEFD119DE2}
EndGlobalSection
EndGlobal
95 changes: 95 additions & 0 deletions source/Samples/NeoCortexApiAnomaly/CSVFileReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;

namespace AnomalyDetectionSample
{
/// <summary>
/// Reads a single CSV file and returns its contents as a list of sequences.
/// </summary>
public class CSVFileReader
{
private string _filePathToCSV;

/// <summary>
/// Creates a new instance of the CSVFileReader class with the provided file path to the constructor.
/// </summary>
/// <param name="filePathToCSV">The path to the CSV file to be read.</param>
public CSVFileReader(string filePathToCSV)
{
_filePathToCSV = filePathToCSV;
}

/// <summary>
/// Reads the CSV file at the file path specified in the constructor,
/// and returns its contents as a list of sequences.
/// </summary>
/// <returns>A list of sequences contained in the CSV file.</returns>
public List<List<double>> ReadFile()
{
List<List<double>> sequences = new List<List<double>>();
string[] csvLines = File.ReadAllLines(_filePathToCSV);
// Loop through each line in the CSV File
for (int i = 0; i < csvLines.Length; i++)
{
// Current line is split into an array of columns
string[] columns = csvLines[i].Split(new char[] { ',' });
List<double> sequence = new List<double>();
// Loop through each column in the current line
for (int j = 0; j < columns.Length; j++)
{
// Value of column is parsed as double and added to sequence
// if it fails then exception is thrown
if (double.TryParse(columns[j], out double value))
{
sequence.Add(value);
}
else
{
throw new ArgumentException($"Non-numeric value found! Please check the file.");
}
}
sequences.Add(sequence);
}
return sequences;
}

/// <summary>
/// This method reads the CSV file at the file path passed on to the constructor,
/// and outputs its contents to the console.
/// </summary>
public void CSVSequencesConsoleOutput()
{
List<List<double>> sequences = ReadFile();
// Looping through each sequence and displaying it in the console
for (int i = 0; i < sequences.Count; i++)
{
Console.Write("Sequence " + (i + 1) + ": ");
foreach (double number in sequences[i])
{
Console.Write(number + " ");
}
Console.WriteLine("");
}
}

/// <summary>
/// Trims a random number of elements (between 1 and 4) from the beginning of each sequence in a list of sequences.
/// </summary>
/// <param name="sequences">The list of sequences to trim.</param>
/// <returns>A new list of trimmed sequences.</returns>
public static List<List<double>> TrimSequences(List<List<double>> sequences)
{
Random rnd = new Random();
List<List<double>> trimmedSequences = new List<List<double>>();

foreach (List<double> sequence in sequences)
{
// Generate a random number between 1 and 4
int numElementsToRemove = rnd.Next(1, 5);
List<double> trimmedSequence = sequence.Skip(numElementsToRemove).ToList();
trimmedSequences.Add(trimmedSequence);
}

return trimmedSequences;
}
}
}
107 changes: 107 additions & 0 deletions source/Samples/NeoCortexApiAnomaly/CSVFolderReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;

namespace AnomalyDetectionSample
{
/// <summary>
/// Reads the CSV files inside a folder and returns its contents as a list of sequences.
/// </summary>
public class CSVFolderReader
{
private string _folderPathToCSV;

/// <summary>
/// Creates a new instance of the CSVFolderReader class with the provided file path to the constructor.
/// </summary>
/// <param name="folderPathToCSV">The path to the folder containing the CSV files.</param>
public CSVFolderReader(string folderPathToCSV)
{
_folderPathToCSV = folderPathToCSV;
}

/// <summary>
/// Reads all CSV files in the folder, path to the folder is specified in the constructor,
/// and returns its contents as a list of sequences.
/// </summary>
/// <returns>A list of sequences contained in the CSV files present in the folder.</returns>
public List<List<double>> ReadFolder()
{
List<List<double>> folderSequences = new List<List<double>>();

// All the CSV files present inside the folder are taken
string[] fileEntries = Directory.GetFiles(_folderPathToCSV, "*.csv");

// Iterating through each CSV file inside the folder
foreach (string fileName in fileEntries)
{
string[] csvLines = File.ReadAllLines(fileName);
List<List<double>> sequencesInFile = new List<List<double>>();

// Looping through each line in the current CSV file
for (int i = 0; i < csvLines.Length; i++)
{
string[] columns = csvLines[i].Split(new char[] { ',' });
List<double> sequence = new List<double>();

// Loop through each column in the current line
for (int j = 0; j < columns.Length; j++)
{
// Value of column is parsed as double and added to sequence
// if it fails then exception is thrown
if (double.TryParse(columns[j], out double value))
{
sequence.Add(value);
}
else
{
throw new ArgumentException($"Non-numeric value found! Please check file: {fileName}.");
}
}
sequencesInFile.Add(sequence);
}
folderSequences.AddRange(sequencesInFile);
}
return folderSequences;
}

/// <summary>
/// This method reads all CSV files in the folder path passed on to the constructor,
/// and outputs its contents to the console.
/// </summary>
public void CSVSequencesConsoleOutput()
{
List<List<double>> sequences = ReadFolder();
// Looping through each sequence and displaying it in the console
for (int i = 0; i < sequences.Count; i++)
{
Console.Write("Sequence " + (i + 1) + ": ");
foreach (double number in sequences[i])
{
Console.Write(number + " ");
}
Console.WriteLine("");
}
}

/// <summary>
/// Trims a random number of elements (between 1 and 4) from the beginning of each sequence in a list of sequences.
/// </summary>
/// <param name="sequences">The list of sequences to trim.</param>
/// <returns>A new list of trimmed sequences.</returns>
public static List<List<double>> TrimSequences(List<List<double>> sequences)
{
Random rnd = new Random();
List<List<double>> trimmedSequences = new List<List<double>>();

foreach (List<double> sequence in sequences)
{
// Generate a random number between 1 and 4
int numElementsToRemove = rnd.Next(1, 5);
List<double> trimmedSequence = sequence.Skip(numElementsToRemove).ToList();
trimmedSequences.Add(trimmedSequence);
}

return trimmedSequences;
}

}
}
29 changes: 29 additions & 0 deletions source/Samples/NeoCortexApiAnomaly/CSVToHTMInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

namespace AnomalyDetectionSample
{
/// <summary>
/// Converts a list of sequences to a dictionary of sequences for facilitating HTM Engine training.
/// </summary>
public class CSVToHTMInput
{
/// <summary>
/// Builds a dictionary of sequences from a list of sequences.
/// An unique key is added, which is later used as an input for HtmClassifier.
/// </summary>
/// <param name="sequences">A list of sequences read from CSV file/files in a folder.</param>
/// <returns>A dictionary of sequences required for HTM Engine training.</returns>
public Dictionary<string, List<double>> BuildHTMInput(List<List<double>> sequences)
{
Dictionary<string, List<double>> dictionary = new Dictionary<string, List<double>>();
for (int i = 0; i < sequences.Count; i++)
{
// Unique key created and added to dictionary for HTM Input
string key = "S" + (i + 1);
List<double> value = sequences[i];
dictionary.Add(key, value);
}
return dictionary;
}
}
}
Loading

0 comments on commit 782777c

Please sign in to comment.