8.Apply k – nearest neighbor classifier on iris data-set using Go.
To apply the k-nearest neighbor (KNN) classifier on the Iris dataset using Go, we'll need to load the
dataset, split it into training and testing sets, and then implement the KNN algorithm. Here's an example
Go program that demonstrates this:
package main
import (
"encoding/csv"
"fmt"
"log"
"math"
"os"
"strconv"
"strings"
"github.com/gonum/stat"
"github.com/gonum/matrix/mat64"
"github.com/gonum/stat/distuv"
)
const (
irisDatasetPath = "iris.csv"
k = 5
)
func main() {
// Load the Iris dataset
irisData, err := loadIrisDataset(irisDatasetPath)
if err != nil {
log.Fatal(err)
}
// Split the dataset into training and testing sets
trainData, testData := splitDataset(irisData, 0.7)
// Convert the training and testing data to feature matrices
trainFeatures, trainLabels := prepareData(trainData)
testFeatures, testLabels := prepareData(testData)
// Create a KNN classifier
knn := NewKNNClassifier(k)
// Train the KNN classifier
knn.Fit(trainFeatures, trainLabels)
predictedLabels := knn.Predict(testFeatures)
// Calculate and display the accuracy
accuracy := calculateAccuracy(testLabels, predictedLabels)
fmt.Printf("Accuracy: %.2f%%\n", accuracy*100)
}
// struct to represent a data instance in the Iris dataset
type irisDataInstance struct {
Features []float64
Label string
}
// Function to load the Iris dataset from a CSV file
func loadIrisDataset(filepath string) ([]irisDataInstance, error) {
file, err := os.Open(filepath)
if err != nil {
return nil, err
}
defer file.Close()
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
return nil, err
}
irisData := make([]irisDataInstance, len(records))
for i, record := range records {
features := make([]float64, 4)
for j := 0; j < 4; j++ {
features[j], err = strconv.ParseFloat(record[j], 64)
if err != nil {
return nil, err
}
}
irisData[i] = irisDataInstance{
Features: features,
Label: record[4],
}
}
return irisData, nil
}
//
func splitDataset(dataset []irisDataInstance, splitRatio float64) ([]irisDataInstance,
[]irisDataInstance) {
trainSize := int(float64(len(dataset)) * splitRatio)
return dataset[:trainSize], dataset[trainSize:]
}
// Function to prepare the dataset by separating features and labels
func prepareData(dataset []irisDataInstance) (*mat64.Dense, []string) {
features := mat64.NewDense(len(dataset), 4, nil)
labels := make([]string, len(dataset))
for i, instance := range dataset {
for j, val := range instance.Features {
features.Set(i, j, val)
}
labels[i] = instance.Label
}
return features, labels
}
// KNNClassifier represents a k-nearest neighbor classifier
type KNNClassifier struct {
K int
X *mat64.Dense
Y []string
}
// NewKNNClassifier creates a new instance of KNNClassifier
func NewKNNClassifier(k int) *KNNClassifier {
return &KNNClassifier{
K: k,
}
}
// Fit trains the KNN classifier with the provided training features and labels
func (knn *KNNClassifier) Fit(features *mat64.Dense, labels []string) {
knn.X = features
knn.Y = labels
}
// Predict predicts the labels for the given test features using the KNN algorithm
func (knn *KNNClassifier) Predict(testFeatures *mat64.Dense) []string {
testSize, _ := testFeatures.Dims()
predictedLabels := make([]string, testSize)
for i := 0; i < testSize; i++ {
testRow := testFeatures.RowView(i)Function to split the dataset into training and testing sets
Function to get the indices of the k nearest neighbors based on distances
func getKNearestIndices(distances []float64, k int) []int {
indices := make([]int, k)
copyDistances := make([]float64, len(distances))
copy(copyDistances, distances)
for i := 0; i < k; i++ {
minIdx := findMinIndex(copyDistances)
indices[i] = minIdx
copyDistances[minIdx] = math.Inf(1)
}
return indices
}
// Function to find the index of the minimum value in a float64 slice
func findMinIndex(slice []float64) int {
minIdx := 0
minVal := slice[0]
for i, val := range slice {
if val < minVal {
minIdx = i
minVal = val
}
}
return minIdx
// Predict the labels for the test features