以下是用C#实现K-近邻算法(K-Nearest Neighbors, KNN)的代码示例。这个实现将数据点存储在一个二维数组中,并计算与测试点的距离,选择最近的K个邻居来进行分类。
实现步骤:
- 计算每个数据点到测试点的欧氏距离。
- 对距离进行排序,选出前K个最近的邻居。
- 根据最近邻居的标签进行投票,选择出现次数最多的标签作为测试点的分类结果。
using System;
using System.Collections.Generic;
using System.Linq;
class KNN
{
// 存储训练数据点和其标签
private List<Tuple<double[], string>> trainingData;
public KNN()
{
trainingData = new List<Tuple<double[], string>>();
}
// 添加训练数据点
public void AddTrainingData(double[] features, string label)
{
trainingData.Add(new Tuple<double[], string>(features, label));
}
// 计算欧氏距离
private double EuclideanDistance(double[] point1, double[] point2)
{
double sum = 0.0;
for (int i = 0; i < point1.Length; i++)
{
sum += Math.Pow(point1[i] - point2[i], 2);
}
return Math.Sqrt(sum);
}
// 分类函数,k为选择的邻居个数
public string Classify(double[] testPoint, int k)
{
// 计算每个训练数据点与测试点的距离
List<Tuple<double, string>> distances = new List<Tuple<double, string>>();
foreach (var data in trainingData)
{
double distance = EuclideanDistance(testPoint, data.Item1);
distances.Add(new Tuple<double, string>(distance, data.Item2));
}
// 按距离排序,选出前K个最近的邻居
var nearestNeighbors = distances.OrderBy(x => x.Item1).Take(k);
// 统计最近邻居中每个标签出现的次数
Dictionary<string, int> labelCounts = new Dictionary<string, int>();
foreach (var neighbor in nearestNeighbors)
{
string label = neighbor.Item2;
if (labelCounts.ContainsKey(label))
{
labelCounts[label]++;
}
else
{
labelCounts[label] = 1;
}
}
// 返回出现次数最多的标签
return labelCounts.OrderByDescending(x => x.Value).First().Key;
}
}
class Program
{
static void Main(string[] args)
{
// 创建KNN实例
KNN knn = new KNN();
// 添加训练数据(特征,标签)
knn.AddTrainingData(new double[] { 1.0, 2.0 }, "A");
knn.AddTrainingData(new double[] { 2.0, 3.0 }, "A");
knn.AddTrainingData(new double[] { 3.0, 3.0 }, "B");
knn.AddTrainingData(new double[] { 5.0, 1.0 }, "B");
// 测试数据
double[] testPoint = new double[] { 2.5, 2.5 };
// K值为3
string result = knn.Classify(testPoint, 3);
Console.WriteLine($"分类结果:{result}");
}
}
解释:
trainingData
:存储训练数据,每个数据点由特征和标签组成。EuclideanDistance
:计算两个数据点之间的欧氏距离。Classify
:根据K值选择K个最近的邻居,返回出现次数最多的标签作为分类结果。
示例运行结果:
假设训练数据点及其标签如下:
- (1.0, 2.0) -> A
- (2.0, 3.0) -> A
- (3.0, 3.0) -> B
- (5.0, 1.0) -> B
对于测试数据点 (2.5, 2.5),K = 3 时,分类结果可能为 "A"。
可改进的地方:
- 支持不同的距离度量方式(如曼哈顿距离)。
- 添加对回归任务的支持。