2013-05-24 7 views
5

Kann mir jemand zeigen, wie man eine SVM-Klassifizierung mit mehreren Klassen in Encog 3.1 verwendet?SVM-Klassifizierung für mehrere Klassen in Encog

Ich habe ihre Neuronalen Netze mit einigem Erfolg verwendet, kann aber nicht herausfinden, wie man eine SVM mit mehreren Klassen aufbaut.

Die docs haben folgende zu sagen:.

„Dies ist ein Netzwerk, das von einem oder mehrere Support Vector Machines (SVM) gesichert ist so konzipiert, ist sehr ähnlich wie ein Encog neuronales Netzwerk funktionieren, und sind weitgehend austauschbar mit einem neuralen Encog-Netzwerk ..... Klassifizierung wird verwendet, wenn die SVM die Eingabedaten in eine oder mehrere Klassen gruppieren soll Support Vector Machines haben typischerweise einen einzigen Ausgang Neuronale Netzwerke können mehrere Ausgabe-Neuronen haben In diesem Fall erstellt diese Klasse mehrere SVMs, wenn mehr als eine Ausgabe angegeben ist. "

. Ich kann jedoch nicht sehen, wie mehrere Ausgaben angegeben werden, in der Tat die Ausgabeeigenschaft gibt einfach 1:

/// <value>For a SVM, the output count is always one.</value> 
    public int OutputCount 
    { 
     get { return 1; } 
    } 

Antworten in Java oder C# sind sehr geschätzt

EDIT noch nicht dieses heraus zu arbeiten. Wirklich genießen mit Encog, aber das Support-Forum ist ziemlich mit nur Jeff Heaton (Autor des Projekts) selbst beantwortet, wenn er eine Chance bekommt, so bin ich den Projektcode verknüpfen und ein Kopfgeld in der Hoffnung, dass jemand sehen kann, was ich offensichtlich vermisse.

Das Projekt: http://heatonresearch.com/

Die SupportVectorMachine Klasse auf Google Code: https://code.google.com/p/encog-cs/source/browse/trunk/encog-core/encog-core-cs/ML/SVM/SupportVectorMachine.cs

Antwort

4

Entschuldigung für die langsame Antwort. Ich habe beschlossen, dies zu einer FAQ für Encog zu machen. Sie können das FAQ & Beispiel hier sehen. http://www.heatonresearch.com/faq/5/2

Grundsätzlich Encog unterstützt Multi-Class-SVM. Sie brauchen nicht mehrere Ausgänge wie ein neuronales Netzwerk. Sie trainieren es einfach mit einer einzigen Ausgabe, und diese Ausgabe ist die Klassennummer, d. H. 0.0, 1.0, 2.0 usw. Abhängig davon, wie viele Klassen Sie haben.

Dies gilt sowohl für die Java-und C# -Versionen von Encog. Ich habe das Beispiel in C# gemacht.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Encog.ML.SVM; 
using Encog.ML.Data; 
using Encog.ML.Data.Basic; 
using Encog.ML.Train; 
using Encog.ML.SVM.Training; 

namespace MultiClassSVM 
{ 
    class Program 
    { 
     /// 
     /// Input for function, normalized to 0 to 1. 
     /// 
     public static double[][] ClassificationInput = { 
      new[] {0.0, 0.0}, 
      new[] {0.1, 0.0}, 
      new[] {0.2, 0.0}, 
      new[] {0.3, 0.0}, 
      new[] {0.4, 0.5}, 
      new[] {0.5, 0.5}, 
      new[] {0.6, 0.5}, 
      new[] {0.7, 0.5}, 
      new[] {0.8, 0.5}, 
      new[] {0.9, 0.5} 
      }; 

     /// 
     /// Ideal output, these are class numbers, a total of four classes here (0,1,2,3). 
     /// DO NOT USE FRACTIONAL CLASSES (i.e. there is no class 1.5) 
     /// 
     public static double[][] ClassificationIdeal = { 
      new[] {0.0}, 
      new[] {0.0}, 
      new[] {0.0}, 
      new[] {0.0}, 
      new[] {1.0}, 
      new[] {1.0}, 
      new[] {2.0}, 
      new[] {2.0}, 
      new[] {3.0}, 
      new[] {3.0} 
     }; 

     static void Main(string[] args) 
     { 
      // create a neural network, without using a factory 
      var svm = new SupportVectorMachine(2, false); // 2 input, & false for classification 

      // create training data 
      IMLDataSet trainingSet = new BasicMLDataSet(ClassificationInput, ClassificationIdeal); 

      // train the SVM 
      IMLTrain train = new SVMSearchTrain(svm, trainingSet); 

      int epoch = 1; 

      do 
      { 
       train.Iteration(); 
       Console.WriteLine(@"Epoch #" + epoch + @" Error:" + train.Error); 
       epoch++; 
      } while (train.Error > 0.01); 

      // test the SVM 
      Console.WriteLine(@"SVM Results:"); 
      foreach (IMLDataPair pair in trainingSet) 
      { 
       IMLData output = svm.Compute(pair.Input); 
       Console.WriteLine(pair.Input[0] 
            + @", actual=" + output[0] + @",ideal=" + pair.Ideal[0]); 
      } 

      Console.WriteLine("Done"); 
     } 
    } 
}
+0

Großartig, danke für die Antwort, weiß nicht, warum ich nicht daran gedacht habe, das zu versuchen. Das Finden von Encog ist sehr nützlich. – Steve

+0

Verwenden Sie nicht einfach Regression für die Klassifizierung? http://stackoverflow.com/questions/9160669/why-is-it-not-to-approach-classification-through-regression –

+0

Einverstanden, es ist schlecht, Regression zu verwenden, um Klassifizierung zu tun, aber so ist hier nicht der Fall. In Encog wird eine SVM im Konstruktor entweder als Regression oder als Klassifizierung bezeichnet. Dies sind zwei sehr unterschiedliche Setups für SVMs. Beachten Sie, dass der Konstruktor einen falschen Wert hat, dh es handelt sich um eine Klassifizierung. Daher sind Werte von 1.0, 2.0 usw. Klassennummern. Es verwendet immer eine Gleitkommaeingabe für Konsistenz. – JeffHeaton

1

Sie können nicht mehrklassige SVM haben. SVMs können nur in zwei Klassen klassifiziert werden. Es gibt natürlich Methoden, wie man sie für die Klassenklassifikation verwenden kann. Sie sind Eins-gegen-Eins und Eins-gegen-alle.

In One-vs-One trainierst du (k * (k-1))/2 SVMs für jedes Klassenpaar. Dann lassen Sie sie wählen und die Klasse mit den meisten Stimmen gewinnt.

In one-vs-all haben Sie nur k SVMs und für jede Klasse trainieren Sie eine SVM gegen den Rest der Klassen und wieder lassen Sie sie wählen und wählen Sie den Gewinner.

Ich weiß nicht, ob es eine Unterstützung für One-vs-One und One-vs-All in Encog gibt, Sie könnten es im schlimmsten Fall selbst schreiben. Ich bin mir jedoch sicher, dass Sie sich den falschen Teil der Codebasis ansehen. Es wird höchstwahrscheinlich nicht in der Implementierung der SVM sein.

+0

Vielen Dank für Ihre Antwort, ich kann am Ende schreiben meine eigene Implementierung oder einfach zurück zur Verwendung von Accord NET, aber ich bin sicher, es muss Unterstützung dafür in Encog gebaut werden.Die Dokumente, die ich hervorgehoben habe, weisen darauf hin. – Steve