I want to ask you if i can use hashing technique with SURF algorithm,i made a program to make face recognition by matching test image with saved image dataset.
i used Accord.net and made bag of features by BOW of this library then I made ID3 decision tree and KNN but the result in both ways were not very good, i am asking if i can use hashing technique to make fast and better result,or this will not be feasible ?
this is the code for BOW
private void button2_Click(object sender, EventArgs e)
{
try
{
var watchFEC = System.Diagnostics.Stopwatch.StartNew();
Accord.Math.Random.Generator.Seed = 0;
bow.ParallelOptions.MaxDegreeOfParallelism = 1;
bow.Learn(DatasetImages);
// After this point, we will be able to translate
// images into double[] feature vectors using
features = bow.Transform(DatasetImages);
watchFEC.Stop();
var elapsedMs = watchFEC.ElapsedMilliseconds;
MessageBox.Show("Feature Extraction and Clastering is done" + '\n' + "Time for Feature Extraction and Clastering for Dataset is: " + elapsedMs.ToString() + " ms");
} catch { MessageBox.Show("Error"); } }
and this is the code for learn
private void button3_Click(object sender, EventArgs e)
{
try
{
var watchLearn = System.Diagnostics.Stopwatch.StartNew();
inputs = features.ToInt32();
tree = teacher.Learn(inputs, outputs);
error = new ZeroOneLoss(outputs).Loss(tree.Decide(inputs));
MessageBox.Show("Error rate of learning is : "+error.ToString());
watchLearn.Stop();
var elapsedMs = watchLearn.ElapsedMilliseconds;
MessageBox.Show("Learning is done" + '\n' + "Time for Learning is: " + elapsedMs.ToString() + " ms");
}
catch(Exception ex) { MessageBox.Show("Error"+ex); }
}
and this code for test
private void button4_Click_1(object sender, EventArgs e)
{
try
{
var watchTest = System.Diagnostics.Stopwatch.StartNew();
Bitmap[] testimage = new Bitmap[1];
testimage[0] = (Bitmap)pictureBox1.Image;
var ff = bow.Transform(testimage);
ff.ToInt32();
var predicted = tree.Decide(ff);
int i = 1;
for (i = 1; i < sizeofdataset; i++)
{
if (predicted[0] == Convert.ToInt16(workSheet.Cells[i, 3].Value.ToString()))
{
listBox1.SelectedItem = i;
MessageBox.Show("Test" + i);
break;
}
}
MessageBox.Show("Test" + predicted[0]);
pictureBox2.Image = new Bitmap(workSheet.Cells[i, 1].Value.ToString());
watchTest.Stop();
var elapsedMs = watchTest.ElapsedMilliseconds;
MessageBox.Show("Time for Testing is: " + elapsedMs.ToString() + " ms");
}
catch (Exception ex) { MessageBox.Show("Error" + ex); }
}
Instead of ID3 or k-NN, please try using a SVM with a Chi-Square kernel.
If you would like to give SVMs a try, there is an example on how to create multi-class kernel SVMs at the bottom of this page (see second example). You can replace all places where it is written "Gaussian" by "ChiSquare" in order to create a chi-square SVM.
If you happen to run in a {"Index was outside the bounds of the array."} as you have indicated in the project's issue tracker, I think you might have a class without training or testing samples. Please make sure you have enough training samples for all classes, that your class numbers start at 0, that the highest class label in your output vector corresponds to the number_of_classes - 1 and that there are no integers in this interval without any associated training samples.
I am posting below an example on how to train SVMs using a Chi-Square kernel in the Accord.NET Framework:
// 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<ChiSquare>()
{
// Configure the learning algorithm to use SMO to train the
// underlying SVMs in each of the binary class subproblems.
Learner = (param) => new SequentialMinimalOptimization<ChiSquare>()
{
// 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 (or leave it at the default value for maximum speed)
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);
Related
The Setup
In my compute-shader I have a StructuredBuffer that is storing an amount of colors. There is also an int variable storing the amount of colors in total ( _colres ). From another script a node tree is dispatched into the shader every frame. The amount of nodes changes dynamically. Because of that the points buffer containing the nodes is at a fixed size of 8192 that the amount of nodes never exceeds.
The Problem
When I'm now trying to draw the points I am storing in the points buffer, oddly enough only every third color is displayed, starting at index [0] (tested for up to 12 colors -> [0],[3],[6],[9]).
Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
What I tried
I used the fmod() function instead but was presented with the same result. Individually targeting stored colors by hard-coding the index has worked so my guess would be that the colors buffer is not the problem. Maybe it has something to do with all the empty spaces in the pointsbuffer but I could't figure it out.
The Question(s)
Is there a fundamental problem I am overlooking?
Is there some other simple way to cycle through the indices of my colorsbuffer that works in this scenario?
Detailed Information
System:
Unity Version 2021.2.12f1 using the HDRP on MacOS Monterey 12.2.1
Compute-Shader
#pragma kernel DrawPoints
// texture
shared RWTexture2D<float4> Result;
int _texres;
int _colres;
// buffer
StructuredBuffer<float2> pointsBuffer;
StructuredBuffer<float4> colorsBuffer;
[numthreads(64,1,1)]
void DrawPoints (uint3 id : SV_DispatchThreadID)
{
if ((pointsBuffer[id.x].x * pointsBuffer[id.x].y) > 0) Result[pointsBuffer[id.x].xy] = colorsBuffer[id.x % _colres];
}
C# Setup
public differentialGrowth diffGrowth;
int texResolution = 4096;
int colorAmount = 12;
RenderTexture settingRef;
Material target;
ComputeShader shader;
RenderTexture outputTexture;
ComputeBuffer pointsBuffer;
ComputeBuffer colorsBuffer;
int pointsHandle;
void Start()
{
outputTexture = new RenderTexture(settingRef);
outputTexture.enableRandomWrite = true;
outputTexture.Create();
// INIT
pointsHandle = shader.FindKernel("DrawPoints");
shader.SetInt("_texres", texResolution);
shader.SetInt("_colres", colorAmount);
int stride = (3) * 4; // every component as a float (3) * 4 bytes per float
pointsBuffer = new ComputeBuffer(8192, stride);
stride = (4) * 4;
colorsBuffer = new ComputeBuffer(colorAmount, stride);
shader.SetTexture( pointsHandle, "Result", outputTexture );
target.SetTexture("_MainTex", outputTexture);
Color[] testColors = new Color[colorAmount];
testColors[0] = new Color(1, 0, 0, 0); //red _ yes
testColors[1] = new Color(0, 1, 0, 0); //green
testColors[2] = new Color(0, 0, 1, 0); //blue
testColors[3] = new Color(1, 1, 0, 0); //yellow _yes
testColors[4] = new Color(0, 1, 1, 0); //cyan
testColors[5] = new Color(1, 0, 1, 0); //magenta
testColors[6] = new Color(0.5f, 0, 1, 0); //mix6 _yes
testColors[7] = new Color(1, 0.5f, 1, 0); //mix7
testColors[8] = new Color(0.5f, 0, 1, 0); //mix8
testColors[9] = new Color(0.5f, 0.5f, 1, 0); //mix9 _yes
testColors[10] = new Color(0.5f, 0.5f, 1, 0); //mix10
testColors[11] = new Color(0.5f, 0.5f, 1, 0); //mix11
}
void Update()
{
pointsBuffer.SetData(diffGrowth.nodes.Points);
shader.SetBuffer(pointsHandle, "colorsBuffer", colorsBuffer);
shader.SetBuffer(pointsHandle, "pointsBuffer", pointsBuffer);
shader.Dispatch(pointsHandle, 128, 1, 1);
}
private void OnDestroy()
{
if (pointsBuffer != null) pointsBuffer.Dispose();
if (colorsBuffer != null) colorsBuffer.Dispose();
}
}
In my project I use or-tools for solving VRPTW problem.
I need to set different waiting time for different nodes.
For example. I have 6 locations.
Depot of vehicle. With max time window (0, 1440)
Pickup point for client 1. Time window (0, 10)
Delivery point for client 1. Time window (0, 50)
Pickup point for client 2. Time window (500, 510)
Delivery point for client 2. Time window (500, 600)
Vehicle service point. With max time window (0, 1440)
If I set slack_max with addDimension
routing.addDimension(transitCallbackIndex, // transit callback
1440, // allow waiting time
60 * 24 * 2,
false, // start cumul to zero
"Time");
My vehicle can wait time in range (0, 1440) in each location. In that case time goes of out range time windows of pickup/delivery node . How can I set slack only for Vehicle service point, because time window for that node is max?
I tried set slack like this
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
but that doesn't work as I expected.
Full code sample:
package test;
import com.google.ortools.Loader;
import com.google.ortools.constraintsolver.Assignment;
import com.google.ortools.constraintsolver.FirstSolutionStrategy;
import com.google.ortools.constraintsolver.IntVar;
import com.google.ortools.constraintsolver.IntervalVar;
import com.google.ortools.constraintsolver.RoutingDimension;
import com.google.ortools.constraintsolver.RoutingIndexManager;
import com.google.ortools.constraintsolver.RoutingModel;
import com.google.ortools.constraintsolver.RoutingSearchParameters;
import com.google.ortools.constraintsolver.Solver;
import com.google.ortools.constraintsolver.main;
import java.util.Arrays;
import java.util.logging.Logger;
/** Minimal VRP with Resource Constraints.*/
public class Test {
// static {
// System.loadLibrary("jniortools");
// }
private static final Logger logger = Logger.getLogger(Test.class.getName());
static class DataModel {
public final long[][] timeMatrix = {
{0, 0, 0, 0, 0, 0},
{0, 0, 10, 0, 10, 0},
{0, 10, 0, 10, 0, 0},
{0, 0, 10, 0, 10, 0},
{0, 10, 0, 10, 0, 0},
{0, 0, 0, 0, 0, 0}
};
public final long[][] timeWindows = {
{0, 1440},
{0, 10}, // 1 from
{0, 50}, // 1 to
{500, 510}, // 2 from
{500, 600}, // 2 to
{0, 1440}, // rest location
};
public final int[][] pickupDeliveries = {
{1, 2},
{3, 4},
};
public final int vehicleNumber = 1;
public final int depot = 0;
}
public static void main(String[] args) throws Exception {
Loader.loadNativeLibraries();
// Instantiate the data problem.
final DataModel data = new DataModel();
// Create Routing Index Manager
RoutingIndexManager manager =
new RoutingIndexManager(data.timeMatrix.length, data.vehicleNumber, data.depot);
// Create Routing Model.
RoutingModel routing = new RoutingModel(manager);
Solver solver = routing.solver();
// Create and register a transit callback.
final int transitCallbackIndex =
routing.registerTransitCallback((long fromIndex, long toIndex) -> {
// Convert from routing variable Index to user NodeIndex.
int fromNode = manager.indexToNode(fromIndex);
int toNode = manager.indexToNode(toIndex);
return data.timeMatrix[fromNode][toNode];
});
// Define cost of each arc.
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
// Add Time constraint.
routing.addDimension(transitCallbackIndex, // transit callback
1440, // allow waiting time
60 * 24 * 2,
false, // start cumul to zero
"Time");
RoutingDimension timeDimension = routing.getMutableDimension("Time");
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
if (index >= 0) {
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
}
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
}
// Add time window constraints for each vehicle start node.
for (int i = 0; i < data.vehicleNumber; ++i) {
long index = routing.start(i);
timeDimension.cumulVar(index).setRange(data.timeWindows[0][0], data.timeWindows[0][1]);
}
// Instantiate route start and end times to produce feasible times.
for (int i = 0; i < data.vehicleNumber; ++i) {
routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.start(i)));
routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.end(i)));
}
// Define Transportation Requests.
for (int[] request : data.pickupDeliveries) {
long pickupIndex = manager.nodeToIndex(request[0]);
long deliveryIndex = manager.nodeToIndex(request[1]);
routing.addPickupAndDelivery(pickupIndex, deliveryIndex);
solver.addConstraint(
solver.makeEquality(routing.vehicleVar(pickupIndex), routing.vehicleVar(deliveryIndex)));
solver.addConstraint(solver.makeLessOrEqual(
timeDimension.cumulVar(pickupIndex), timeDimension.cumulVar(deliveryIndex)));
}
// Setting first solution heuristic.
RoutingSearchParameters searchParameters =
main.defaultRoutingSearchParameters()
.toBuilder()
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
.build();
// Solve the problem.
Assignment solution = routing.solveWithParameters(searchParameters);
if (solution == null) {
System.err.println("No solution found");
return;
}
// Print solution on console.
printSolution(data, routing, manager, solution);
}
/// #brief Print the solution.
static void printSolution(
DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
RoutingDimension timeDimension = routing.getMutableDimension("Time");
long totalTime = 0;
for (int i = 0; i < data.vehicleNumber; ++i) {
long index = routing.start(i);
logger.info("Route for Vehicle " + i + ":");
String route = "";
while (!routing.isEnd(index)) {
IntVar timeVar = timeDimension.cumulVar(index);
route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
+ solution.max(timeVar) + ") -> ";
index = solution.value(routing.nextVar(index));
}
IntVar timeVar = timeDimension.cumulVar(index);
route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
+ solution.max(timeVar) + ")";
logger.info(route);
logger.info("Time of the route: " + solution.min(timeVar) + "min");
totalTime += solution.min(timeVar);
}
logger.info("Total time of all routes: " + totalTime + "min");
}
}
In your code:
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
if (index >= 0) {
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
}
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
}
I think:
here your if conditions should use i,
since your loop start at 1 you already skip the depot (node 0),
your timeWindows structure already contains [0, 1440] for node 5.
to force slack to zero for P&D nodes you should use SetValue()
So you could rewrite it like this:
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
if (i == 5) {
timeDimension.slackVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
} else { // disable waiting time for Pickup&Drop location
timeDimension.slackVar(index).setValue(0);
}
}
possible output:
$ mvn exec:java
[INFO] --- exec-maven-plugin:3.0.0:java (default-cli) # test ---
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Route for Vehicle 0:
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: 0 Time(0,0) -> 1 Time(0,10) -> 2 Time(10,20) -> 5 Time(10,20) -> 3 Time(500,500) -> 4 Time(510,510) -> 0 Time(510,510)
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Time of the route: 510min
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Total time of all routes: 510min
So last question, what do you means by "but that doesn't work as I expected."
What is the observed output and what did you expect ?
I'm working on a project which require streaming video with GStreamer, and then I need to display the video in Unity.
I am now trying a method:
I use the following GStreamer command to put webcam view onto tcp
gst-launch-1.0 v4l2src ! videoconvert ! video/x-raw,width=640,height=480,framerate=20/1 ! jpegenc ! multipartmux ! tcpserversink host=127.0.0.1 port=5000
which can be viewed by GStreamer with:
gst-launch-1.0 tcpclientsrc port=5000 host=127.0.0.1 ! multipartdemux ! jpegdec ! autovideosink
In Unity, I use the following script to get the streaming bytes and decode them
public class _TextureReceiver : MonoBehaviour {
public int port = 5000;
public string IP = "127.0.0.1";
TcpClient client;
[HideInInspector]
public Texture2D texture;
private bool stop = false;
[Header("Must be the same in sender and receiver")]
public int messageByteLength = 24;
// Use this for initialization
void Start() {
Application.runInBackground = true;
client = new TcpClient();
//Connect to server from another Thread
Loom.RunAsync(() => {
// if on desktop
// client.Connect(IPAddress.Loopback, port);
client.Connect(IPAddress.Parse(IP), port);
imageReceiver();
});
}
void imageReceiver() {
//While loop in another Thread is fine so we don't block main Unity Thread
Loom.RunAsync(() => {
while (!stop) {
//Read Image Count
int imageSize = readImageByteSize(messageByteLength);
//Read Image Bytes and Display it
readFrameByteArray(imageSize);
//readFrameByteArray(12288000);
}
});
}
//Converts the byte array to the data size and returns the result
int frameByteArrayToByteLength(byte[] frameBytesLength) {
/*if (BitConverter.IsLittleEndian)
{
Array.Reverse(frameBytesLength);
UnityEngine.Debug.Log("- BitConverter.IsLittleEndian");
}*/
var sb = new StringBuilder("frameBytesLength[] { ");
foreach (var b in frameBytesLength)
{
sb.Append(b + ", ");
}
sb.Append("}");
UnityEngine.Debug.Log(sb.ToString());
//int byteLength = BitConverter.ToInt32(frameBytesLength, 0);
int byteLength = frameBytesLength[0] + frameBytesLength[1] * 256;
return byteLength;
}
private int readImageByteSize(int size) {
UnityEngine.Debug.Log("- image byte size: " + size);
bool disconnected = false;
NetworkStream serverStream = client.GetStream();
UnityEngine.Debug.Log("- serverStream: " + serverStream);
byte[] imageBytesCount = new byte[size];
var total = 0;
do {
var read = serverStream.Read(imageBytesCount, total, size - total);
UnityEngine.Debug.LogFormat("Client recieved "+read+" bytes");
if (read == 0)
{
disconnected = true;
break;
}
total += read;
UnityEngine.Debug.Log("- image byte read: " + read);
UnityEngine.Debug.Log("- image byte total: " + total);
} while (total != size);
UnityEngine.Debug.Log("- break While");
int byteLength;
if (disconnected) {
UnityEngine.Debug.Log("disconnected");
byteLength = -1;
} else {
byteLength = frameByteArrayToByteLength(imageBytesCount);
}
return byteLength;
}
private void readFrameByteArray(int size) {
bool disconnected = false;
UnityEngine.Debug.Log("- image size: " + size);
NetworkStream serverStream = client.GetStream();
byte[] imageBytes = new byte[size];
var total = 0;
//do{
var read = serverStream.Read(imageBytes, total, size - total);
if (read == 0)
{
disconnected = true;
//break;
}
total += read;
UnityEngine.Debug.Log("- read: " + read);
UnityEngine.Debug.Log("- total: " + total);
//} while (total != size);
byte[] imageBytes2 = new byte[read];
imageBytes.CopyTo(imageBytes2, 0);
UnityEngine.Debug.Log("break while");
var sb = new StringBuilder("imageBytes[] { ");
foreach (var b in imageBytes2)
{
sb.Append(b + ", ");
}
sb.Append("}");
UnityEngine.Debug.Log(sb.ToString());
bool readyToReadAgain = false;
//Display Image
if (!disconnected) {
//Display Image on the main Thread
Loom.QueueOnMainThread(() => {
loadReceivedImage(imageBytes2);
readyToReadAgain = true;
});
}
//Wait until old Image is displayed
while (!readyToReadAgain) {
System.Threading.Thread.Sleep(1);
}
}
void loadReceivedImage(byte[] receivedImageBytes) {
if(texture) texture.LoadImage(receivedImageBytes);
}
public void SetTargetTexture (Texture2D t) {
texture = t;
}
void OnApplicationQuit() {
stop = true;
if (client != null) {
client.Close();
}
}
}
However, It's not working.
I think it is because the encoding method and decoding method does not match, but I don't know how to interpretate GStreamer's byte sequence.
At int imageSize = readImageByteSize(messageByteLength);,
the imageSize should be computed with an incoming byte that look something like this:
frameBytesLength[] { 196, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
But instead it look like this:
frameBytesLength[] { 255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, }
causing the size is too large that it goes negative, and thus can not continue the decoding process.
That's what I've ot so far.
Here is the reference of Unity code:
https://github.com/BarakChamo/uTextureSendReceive
p.s. I'm using Linux, so I cannot use mray GStreamer Unity Plugin since it does not support Linux.
Thank you for your time.
I over come this problem in a way that is not very elegant...
I just assign a fixed max-byte-size to every frame that is received.
It's not the best way, but that's working for me.
I have a test program that does not give consistent results for Accord.Net K-Means.
I am enclosing a reproducible test program that can be run in Visual Studio 2013.
The program is a console application and to reproduce the results you need to reference:
Accord.MachineLearning
Accord.Statistics,
from the Accord.Net 2.15 library.
When I run the program several times I get different results each time. The program uses the classic Fisher Iris dataset. The dataset has 150 rows, and I split the data into 120 rows of training data and 30 rows of testing data.
When I run the program I might get 26 out of 30 classified correctly. Running it again may produce 2 out of 30 correct.
For example:
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
I am wondering if I am correctly using Accord.Net. Any help will be greatly appreciated.
My program is:
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();
}
}
}
K-means is not a classification algorithm.
But it is a randomized algorithm, so it's not surprise you get different results every time.
Now since it is randomized the labels used by k-means are random, too.
So 2 out of 30 correct may be the same as 28 out of 30 correct (just the labels shuffled).
Run it again, and it may yield the same clusters, but with the "labels" all mixed up. (In fact, it doesn't know about iris species. It labels objects 0,1,2; not "iris setosa")
I am trying to implement the queue using an array. But my implementation is not working. I couldn't find the mistake. My implementations are as follows:
class ArrayQueue[T: ClassManifest] extends Queue[T] {
private var A = new Array[T](2) // array for storing the queue elements
private var front = 0 // index of the front element in the array
private var rear = 0 // index of the rear element in the array
private var item_num = 0 // number of elements that are in the array
// when an array overflows we double the size of the array
private def grow() {
val B = A
A = new Array[T](2 * B.length)
if (front < rear) {
for ( i <- 0 until B.length)
A(i) = B(i)
}
else {
System.arraycopy(B, rear, A, 0, B.length - rear)
System.arraycopy(B, 0, A, B.length-rear, front)
front = B.length - (rear - front)
rear = 0
}
}
def clear(): Unit = {
A = new Array[T](22)
front = 0
rear = 0
item_num = 0
}
def isEmpty: Boolean = (item_num == 0)
def head = {
if (isEmpty)
throw new NoSuchElementException
A(front)
}
def dequeue(): T = {
if (isEmpty)
throw new NoSuchElementException
front += 1
item_num = item_num - 1
A(front - 1)
}
def enqueue(elem: T): Unit = {
A(rear) = elem
rear += 1
item_num += 1
if (rear == A.length - 1 && item_num != A.length)
rear = 0
if (item_num == A.length || rear == front - 1) {
grow()
}
if (item_num == 0) {
front = 0
rear = 0 }
}
Queue has 5 methods including enqueue, dequeue, isEmpty, clear, head.
In my code head method returns the element at front position
isEmpty returns true if item_num = 0
Clear method clears the queue
Method enqueue must add elements after rear and increase the rear by 1. I think I have some mistake here
Method dequeue returns the first element and removes it.
However, I am having an error. Can you please tell me some hints? Thank you in advance.
To put it simply, in a circular array, whenever a pointer moves, you have to check it and fix it if necessary. You don't do that in dequeue.
The logic inside enqueue is not correct either.
Finally, you have two pointers and a counter. You shouldn't need three things, only two.
There are lots of logical errors. Its hard to find any correct thing implemented in your code.
trying answering following
(1) do you really need to do front = B.length - (rear - front) inside grow() when you already know that grow()is called when the array/queue is full
(2) in case if the if() condition evaluates to true, what are you doing?
let say initially A=[1 2 3 4], front =3, rear =2, then your new array will be [1 2 3 4 0 0 0 0] with same front and rear values. Is it valid?
(3) check the enque and deque logics also.
(4) consider serialization of the queue data otherwise it will go in an inconsistent state.
(5) to ease, you can simply use rear = (rear+1)%length no need to check,no ifs needed.
I am posting the complete code here to implement circular queue using array in java.
trim(): trim the size of array.
package com.java.util.collection.advance.datastructure.queue;
public interface Queue<E>{
boolean addR(E e);
E removeL();
E element();
boolean isFull();
boolean isEmpty();
void trim();
}
package com.java.util.collection.advance.datastructure.queue;
public interface CircularQueue<E> extends Queue<E>{
}
package com.java.util.collection.advance.datastructure.queue;
import java.util.Arrays;
public class MyCircularQueue<E> implements CircularQueue<E>{
private int front = 0;
private int rear =-1;
private E[] elements =null;
private static final int DEFAULT_INTIAL_CAPACITY =100;
private int size =0;
public MyCircularQueue(){
this(DEFAULT_INTIAL_CAPACITY);
}
#SuppressWarnings("unchecked")
public MyCircularQueue(int intialCapacity){
if(intialCapacity < 0){
throw new IllegalArgumentException("intial capacity can't be null");
}
elements =(E[]) new Object[intialCapacity];
}
#Override
public boolean addR(E e) {
if(! isFull()) {
rear = (rear+1)%elements.length;
elements[rear] = e;
size++;
return true;
}
return false;
}
#Override
public E removeL() {
E element =null;
if(!isEmpty()){
if(front == elements.length-1)
{
front =(front+1)%elements.length;
}
element=elements[front];
// Nullify the reference
elements[front] =null;
front++;
--size;
}
return element;
}
#Override
public E element() {
E element =null;
if(!isEmpty()){
element=elements[front];
}
return element;
}
#Override
public boolean isFull() {
return size == elements.length;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
// Do Nothing
public void trim() {
#SuppressWarnings("unchecked")
E[]dest =(E[]) new Object[size];
if(front < rear) {
System.arraycopy(elements, front, dest, front-1,rear);
} else {
System.arraycopy(elements, front, dest, 0, size-front+1);
System.arraycopy(elements, 0, dest, size-front+1, front-rear);
front =0;
rear = size;
}
elements =dest;
}
#Override
public String toString() {
return "MyCircularQueue [front=" + front + ", rear=" + rear
+ ", elements=" + Arrays.toString(elements) + ", size=" + size
+ "]";
}
}
Test class:
package com.java.util.collection.advance.datastructure.queue;
import java.util.Random;
public class MyCircularQueueApp<E> {
public static void main(String[] args) {
CircularQueue<Integer> cirQueue =new MyCircularQueue<Integer>(11);
Random random =new Random();
for(int i=0;i<10;i++){
cirQueue.addR(random.nextInt(3));
}
System.out.println(cirQueue);
cirQueue.removeL();
System.out.println("Before triming: "+cirQueue);
cirQueue.trim();
System.out.println("After triming: "+cirQueue);
cirQueue.removeL();
System.out.println(cirQueue);
cirQueue.addR(1000);
System.out.println(cirQueue);
cirQueue.addR(10000);
cirQueue.addR(100000);
System.out.println(cirQueue);
System.out.println(cirQueue.element());
}
}
Output:
MyCircularQueue [front=0, rear=9, elements=[1, 2, 2, 2, 1, 2, 2, 1, 2, 1, null], size=10]
Before triming: MyCircularQueue [front=1, rear=9, elements=[null, 2, 2, 2, 1, 2, 2, 1, 2, 1, null], size=9]
After triming: MyCircularQueue [front=1, rear=9, elements=[2, 2, 2, 1, 2, 2, 1, 2, 1], size=9]
MyCircularQueue [front=2, rear=9, elements=[2, null, 2, 1, 2, 2, 1, 2, 1], size=8]
MyCircularQueue [front=2, rear=1, elements=[2, 1000, 2, 1, 2, 2, 1, 2, 1], size=9]
MyCircularQueue [front=2, rear=1, elements=[2, 1000, 2, 1, 2, 2, 1, 2, 1], size=9]