Go语言实现K-近邻算法 (K-Nearest Neighbors, KNN)

可以通过Go语言实现K-近邻算法(K-Nearest Neighbors, KNN)来进行分类任务。KNN算法的核心思想是:给定一个样本点,找到距离该点最近的K个样本,然后根据这些邻居的类别,使用投票机制来决定该样本点的类别。

下面是一个简单的KNN实现:

package main

import (
	"fmt"
	"math"
	"sort"
)

// 定义数据点结构体
type DataPoint struct {
	features []float64
	label    string
}

// 计算两点之间的欧几里得距离
func euclideanDistance(p1, p2 DataPoint) float64 {
	sum := 0.0
	for i := range p1.features {
		diff := p1.features[i] - p2.features[i]
		sum += diff * diff
	}
	return math.Sqrt(sum)
}

// 实现KNN算法
func knn(trainingData []DataPoint, testPoint DataPoint, k int) string {
	type Neighbor struct {
		distance float64
		label    string
	}

	// 计算testPoint与所有训练数据点的距离
	var neighbors []Neighbor
	for _, data := range trainingData {
		dist := euclideanDistance(data, testPoint)
		neighbors = append(neighbors, Neighbor{distance: dist, label: data.label})
	}

	// 按照距离对邻居排序
	sort.Slice(neighbors, func(i, j int) bool {
		return neighbors[i].distance < neighbors[j].distance
	})

	// 统计前K个邻居中每个类别的票数
	labelCount := make(map[string]int)
	for i := 0; i < k; i++ {
		labelCount[neighbors[i].label]++
	}

	// 找到票数最多的类别
	maxCount := 0
	var predictedLabel string
	for label, count := range labelCount {
		if count > maxCount {
			maxCount = count
			predictedLabel = label
		}
	}

	return predictedLabel
}

func main() {
	// 示例数据集 (特征和标签)
	trainingData := []DataPoint{
		{features: []float64{1.0, 2.0}, label: "A"},
		{features: []float64{2.0, 3.0}, label: "A"},
		{features: []float64{3.0, 3.0}, label: "B"},
		{features: []float64{6.0, 5.0}, label: "B"},
		{features: []float64{7.0, 8.0}, label: "B"},
	}

	// 测试点
	testPoint := DataPoint{features: []float64{3.5, 4.0}}

	// 执行KNN算法,设置K=3
	k := 3
	predictedLabel := knn(trainingData, testPoint, k)

	fmt.Printf("预测类别: %s/n", predictedLabel)
}

解释:

  • DataPoint: 用于存储样本的特征和类别标签。
  • euclideanDistance: 计算两个点之间的欧几里得距离。
  • knn: 实现了KNN算法,首先计算测试点与训练集所有点的距离,并按距离排序,然后选取距离最近的K个点进行投票,最后预测测试点的类别。
  • main: 包含示例数据集和测试点,执行KNN算法并输出预测结果。

运行结果:

运行此代码后,会输出测试点的预测类别。

可以通过Go语言实现K-近邻算法(K-Nearest Neighbors, KNN)来进行分类任务。KNN算法的核心思想是:给定一个样本点,找到距离该点最近的K个样本,然后根据这些邻居的类别,使用投票机制来决定该样本点的类别。

下面是一个简单的KNN实现:

package main

import (
	"fmt"
	"math"
	"sort"
)

// 定义数据点结构体
type DataPoint struct {
	features []float64
	label    string
}

// 计算两点之间的欧几里得距离
func euclideanDistance(p1, p2 DataPoint) float64 {
	sum := 0.0
	for i := range p1.features {
		diff := p1.features[i] - p2.features[i]
		sum += diff * diff
	}
	return math.Sqrt(sum)
}

// 实现KNN算法
func knn(trainingData []DataPoint, testPoint DataPoint, k int) string {
	type Neighbor struct {
		distance float64
		label    string
	}

	// 计算testPoint与所有训练数据点的距离
	var neighbors []Neighbor
	for _, data := range trainingData {
		dist := euclideanDistance(data, testPoint)
		neighbors = append(neighbors, Neighbor{distance: dist, label: data.label})
	}

	// 按照距离对邻居排序
	sort.Slice(neighbors, func(i, j int) bool {
		return neighbors[i].distance < neighbors[j].distance
	})

	// 统计前K个邻居中每个类别的票数
	labelCount := make(map[string]int)
	for i := 0; i < k; i++ {
		labelCount[neighbors[i].label]++
	}

	// 找到票数最多的类别
	maxCount := 0
	var predictedLabel string
	for label, count := range labelCount {
		if count > maxCount {
			maxCount = count
			predictedLabel = label
		}
	}

	return predictedLabel
}

func main() {
	// 示例数据集 (特征和标签)
	trainingData := []DataPoint{
		{features: []float64{1.0, 2.0}, label: "A"},
		{features: []float64{2.0, 3.0}, label: "A"},
		{features: []float64{3.0, 3.0}, label: "B"},
		{features: []float64{6.0, 5.0}, label: "B"},
		{features: []float64{7.0, 8.0}, label: "B"},
	}

	// 测试点
	testPoint := DataPoint{features: []float64{3.5, 4.0}}

	// 执行KNN算法,设置K=3
	k := 3
	predictedLabel := knn(trainingData, testPoint, k)

	fmt.Printf("预测类别: %s/n", predictedLabel)
}

解释:

  • DataPoint: 用于存储样本的特征和类别标签。
  • euclideanDistance: 计算两个点之间的欧几里得距离。
  • knn: 实现了KNN算法,首先计算测试点与训练集所有点的距离,并按距离排序,然后选取距离最近的K个点进行投票,最后预测测试点的类别。
  • main: 包含示例数据集和测试点,执行KNN算法并输出预测结果。

运行结果:

运行此代码后,会输出测试点的预测类别。

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在