Accord.Net K-Means で一貫した結果が得られないテスト プログラムがあります。
Visual Studio 2013 で実行できる再現可能なテスト プログラムを同封しています。
このプログラムはコンソール アプリケーションであり、参照する必要がある結果を再現するには:
Accord.MachineLearning
Accord.Statistics,
Accord.Net 2.15 ライブラリから。
プログラムを数回実行すると、毎回異なる結果が得られます。このプログラムは、従来の Fisher Iris データセットを使用します。データセットには 150 行あり、データを 120 行のトレーニング データと 30 行のテスト データに分割します。
プログラムを実行すると、30 のうち 26 が正しく分類される可能性があります。もう一度実行すると、30 問中 2 問正解できます。
例えば:
Number correct: 2 out of 30
FScore: NaN
Precision: 0
True Positives: 0
False Positives: 9
True Negatives: 9
False Negatives: 12
Accuracy: 0.3
Standard Error: 0.107268513868515
Variance: 0.0115065340675597
Accord.Net を正しく使用しているかどうか疑問に思っています。どんな助けでも大歓迎です。
私のプログラムは次のとおりです。
using System;
using System.IO;
using System.Net;
using Accord.MachineLearning;
using Accord.Statistics.Analysis;
namespace K_Keans {
#region K_Means
public static class K_Means {
private static KMeans kmeans;
#region DowloadIrisData
private static void DowloadIrisData(out double[][] predictors, out int[] targets) {
using (var fileDownloader = new WebClient()) {
// http://www.math.uah.edu/stat/data/Fisher.html
// The dataset gives Ronald Fisher's measurements of type, petal width (PW), petal length (PL),
// sepal width (SW), and sepal length (SL) for a sample of 150 irises, measured in millimeters.
// Type 0 is Setosa; type 1 is Verginica; and type 2 is Versicolor.
const string webLocation = @"http://www.math.uah.edu/stat/data/Fisher.csv";
const string fileName = @"c:\Temp\iris.csv";
fileDownloader.DownloadFile(webLocation, fileName);
var s = File.ReadAllText(fileName);
var sarray = s.Split('\n');
var nrows = sarray.Length - 2;
var ncols = sarray[0].Split(',').Length;
predictors = new double[nrows][];
targets = new int[nrows];
for (var j=1; j<=nrows; j++) {
predictors[j-1] = new double[ncols-1];
var line = sarray[j].Split(',');
for (var k = 1; k < ncols; k++) {
targets[j-1] = Convert.ToInt32(line[0]);
predictors[j-1][k-1] = Convert.ToDouble(line[k]);
}
}
}
}
#endregion
#region IrisData
public static void IrisData(out double[][] trainingData, out int[] expectedTrainingTargets,
out double[][] testingData, out int[] expectedTestingTargets) {
double[][] predictors;
int[] targets;
DowloadIrisData(out predictors, out targets);
var nRows = predictors.Length;
var nCols = predictors[0].Length;
var nRowsTesting = Convert.ToInt32(0.2*nRows);
var nRowsTraining = nRows - nRowsTesting;
trainingData = new double[nRowsTraining][];
expectedTrainingTargets = new int[nRowsTraining];
for (var k = 0; k < nRowsTraining; k++) {
trainingData[k] = new double[nCols];
Array.Copy(predictors[k], trainingData[k], nCols);
expectedTrainingTargets[k] = targets[k];
}
testingData = new double[nRowsTesting][];
expectedTestingTargets = new int[nRowsTesting];
for (var k = 0; k < nRowsTesting; k++) {
testingData[k] = new double[nCols];
Array.Copy(predictors[nRows-nRowsTesting+k], testingData[k], nCols);
expectedTestingTargets[k] = targets[nRows-nRowsTesting+k];
}
}
#endregion
#region Train
public static void Train(double[][] trainingData, out int[] predicted) {
kmeans = new KMeans(3) {
Tolerance = 1e-5,
ComputeInformation = true
};
predicted = kmeans.Compute(trainingData);
}
#endregion
#region Test
public static void Test(double[][] testingData, out int[] predicted) {
var nRowsTesting = testingData.Length;
predicted = new int[nRowsTesting];
for (var k = 0; k < nRowsTesting; k++) {
predicted[k] = kmeans.Clusters.Nearest(testingData[k]);
}
}
#endregion
}
#endregion
class Program {
static void Main(string[] args) {
double[][] trainingData, testingData;
int[] expectedTrainingTargets, expectedTestingTargets;
K_Means.IrisData(out trainingData, out expectedTrainingTargets, out testingData, out expectedTestingTargets);
int[] predictedTrainingTargets;
K_Means.Train(trainingData, out predictedTrainingTargets);
int[] predictedTestingTargets;
K_Means.Test(testingData, out predictedTestingTargets);
var confusionMatrix = new ConfusionMatrix(predictedTestingTargets, expectedTestingTargets);
var nCorrect = 0;
var nRows = expectedTestingTargets.Length;
for (var k=0; k<nRows; k++) {
if (predictedTestingTargets[k] == expectedTestingTargets[k]) { nCorrect++; }
}
Console.WriteLine(" Number correct: {0} out of {1}", nCorrect, nRows);
Console.WriteLine(" FScore: {0}", confusionMatrix.FScore);
Console.WriteLine(" Precision: {0}", confusionMatrix.Precision);
Console.WriteLine(" True Positives: {0}", confusionMatrix.TruePositives);
Console.WriteLine("False Positives: {0}", confusionMatrix.FalsePositives);
Console.WriteLine(" True Negatives: {0}", confusionMatrix.TrueNegatives);
Console.WriteLine("False Negatives: {0}", confusionMatrix.FalseNegatives);
Console.WriteLine(" Accuracy: {0}", confusionMatrix.Accuracy);
Console.WriteLine(" Standard Error: {0}", confusionMatrix.StandardError);
Console.WriteLine(" Variance: {0}", confusionMatrix.Variance);
Console.WriteLine(" ");
Console.WriteLine("Hit enter to exit.");
Console.ReadKey();
}
}
}