Skip to content

Commit

Permalink
Merge pull request #1 from radumg/BiLT
Browse files Browse the repository at this point in the history
BiLT - LinearRegression & NaiveBayes Classifier
  • Loading branch information
radumg authored Oct 2, 2017
2 parents 937b970 + 42117d2 commit ba8fd9e
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/DynAI.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynAI", "DynAI\MachineLearning.csproj", "{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
201 changes: 201 additions & 0 deletions src/DynAI/MachineLearning.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using Accord.MachineLearning.Bayes;
using Accord.Math;
using Accord.Math.Random;
using Accord.Statistics.Filters;
using Accord.Statistics.Models.Regression.Linear;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AI.MachineLearning
{
#region Linear Regression

/// <summary>
/// Class providing support for linear regression ML algorithms
/// </summary>
public class LinearRegression
{
#region public properties
// dataset
public double[] inputs { get; private set; }
public double[] outputs { get; private set; }
public double testValue { get; private set; }

// regression
public SimpleLinearRegression regression { get; private set; }
public OrdinaryLeastSquares ols;

// state & result
public bool learned { get; private set; }
public double result { get; private set; }
#endregion

/// <summary>
/// Constructs a new LinearRegression machine.
/// </summary>
public LinearRegression(List<double> inputList, List<double> outputList)
{
// validation
if (inputList == null || outputList == null) throw new ArgumentNullException("Neither the input list nor the output list can be NULL");

// initialise seed value
Generator.Seed = new Random().Next();

// process input and output lists into arrays
inputs = inputList.ToArray();
outputs = outputList.ToArray();

// set up linear regression using OLS
regression = new SimpleLinearRegression();
ols = new OrdinaryLeastSquares();

// nulls
testValue = new double();
result = new double();
this.learned = false;
}

/// <summary>
/// Use the object's inputs and outputs to learn the model of the linear regression, using OrdinaryLeastSquares
/// </summary>
public LinearRegression Learn()
{
regression = this.ols.Learn(inputs, outputs);
learned = true;

return this;
}

/// <summary>
/// Using the learned model, predict an output for the specified input
/// </summary>
/// <param name="test">The value to use as input for the prediction</param>
/// <returns>The predicted value</returns>
public double Predict(double test)
{
// don't predict if we haven't learned the model yet
if (this.learned != true) throw new Exception("Cannot predict before the machine has learned.");

// check we haven't already predicted for this input
if (test == this.testValue && this.learned == true) return this.result;

// predict
this.testValue = test;
this.result = this.regression.Transform(this.testValue);

return this.result;
}
}
#endregion

#region Classifiers
/// <summary>
/// Class providing support for Naive Bayes classification machines.
/// </summary>
public class NaiveBayes
{
#region public properties
// dataset
public string[][] dataset { get; private set; }
public string[] columns { get; private set; }
public string outputColumn { get; private set; }
public int[][] inputs;
public int[] outputs;

// classifier
public Accord.MachineLearning.Bayes.NaiveBayes classifier;
public NaiveBayesLearning learner;
public Codification codebook { get; private set; }

// state & result
public bool learned { get; private set; }
public string[] testValue { get; private set; }
public string result { get; private set; }
public double[] probs { get; private set; }
#endregion

/// <summary>
/// Constructs a new NaiveBayes classification machine.
/// </summary>
public NaiveBayes(string[][] data, List<string> columnList, string outputColumn)
{
// validation
if (data == null || columnList == null || outputColumn==null) throw new ArgumentNullException("Neither the input list nor the column list can be NULL");

// initialise seed value
Generator.Seed = new Random().Next();

// process input and output lists into arrays
this.dataset = data;
this.columns = columnList.ToArray();
this.outputColumn = outputColumn;

// Create a new codification codebook to
// convert strings into discrete symbols
this.codebook = new Codification(columns, this.dataset);

// Extract input and output pairs to train
int[][] symbols = this.codebook.Transform(this.dataset);
this.inputs = symbols.Get(null, 0, -1); // Gets all rows, from 0 to the last (but not the last)
this.outputs = symbols.GetColumn(-1); // Gets only the last column

// Create a new Naive Bayes learning
this.learner = new NaiveBayesLearning();

// nulls
testValue = null;
result = null;
probs = null;
this.learned = false;
}

/// <summary>
/// Use the object's inputs and outputs to learn the model of the linear regression, using OrdinaryLeastSquares
/// </summary>
public NaiveBayes Learn()
{
this.classifier = this.learner.Learn(inputs, outputs);
this.learned = true;

return this;
}

/// <summary>
/// Using the learned model, predict an output for the specified input
/// </summary>
/// <param name="test">The value to use as input for the prediction</param>
/// <returns>The predicted value</returns>
public string Predict(string[] test)
{
// don't predict if we haven't learned the model yet
if (this.learned != true) throw new Exception("Cannot predict before the machine has learned.");

// check we haven't already predicted for this input
if (test == this.testValue && this.learned == true) return this.result;

// predict
// First encode the test instance
int[] instance = this.codebook.Transform(test);

// Let us obtain the numeric output that represents the answer
int codeword = this.classifier.Decide(instance);

// Now let us convert the numeric output to an actual answer
this.result = this.codebook.Revert(this.outputColumn, codeword);

// We can also extract the probabilities for each possible answer
this.probs = this.classifier.Probabilities(instance);

return this.result;
}
}
#endregion

#region Helpers

#endregion

}
75 changes: 75 additions & 0 deletions src/DynAI/MachineLearning.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5990DC45-28B6-4E1E-B3EA-C6549EE270F7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AI</RootNamespace>
<AssemblyName>AI</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\AI.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Accord, Version=3.7.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
<HintPath>..\packages\Accord.3.7.0\lib\net45\Accord.dll</HintPath>
</Reference>
<Reference Include="Accord.MachineLearning, Version=3.7.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
<HintPath>..\packages\Accord.MachineLearning.3.7.0\lib\net45\Accord.MachineLearning.dll</HintPath>
</Reference>
<Reference Include="Accord.Math, Version=3.7.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
<HintPath>..\packages\Accord.Math.3.7.0\lib\net45\Accord.Math.dll</HintPath>
</Reference>
<Reference Include="Accord.Math.Core, Version=3.7.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
<HintPath>..\packages\Accord.Math.3.7.0\lib\net45\Accord.Math.Core.dll</HintPath>
</Reference>
<Reference Include="Accord.Statistics, Version=3.7.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
<HintPath>..\packages\Accord.Statistics.3.7.0\lib\net45\Accord.Statistics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MachineLearning.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Accord.3.7.0\build\Accord.targets" Condition="Exists('..\packages\Accord.3.7.0\build\Accord.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Accord.3.7.0\build\Accord.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Accord.3.7.0\build\Accord.targets'))" />
</Target>
</Project>
36 changes: 36 additions & 0 deletions src/DynAI/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DynAI Machine Learning")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DynAI Machine Learning")]
[assembly: AssemblyCopyright("Copyright © Radu Gidei 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5990dc45-28b6-4e1e-b3ea-c6549ee270f7")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("0.1.0.0")]
[assembly: AssemblyFileVersion("0.1.0.0")]
7 changes: 7 additions & 0 deletions src/DynAI/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Accord" version="3.7.0" targetFramework="net452" />
<package id="Accord.MachineLearning" version="3.7.0" targetFramework="net452" />
<package id="Accord.Math" version="3.7.0" targetFramework="net452" />
<package id="Accord.Statistics" version="3.7.0" targetFramework="net452" />
</packages>

0 comments on commit ba8fd9e

Please sign in to comment.