This is a work in progress. I will add training and demonstrate that as my final project.
static final String IRIS_DATASET_FILENAME = "iris.json";
// Keys used at the top level of the JSON dictionary
static final String DATA_KEY = "data";
// Keys used in each iris data record
static final String SEPAL_LENGTH_KEY = "sepalLength";
static final String SEPAL_WIDTH_KEY = "sepalWidth";
static final String PETAL_LENGTH_KEY = "petalLength";
static final String PETAL_WIDTH_KEY = "petalWidth";
static final String SPECIES_KEY = "species";
// The allowed values for species:
static final String[] ALLOWED_SPECIES = {"setosa", "versicolor", "virginica"};
interface IsAnInputSource {
// To be an input source for something that requires an input source,
// an object must be able to compute outputs
float getOutput(int index) throws InputSourceNotSetException;
// It must also be able to report its size
int getSize();
}
interface RequiresAnInputSource {
// An object that requires an input source will throw an exception if it hasn't had an input source set
// It will also throw an exception if the input source is the wrong size.
void setInputSource(IsAnInputSource inputSource) throws InputSourceSizeMismatchException;
}
class InputSourceNotSetException extends Exception {
}
class InputSourceSizeMismatchException extends Exception {
}
class Layer implements IsAnInputSource, RequiresAnInputSource {
Neuron[] neurons;
IsAnInputSource inputSource = null;
Layer(int inputsPerNeuron, int neuronsCount) {
neurons = new Neuron[neuronsCount];
for (int i = 0; i < neuronsCount; ++i) {
neurons[i] = new Neuron(inputsPerNeuron + 1);
}
}
void setInputSource(IsAnInputSource inputSource_) throws InputSourceSizeMismatchException {
if (inputSource_.getSize() != neurons.length * (neurons[0].weights.length - 1)) {
println("inputSource_.getSize() is " + inputSource_.getSize());
println("neurons.length is " + neurons.length);
println("neurons[0].weights.length - 1 " + (neurons[0].weights.length - 1));
throw new InputSourceSizeMismatchException();
}
inputSource = inputSource_;
}
float getOutput(int index) throws InputSourceNotSetException {
if (inputSource == null) {
throw new InputSourceNotSetException();
}
return neurons[index].feedForward();
}
int getSize() {
return neurons.length;
}
}
class TwoLayerNeuralNet implements IsAnInputSource, RequiresAnInputSource {
Layer inputLayer;
Layer outputLayer;
TwoLayerNeuralNet(int inputsCount, int outputsCount) throws InputSourceSizeMismatchException {
inputLayer = new Layer(inputsCount, outputsCount);
outputLayer = new Layer(outputsCount, 1);
outputLayer.setInputSource(inputLayer);
}
void setInputSource(IsAnInputSource inputSource_) throws InputSourceSizeMismatchException {
inputLayer.setInputSource(inputSource_);
}
float getOutput(int index) throws InputSourceNotSetException {
return outputLayer.getOutput(index);
}
int getSize() {
return outputLayer.getSize();
}
float[] softMax() throws InputSourceNotSetException {
float[] values = new float[getSize()];
float sum = 0.0;
for (int i = 0; i < values.length; ++i) {
values[i] = exp(getOutput(i));
sum += values[i];
}
for (int i = 0; i < values.length; ++i) {
values[i] /= sum;
}
return values;
}
int classify() throws InputSourceNotSetException {
float[] softMax = softMax();
float biggest = softMax[0];
int classification = 0;
for (int i = 1; i < softMax.length; ++i) {
if (softMax[i] > biggest) {
biggest = softMax[i];
classification = i;
}
}
return classification;
}
}
class Neuron implements RequiresAnInputSource {
float[] weights;
float learningRate = 0.01;
IsAnInputSource inputSource = null;
// Constructor. Takes one variable which is the number of
// inputs. There is actually one more weight than the number
// of inputs. The extra weight is for the bias.
// Initializes the weights of the neuron randomly.
// Later the weights will be trained.
Neuron(int n) {
weights = new float[n + 1];
for (int i = 0; i <= n; ++i) {
weights[i] = random(-1, 1);
}
}
void setInputSource(IsAnInputSource inputSource_) throws InputSourceSizeMismatchException {
if (inputSource_.getSize() != weights.length - 1) {
throw new InputSourceSizeMismatchException();
}
inputSource = inputSource_;
}
float feedForward() throws InputSourceNotSetException {
if (inputSource != null) {
throw new InputSourceNotSetException();
}
float sum = 0.0;
for (int i = 0; i < weights.length - 1; ++i) {
sum += inputSource.getOutput(i) * weights[i];
}
sum += weights[weights.length - 1];
float output = activate(sum);
return output;
}
float activate(float sum) {
// We use the classic sigmoid function for activation. See:
// https://machinelearningmastery.com/a-gentle-introduction-to-sigmoid-function/
return 1.0 / (1.0 + exp(-sum));
}
}
abstract class FloatingPointDataset implements IsAnInputSource {
float[][] records;
int[] classifications;
int recordPointer = 0;
int recordCount = 0;
float getOutput(int index) throws InputSourceNotSetException {
return records[recordPointer][index];
}
int getClassification() {
return classifications[recordPointer];
}
int getSize() {
return records[0].length;
}
int recordPointer() {
return recordPointer;
}
void setRecordPointer(int recordPointer_) {
recordPointer = recordPointer_;
}
}
class IrisDataset extends FloatingPointDataset {
void configure(JSONObject json) {
JSONArray data = json.getJSONArray(DATA_KEY);
recordCount = data.size();
classifications = new int[recordCount];
// for convenience convert allowed species to an ArrayList
ArrayList <String> allowedSpecies = new ArrayList <String>();
for (String species : ALLOWED_SPECIES) {
allowedSpecies.add(species);
}
records = new float[recordCount][4];
for (int i = 0; i < recordCount; ++i) {
JSONObject irisRecord = data.getJSONObject(i);
String species = irisRecord.getString(SPECIES_KEY);
int index = allowedSpecies.indexOf(species);
classifications[i] = index;
records[i][0] = irisRecord.getFloat(SEPAL_LENGTH_KEY);
records[i][1] = irisRecord.getFloat(SEPAL_WIDTH_KEY);
records[i][2] = irisRecord.getFloat(PETAL_LENGTH_KEY);
records[i][3] = irisRecord.getFloat(PETAL_WIDTH_KEY);
}
}
}
TwoLayerNeuralNet neuralNet;
IrisDataset irisDataset;
void setup() {
size(600, 400);
frameRate(30);
irisDataset = new IrisDataset();
JSONObject json = loadJSONObject(IRIS_DATASET_FILENAME);
irisDataset.configure(json);
try {
neuralNet = new TwoLayerNeuralNet(4, 3);
} catch (InputSourceSizeMismatchException e) {
e.printStackTrace(System.out);
}
try {
neuralNet.setInputSource(irisDataset);
} catch (InputSourceSizeMismatchException e) {
e.printStackTrace(System.out);
}
}
void draw() {
int recordPointer = frameCount % irisDataset.recordCount;
irisDataset.setRecordPointer(recordPointer);
int classification = 0;
try {
classification = neuralNet.classify();
} catch (InputSourceNotSetException e) {
e.printStackTrace(System.out);
}
println("Record " + recordPointer + " is classified as " + ALLOWED_SPECIES[classification]);
}
Save the json data below iris.json and add the file to the Processing sketch:
{
"source": "https://www.kaggle.com/datasets/rtatman/iris-dataset-json-version?resource=download",
"citation": "Fisher, R. A. (1936) The use of multiple measurements in taxonomic problems. Annals of Eugenics, 7, Part II, 179–188.",
"data": [
{
"sepalLength": 5.1,
"sepalWidth": 3.5,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.9,
"sepalWidth": 3.0,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.7,
"sepalWidth": 3.2,
"petalLength": 1.3,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.6,
"sepalWidth": 3.1,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.6,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.9,
"petalLength": 1.7,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 4.6,
"sepalWidth": 3.4,
"petalLength": 1.4,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.4,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.4,
"sepalWidth": 2.9,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.9,
"sepalWidth": 3.1,
"petalLength": 1.5,
"petalWidth": 0.1,
"species": "setosa"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.7,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.8,
"sepalWidth": 3.4,
"petalLength": 1.6,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.8,
"sepalWidth": 3.0,
"petalLength": 1.4,
"petalWidth": 0.1,
"species": "setosa"
},
{
"sepalLength": 4.3,
"sepalWidth": 3.0,
"petalLength": 1.1,
"petalWidth": 0.1,
"species": "setosa"
},
{
"sepalLength": 5.8,
"sepalWidth": 4.0,
"petalLength": 1.2,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.7,
"sepalWidth": 4.4,
"petalLength": 1.5,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.9,
"petalLength": 1.3,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.5,
"petalLength": 1.4,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 5.7,
"sepalWidth": 3.8,
"petalLength": 1.7,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.8,
"petalLength": 1.5,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.4,
"petalLength": 1.7,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.7,
"petalLength": 1.5,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 4.6,
"sepalWidth": 3.6,
"petalLength": 1.0,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.3,
"petalLength": 1.7,
"petalWidth": 0.5,
"species": "setosa"
},
{
"sepalLength": 4.8,
"sepalWidth": 3.4,
"petalLength": 1.9,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.0,
"petalLength": 1.6,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.4,
"petalLength": 1.6,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 5.2,
"sepalWidth": 3.5,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.2,
"sepalWidth": 3.4,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.7,
"sepalWidth": 3.2,
"petalLength": 1.6,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.8,
"sepalWidth": 3.1,
"petalLength": 1.6,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.4,
"petalLength": 1.5,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 5.2,
"sepalWidth": 4.1,
"petalLength": 1.5,
"petalWidth": 0.1,
"species": "setosa"
},
{
"sepalLength": 5.5,
"sepalWidth": 4.2,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.9,
"sepalWidth": 3.1,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.2,
"petalLength": 1.2,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.5,
"sepalWidth": 3.5,
"petalLength": 1.3,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.9,
"sepalWidth": 3.6,
"petalLength": 1.4,
"petalWidth": 0.1,
"species": "setosa"
},
{
"sepalLength": 4.4,
"sepalWidth": 3.0,
"petalLength": 1.3,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.4,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.5,
"petalLength": 1.3,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 4.5,
"sepalWidth": 2.3,
"petalLength": 1.3,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 4.4,
"sepalWidth": 3.2,
"petalLength": 1.3,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.5,
"petalLength": 1.6,
"petalWidth": 0.6,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.8,
"petalLength": 1.9,
"petalWidth": 0.4,
"species": "setosa"
},
{
"sepalLength": 4.8,
"sepalWidth": 3.0,
"petalLength": 1.4,
"petalWidth": 0.3,
"species": "setosa"
},
{
"sepalLength": 5.1,
"sepalWidth": 3.8,
"petalLength": 1.6,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 4.6,
"sepalWidth": 3.2,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.3,
"sepalWidth": 3.7,
"petalLength": 1.5,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 5.0,
"sepalWidth": 3.3,
"petalLength": 1.4,
"petalWidth": 0.2,
"species": "setosa"
},
{
"sepalLength": 7.0,
"sepalWidth": 3.2,
"petalLength": 4.7,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 6.4,
"sepalWidth": 3.2,
"petalLength": 4.5,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 6.9,
"sepalWidth": 3.1,
"petalLength": 4.9,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 5.5,
"sepalWidth": 2.3,
"petalLength": 4.0,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.5,
"sepalWidth": 2.8,
"petalLength": 4.6,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 5.7,
"sepalWidth": 2.8,
"petalLength": 4.5,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.3,
"sepalWidth": 3.3,
"petalLength": 4.7,
"petalWidth": 1.6,
"species": "versicolor"
},
{
"sepalLength": 4.9,
"sepalWidth": 2.4,
"petalLength": 3.3,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 6.6,
"sepalWidth": 2.9,
"petalLength": 4.6,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.2,
"sepalWidth": 2.7,
"petalLength": 3.9,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 5.0,
"sepalWidth": 2.0,
"petalLength": 3.5,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 5.9,
"sepalWidth": 3.0,
"petalLength": 4.2,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 6.0,
"sepalWidth": 2.2,
"petalLength": 4.0,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 6.1,
"sepalWidth": 2.9,
"petalLength": 4.7,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 5.6,
"sepalWidth": 2.9,
"petalLength": 3.6,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.1,
"petalLength": 4.4,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 5.6,
"sepalWidth": 3.0,
"petalLength": 4.5,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.7,
"petalLength": 4.1,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 6.2,
"sepalWidth": 2.2,
"petalLength": 4.5,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 5.6,
"sepalWidth": 2.5,
"petalLength": 3.9,
"petalWidth": 1.1,
"species": "versicolor"
},
{
"sepalLength": 5.9,
"sepalWidth": 3.2,
"petalLength": 4.8,
"petalWidth": 1.8,
"species": "versicolor"
},
{
"sepalLength": 6.1,
"sepalWidth": 2.8,
"petalLength": 4.0,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.5,
"petalLength": 4.9,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 6.1,
"sepalWidth": 2.8,
"petalLength": 4.7,
"petalWidth": 1.2,
"species": "versicolor"
},
{
"sepalLength": 6.4,
"sepalWidth": 2.9,
"petalLength": 4.3,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.6,
"sepalWidth": 3.0,
"petalLength": 4.4,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 6.8,
"sepalWidth": 2.8,
"petalLength": 4.8,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.0,
"petalLength": 5.0,
"petalWidth": 1.7,
"species": "versicolor"
},
{
"sepalLength": 6.0,
"sepalWidth": 2.9,
"petalLength": 4.5,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 5.7,
"sepalWidth": 2.6,
"petalLength": 3.5,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 5.5,
"sepalWidth": 2.4,
"petalLength": 3.8,
"petalWidth": 1.1,
"species": "versicolor"
},
{
"sepalLength": 5.5,
"sepalWidth": 2.4,
"petalLength": 3.7,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.7,
"petalLength": 3.9,
"petalWidth": 1.2,
"species": "versicolor"
},
{
"sepalLength": 6.0,
"sepalWidth": 2.7,
"petalLength": 5.1,
"petalWidth": 1.6,
"species": "versicolor"
},
{
"sepalLength": 5.4,
"sepalWidth": 3.0,
"petalLength": 4.5,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 6.0,
"sepalWidth": 3.4,
"petalLength": 4.5,
"petalWidth": 1.6,
"species": "versicolor"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.1,
"petalLength": 4.7,
"petalWidth": 1.5,
"species": "versicolor"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.3,
"petalLength": 4.4,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.6,
"sepalWidth": 3.0,
"petalLength": 4.1,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.5,
"sepalWidth": 2.5,
"petalLength": 4.0,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.5,
"sepalWidth": 2.6,
"petalLength": 4.4,
"petalWidth": 1.2,
"species": "versicolor"
},
{
"sepalLength": 6.1,
"sepalWidth": 3.0,
"petalLength": 4.6,
"petalWidth": 1.4,
"species": "versicolor"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.6,
"petalLength": 4.0,
"petalWidth": 1.2,
"species": "versicolor"
},
{
"sepalLength": 5.0,
"sepalWidth": 2.3,
"petalLength": 3.3,
"petalWidth": 1.0,
"species": "versicolor"
},
{
"sepalLength": 5.6,
"sepalWidth": 2.7,
"petalLength": 4.2,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.7,
"sepalWidth": 3.0,
"petalLength": 4.2,
"petalWidth": 1.2,
"species": "versicolor"
},
{
"sepalLength": 5.7,
"sepalWidth": 2.9,
"petalLength": 4.2,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.2,
"sepalWidth": 2.9,
"petalLength": 4.3,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 5.1,
"sepalWidth": 2.5,
"petalLength": 3.0,
"petalWidth": 1.1,
"species": "versicolor"
},
{
"sepalLength": 5.7,
"sepalWidth": 2.8,
"petalLength": 4.1,
"petalWidth": 1.3,
"species": "versicolor"
},
{
"sepalLength": 6.3,
"sepalWidth": 3.3,
"petalLength": 6.0,
"petalWidth": 2.5,
"species": "virginica"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.7,
"petalLength": 5.1,
"petalWidth": 1.9,
"species": "virginica"
},
{
"sepalLength": 7.1,
"sepalWidth": 3.0,
"petalLength": 5.9,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.9,
"petalLength": 5.6,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.5,
"sepalWidth": 3.0,
"petalLength": 5.8,
"petalWidth": 2.2,
"species": "virginica"
},
{
"sepalLength": 7.6,
"sepalWidth": 3.0,
"petalLength": 6.6,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 4.9,
"sepalWidth": 2.5,
"petalLength": 4.5,
"petalWidth": 1.7,
"species": "virginica"
},
{
"sepalLength": 7.3,
"sepalWidth": 2.9,
"petalLength": 6.3,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.7,
"sepalWidth": 2.5,
"petalLength": 5.8,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 7.2,
"sepalWidth": 3.6,
"petalLength": 6.1,
"petalWidth": 2.5,
"species": "virginica"
},
{
"sepalLength": 6.5,
"sepalWidth": 3.2,
"petalLength": 5.1,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 6.4,
"sepalWidth": 2.7,
"petalLength": 5.3,
"petalWidth": 1.9,
"species": "virginica"
},
{
"sepalLength": 6.8,
"sepalWidth": 3.0,
"petalLength": 5.5,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 5.7,
"sepalWidth": 2.5,
"petalLength": 5.0,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.8,
"petalLength": 5.1,
"petalWidth": 2.4,
"species": "virginica"
},
{
"sepalLength": 6.4,
"sepalWidth": 3.2,
"petalLength": 5.3,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 6.5,
"sepalWidth": 3.0,
"petalLength": 5.5,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 7.7,
"sepalWidth": 3.8,
"petalLength": 6.7,
"petalWidth": 2.2,
"species": "virginica"
},
{
"sepalLength": 7.7,
"sepalWidth": 2.6,
"petalLength": 6.9,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 6.0,
"sepalWidth": 2.2,
"petalLength": 5.0,
"petalWidth": 1.5,
"species": "virginica"
},
{
"sepalLength": 6.9,
"sepalWidth": 3.2,
"petalLength": 5.7,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 5.6,
"sepalWidth": 2.8,
"petalLength": 4.9,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 7.7,
"sepalWidth": 2.8,
"petalLength": 6.7,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.7,
"petalLength": 4.9,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.3,
"petalLength": 5.7,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 7.2,
"sepalWidth": 3.2,
"petalLength": 6.0,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.2,
"sepalWidth": 2.8,
"petalLength": 4.8,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.1,
"sepalWidth": 3.0,
"petalLength": 4.9,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.4,
"sepalWidth": 2.8,
"petalLength": 5.6,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 7.2,
"sepalWidth": 3.0,
"petalLength": 5.8,
"petalWidth": 1.6,
"species": "virginica"
},
{
"sepalLength": 7.4,
"sepalWidth": 2.8,
"petalLength": 6.1,
"petalWidth": 1.9,
"species": "virginica"
},
{
"sepalLength": 7.9,
"sepalWidth": 3.8,
"petalLength": 6.4,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 6.4,
"sepalWidth": 2.8,
"petalLength": 5.6,
"petalWidth": 2.2,
"species": "virginica"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.8,
"petalLength": 5.1,
"petalWidth": 1.5,
"species": "virginica"
},
{
"sepalLength": 6.1,
"sepalWidth": 2.6,
"petalLength": 5.6,
"petalWidth": 1.4,
"species": "virginica"
},
{
"sepalLength": 7.7,
"sepalWidth": 3.0,
"petalLength": 6.1,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 6.3,
"sepalWidth": 3.4,
"petalLength": 5.6,
"petalWidth": 2.4,
"species": "virginica"
},
{
"sepalLength": 6.4,
"sepalWidth": 3.1,
"petalLength": 5.5,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.0,
"sepalWidth": 3.0,
"petalLength": 4.8,
"petalWidth": 1.8,
"species": "virginica"
},
{
"sepalLength": 6.9,
"sepalWidth": 3.1,
"petalLength": 5.4,
"petalWidth": 2.1,
"species": "virginica"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.1,
"petalLength": 5.6,
"petalWidth": 2.4,
"species": "virginica"
},
{
"sepalLength": 6.9,
"sepalWidth": 3.1,
"petalLength": 5.1,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 5.8,
"sepalWidth": 2.7,
"petalLength": 5.1,
"petalWidth": 1.9,
"species": "virginica"
},
{
"sepalLength": 6.8,
"sepalWidth": 3.2,
"petalLength": 5.9,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.3,
"petalLength": 5.7,
"petalWidth": 2.5,
"species": "virginica"
},
{
"sepalLength": 6.7,
"sepalWidth": 3.0,
"petalLength": 5.2,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 6.3,
"sepalWidth": 2.5,
"petalLength": 5.0,
"petalWidth": 1.9,
"species": "virginica"
},
{
"sepalLength": 6.5,
"sepalWidth": 3.0,
"petalLength": 5.2,
"petalWidth": 2.0,
"species": "virginica"
},
{
"sepalLength": 6.2,
"sepalWidth": 3.4,
"petalLength": 5.4,
"petalWidth": 2.3,
"species": "virginica"
},
{
"sepalLength": 5.9,
"sepalWidth": 3.0,
"petalLength": 5.1,
"petalWidth": 1.8,
"species": "virginica"
}
]
}