I need to implement multiple classification classifier using Liblinear. Accord.net machine learning framework provides all of Liblinear properties except the Crammer and Singer’s formulation for multi-class classification. This is the process.
The usual way of learning a multi-class machine is by using the MulticlassSupportVectorLearning class. This class can teach one-vs-one machines that can then be queried using either voting or elimination strategies.
As such, here is an example on how linear training can be done for multiple classes:
// Let's say we have the following data to be classified
// into three possible classes. Those are the samples:
//
double[][] inputs =
{
// input output
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 0, 0, 1, 0 }, // 0
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 1, 1, 1, 1 }, // 2
new double[] { 1, 0, 1, 1 }, // 2
new double[] { 1, 1, 0, 1 }, // 2
new double[] { 0, 1, 1, 1 }, // 2
new double[] { 1, 1, 1, 1 }, // 2
};
int[] outputs = // those are the class labels
{
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
2, 2, 2, 2, 2,
};
// Create a one-vs-one multi-class SVM learning algorithm
var teacher = new MulticlassSupportVectorLearning<Linear>()
{
// using LIBLINEAR's L2-loss SVC dual for each SVM
Learner = (p) => new LinearDualCoordinateDescent()
{
Loss = Loss.L2
}
};
// Learn a machine
var machine = teacher.Learn(inputs, outputs);
// Obtain class predictions for each sample
int[] predicted = machine.Decide(inputs);
// Compute classification accuracy
double acc = new GeneralConfusionMatrix(expected: outputs, predicted: predicted).Accuracy;
You can also try to solve a multiclass decision problem using the one-vs-rest strategy. In this case, you can use the MultilabelSupportVectorLearning teaching algorithm instead of the multi-class one shown above.
Related
This question already has answers here:
Method parameter array default value [duplicate]
(2 answers)
Closed 1 year ago.
I am making an RPG, and I have a monster encounter function where I was adding weight and pattern to enemy attacks, and where I can edit it when calling the function:
Is it possible for arrays and variables to both be parameters in the same function? If not, are there any alternatives to achieve the same goal?
static void MonsterEncounter(float hp = 10, float speed = 3, float attack = 2, string monName = "Monster", float exp = 200F, float gold = 30, bool boss = false, bool doubleBattle = false, bool twoEnemy = false, float hpTwo = 10, float speedTwo = 10, float attackTwo = 1, string monNameTwo = "Monster 2", int teamMate = 0, string status = "Fine", string powerAttack = "Super Hit", float powerAttackHit = 10, float powerAttackHeal = 2, bool isHealing = false, bool isDefending = false, int waitTime = 0, string statusAfflict = "null", bool hasWeight = true, bool hasPattern = false, string statusTwo = "Fine",string powerAttackTwo = "Super Hit", float powerAttackHitTwo = 10, float powerAttackHealTwo = 2, bool isHealingTwo = false, bool isDefendingTwo = false, int waitTimeTwo = 0,string statusAfflictTwo = "null", bool hasWeightTwo = true, bool hasPatternTwo = false, int[] patternTwo = {1, 1, 1, 1, 1,1 ,1, 1, 1, 1}, int[] weight = {0, 0, 0, 0}, int[] pattern = {1, 1, 1, 1, 1,1 ,1, 1, 1, 1}, int[] weightTwo = {0, 0, 0, 0})
but this is relevant:
int[] patternTwo = {1, 1, 1, 1, 1,1 ,1, 1, 1, 1}, int[] weight = {0, 0, 0, 0}, int[] pattern = {1, 1, 1, 1, 1,1 ,1, 1, 1, 1}, int[] weightTwo = {0, 0, 0, 0}
But I kept getting the same error here:
main.cs(4265,254): error CS1525: Unexpected symbol '{'
main.cs(4265,255+): error CS1737: Optional parameter cannot precede required parameters
main.cs(4265,254): error CS1525: Unexpected symbol '1'
I've tried declaring the variables a different way:
int[] patternTwo = new int[10] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, int[] weight = new int[4] {0, 0, 0, 0}, int[] pattern = new int[10] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, int[] weightTwo = new int[4] {0, 0, 0, 0}
But it produced errors still:
main.cs(4265,255+): error CS1736: The expression being assigned to optional parameter 'patternTwo' must be a constant or default value
main.cs(4265,255+): error CS1736: The expression being assigned to optional parameter 'weight' must be a constant or default value
main.cs(4265,255+): error CS1736: The expression being assigned to optional parameter 'pattern' must be a constant or default value
main.cs(4265,255+): error CS1736: The expression being assigned to optional parameter 'weightTwo' must be a constant or default value
I searched through google, but the pages I found were either in a different Programming Language or don't cover what I was asking.
Can I pass an array as arguments to a method with variable arguments in Java?
c# method with unlimited params or method with an array or list?
Passing arrays as arguments (C# Programming Guide)
Passing arrays as arguments in C#
Is it possible for arrays and variables to both be parameters in the same function? If not, are there any alternatives to achieve the same goal?
This is not a "real" solution but more a workaround. You can set the default array value as null and then use if statements to setup your desired arrays values
static void MonsterEncounter(float hp = 10, /*[...]*/ int[] patternTwo = null, int[] weight = null, int[] pattern = null, int[] weightTwo = null){
if (patternTwo == null) { pattern = new int [] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; }
//[...]
if (weightTwo == null) { weightTwo = new int[] { 0, 0, 0, 0 }; }
}
Otherwise, you can also use overloading.
I wan't to have an array result [1000, 0, 0, 500, 0, 0, 0, 0, 3210, 0] from 1 array and sql MySqlDataReader sdr.Read() result.
here are the arrays
ArrayList array1 = new ArrayList()[1,2,3,4,5,6,7,8,9,10];
ArrayList arrayresult = new ArrayList();
while (sdr.Read())
{
transactions.Add(new transaction_details
{
ID = Int32.Parse(sdr["ID"].ToString()),
Transdate = DateTime.Parse(sdr["Transdate"].ToString()),
Debit = Decimal.Parse(sdr["Debit"].ToString()),
TransactionName = sdr["TransactionName"].ToString()
});
}
//arrayresult.add() - what do I do with this ?
If ID in sdr["ID"].ToString() is in array1, then the result would be [ 1, 4, 9]. array1 has 10 index so for final result I want it to be [ 1, 0, 0, 4, 0, 0, 0, 0, 9, 0]. If ID does not exist, 0 will be inserted.
I need arrayresult to have this result.
var debit = [1000, 0, 0 ,500, 0, 0, 0, 0, 3210, 0];
var ID = [ 1, 0, 0, 4, 0, 0, 0, 0, 9, 0];
var date= [ "2020-01-01", 0, 0, "2020-01-02", 0, 0, 0, 0, "2020-01-03", 0];
Short linq pseudo code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
List<int> inp = new List<int>(){1,4,9};
List<int> array1 = new List<int>(){1,2,3,4,5,6,7,8,9,10};
var array1Index = array1.Select((i, index) => new { Index=index, i=i }).ToList();
List<int> arrayresult = new List<int>();
var query = from p in array1Index
select inp.Contains(p.i)==true?p.i:0;
arrayresult = query.ToList();
arrayresult.ForEach(x=>{
Console.Write(x+" ");
});
}
}
I am trying to understand how HMM works, but I think I am missing some crucial part of information that I cannot identify. I want it to predict the next "feature"/"symbol" based on a given sequence.
int[][] sequences =
{
new[] { 10001, 15, 1, 0, 0, 10002 },
new[] { 10002, 0, 1, 0, 15, 10001 },
new[] { 101, 15, 0, 0, 0, 101},
new[] { 101, 0, 0, 0, 15, 101 },
new[] { 114, 15, 0, 1, 0, 114 },
new[] { 114, 0, 0, 1, 15, 114 },
new[] { 10001, 15, 1, 0, 0, 10002 },
new[] { 10002, 0, 1, 0, 15, 10001 },
};
var teacher = new BaumWelchLearning()
{
Topology = new Forward(6),
Tolerance = 0.0001,
};
HiddenMarkovModel hmm = teacher.Learn(sequences);
// Gives 15 instead of 114
int[] prediction = hmm.Predict(observations: new[] { 114, 15, 0, 1, 0 }, next: 1);
The next character for "114, 15, 0, 1, 0" should be 114, yet the prediction is 15. Am I doing something wrong with the topology? Do I need to define something differently?
Thanks in advance!
u can't use statistic/probabilistic to predict one single realization. The theory make sense when u use it in many occurrences. In your case
call :
int[] prediction = hmm.Predict(observations: new[] { 114, 15, 0, 1, 0 }, next: 1);
many times and see what's next observations probs. really is ...
I am using example code below from accord.net framework website, Any ways this code is working fine what i want to achieve is save object to the file..
I want to save DynamicTimeWarping class type object, kernel in following code to the disk(Save in a file)
DynamicTimeWarping kernel = new DynamicTimeWarping(length: 3);
I have tried using XMLSerializer but visual studio is giving error that it can not be serialized because it does not have parameterless constructor.
double[][][] sequences =
{
{
new double[] { 1, 1, 1 }, // first observation of the first sequence
new double[] { 1, 2, 1 }, // second observation of the first sequence
new double[] { 1, 4, 2 }, // third observation of the first sequence
new double[] { 2, 2, 2 }, // fourth observation of the first sequence
},
new double[][] // second sequence (note that this sequence has a different length)
{
new double[] { 1, 1, 1 }, // first observation of the second sequence
new double[] { 1, 5, 6 }, // second observation of the second sequence
new double[] { 2, 7, 1 }, // third observation of the second sequence
},
new double[][] // third sequence
{
new double[] { 8, 2, 1 }, // first observation of the third sequence
},
new double[][] // fourth sequence
{
new double[] { 8, 2, 5 }, // first observation of the fourth sequence
new double[] { 1, 5, 4 }, // second observation of the fourth sequence
}
};
int[] outputs =
{
-1,-1, // First two sequences are of class -1 (those start with {1,1,1})
1, 1, // Last two sequences are of class +1 (don't start with {1,1,1})
};
double[][] inputs = new double[sequences.Length][];
for (int i = 0; i < sequences.Length; i++)
inputs[i] = Matrix.Concatenate(sequences[i]);
// Now we have to setup the Dynamic Time Warping kernel. We will have to
// inform the length of the fixed-length observations contained in each
// arbitrary-length sequence:
//
DynamicTimeWarping kernel = new DynamicTimeWarping(length: 3);
// Now we can create the machine. When using variable-length
// kernels, we will need to pass zero as the input length:
var svm = new KernelSupportVectorMachine(kernel, inputs: 0);
/ / Create the Sequential Minimal Optimization learning algorithm
var smo = new SequentialMinimalOptimization(svm, inputs, outputs)
{
Complexity = 1.5
};
// And start learning it!
double error = smo.Run(); // error will be 0.0
// At this point, we should have obtained an useful machine. Let's
// see if it can understand a few examples it hasn't seem before:
double[][] a =
{
new double[] { 1, 1, 1 },
new double[] { 7, 2, 5 },
new double[] { 2, 5, 1 },
};
double[][] b =
{
new double[] { 7, 5, 2 },
new double[] { 4, 2, 5 },
new double[] { 1, 1, 1 },
};
int resultA = System.Math.Sign(svm.Compute(Matrix.Concatenate(a))); // -1
int resultB = System.Math.Sign(svm.Compute(Matrix.Concatenate(b))); // +1
Looks like this Class in that framework has SerializableAttribute added.
This example should do:
https://msdn.microsoft.com/en-us/library/system.serializableattribute%28v=vs.110%29.aspx
I'm working through the example in the docs for a multi-class support vector machine - http://accord-framework.net/docs/html/T_Accord_MachineLearning_VectorMachines_MultilabelSupportVectorMachine.htm
Though, I'm not getting a 0 error rate, and when I try to compute values, they do not give the output values they should. Is there something wrong with the example?
static void Main(string[] args)
{
// Sample input data
double[][] inputs =
{
new double[] { 0 },
new double[] { 1 },
new double[] { 2 },
new double[] { 3 },
};
// Outputs for each of the inputs
int[][] outputs =
{
new[] {1,-1,-1,-1},
new[] {-1,1,-1,-1},
new[] {-1,-1,1,-1},
new[] {-1,-1,-1,1},
};
// Create a new Linear kernel
IKernel kernel = new Linear();
// Create a new Multi-class Support Vector Machine with one input,
// using the linear kernel and for four disjoint classes.
var machine = new MultilabelSupportVectorMachine(1, kernel, 4);
// Create the Multi-label learning algorithm for the machine
var teacher = new MultilabelSupportVectorLearning(machine, inputs, outputs);
// Configure the learning algorithm to use SMO to train the
// underlying SVMs in each of the binary class subproblems.
teacher.Algorithm = (svm, classInputs, classOutputs, i, j) =>
new SequentialMinimalOptimization(svm, classInputs, classOutputs);
// Run the learning algorithm
double error = teacher.Run();
error = teacher.Run(); // 0.1875 error rate
var answer = machine.Compute(new double[] {2}); // gives -1,-1,-1,-1, instead of -1,-1,1,-1
Should the error rate be zero, and why does it seem that only an input of 0 gives the right output?
To answer the question, it is very likely that there was something wrong with that particular example. Most examples have been updated to reflect the new .Learn() API that was put in place last year.
Now you may see that the documentation page for Multi-label Support Vector Machine has also changed addresses due the new API and is now at
http://accord-framework.net/docs/html/T_Accord_MachineLearning_VectorMachines_MultilabelSupportVectorMachine_1.htm
And now it includes this example, among others:
// Let's say we have the following data to be classified
// into three possible classes. Those are the samples:
//
double[][] inputs =
{
// input output
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 0, 0, 1, 0 }, // 0
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 1, 1, 1, 1 }, // 2
new double[] { 1, 0, 1, 1 }, // 2
new double[] { 1, 1, 0, 1 }, // 2
new double[] { 0, 1, 1, 1 }, // 2
new double[] { 1, 1, 1, 1 }, // 2
};
int[] outputs = // those are the class labels
{
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
2, 2, 2, 2, 2,
};
// Create the multi-class learning algorithm for the machine
var teacher = new MulticlassSupportVectorLearning<Gaussian>()
{
// Configure the learning algorithm to use SMO to train the
// underlying SVMs in each of the binary class subproblems.
Learner = (param) => new SequentialMinimalOptimization<Gaussian>()
{
// Estimate a suitable guess for the Gaussian kernel's parameters.
// This estimate can serve as a starting point for a grid search.
UseKernelEstimation = true
}
};
// Configure parallel execution options
teacher.ParallelOptions.MaxDegreeOfParallelism = 1;
// Learn a machine
var machine = teacher.Learn(inputs, outputs);
// Obtain class predictions for each sample
int[] predicted = machine.Decide(inputs);
// Get class scores for each sample
double[] scores = machine.Score(inputs);
// Compute classification error
double error = new ZeroOneLoss(outputs).Loss(predicted);