C++ 语言 实现 KNN 分类算法优化

C++阿木 发布于 2025-06-14 6 次阅读


KNN 分类算法在 C++ 中的优化实现

K最近邻(K-Nearest Neighbors,KNN)是一种简单的监督学习算法,它通过测量不同特征值之间的距离来分类数据点。KNN 算法在许多领域都有应用,如图像识别、文本分类等。随着数据量的增加,KNN 算法的效率会显著下降。本文将探讨如何在 C++ 中优化 KNN 分类算法,以提高其处理大数据集的能力。

KNN 算法原理

KNN 算法的基本思想是:对于一个待分类的数据点,找到与其最接近的 K 个邻居,然后根据这 K 个邻居的类别来预测待分类数据点的类别。具体步骤如下:

1. 计算待分类数据点与训练集中所有数据点的距离。
2. 找到距离最近的 K 个数据点。
3. 根据这 K 个数据点的类别,通过投票或其他方法确定待分类数据点的类别。

C++ 中的 KNN 实现与优化

1. 数据结构选择

在 C++ 中,合理选择数据结构对于提高算法效率至关重要。以下是一些常用的数据结构:

- std::vector:用于存储训练集和测试集。
- std::pair:用于存储数据点和其对应的标签。
- std::map:用于快速查找距离最近的 K 个邻居。

2. 距离计算

距离计算是 KNN 算法中的关键步骤。以下是一些常用的距离度量方法:

- 欧几里得距离:适用于特征空间维度较低的情况。
- 曼哈顿距离:适用于特征空间维度较高的情况。
- 余弦相似度:适用于特征空间维度较高且特征之间存在相关性的情况。

以下是一个计算欧几里得距离的函数示例:

cpp
include

double euclideanDistance(const std::vector& point1, const std::vector& point2) {
double sum = 0.0;
for (size_t i = 0; i < point1.size(); ++i) {
sum += (point1[i] - point2[i]) (point1[i] - point2[i]);
}
return std::sqrt(sum);
}

3. KNN 算法优化

以下是一些优化 KNN 算法的方法:

- 并行计算:利用多线程技术,并行计算待分类数据点与训练集中所有数据点的距离。
- 空间划分:使用空间划分技术,如四叉树或 k-d 树,减少需要比较的数据点数量。
- 近似算法:使用近似算法,如局部敏感哈希(LSH),减少计算量。

以下是一个使用并行计算优化 KNN 算法的示例:

cpp
include
include
include
include

void computeDistances(const std::vector<#std::pair<#std::vector, int>>& trainingSet,
const std::vector& point,
std::vector<#std::pair>& distances,
size_t start, size_t end) {
for (size_t i = start; i < end; ++i) {
double distance = euclideanDistance(point, trainingSet[i].first);
distances.push_back(std::make_pair(distance, trainingSet[i].second));
}
}

std::vector<#std::pair> kNN(const std::vector<#std::pair<#std::vector, int>>& trainingSet,
const std::vector& point,
int k) {
size_t numThreads = std::thread::hardware_concurrency();
size_t chunkSize = trainingSet.size() / numThreads;
std::vector<#std::future<#std::vector<#std::pair>>> futures;

for (size_t i = 0; i < numThreads; ++i) {
size_t start = i chunkSize;
size_t end = (i == numThreads - 1) ? trainingSet.size() : (i + 1) chunkSize;
futures.push_back(std::async(std::launch::async, computeDistances, std::ref(trainingSet), std::ref(point), std::ref(distances), start, end));
}

std::vector<#std::pair> allDistances;
for (auto& future : futures) {
allDistances.insert(allDistances.end(), future.get().begin(), future.get().end());
}

std::sort(allDistances.begin(), allDistances.end());
std::vector<#std::pair> kNearest(allDistances.begin(), allDistances.begin() + k);

return kNearest;
}

4. 代码测试与评估

为了验证 KNN 算法的优化效果,我们可以使用一些公开的数据集进行测试。以下是一个简单的测试示例:

cpp
include
include
include

int main() {
std::ifstream file("data.txt");
std::string line;
std::vector<#std::pair<#std::vector, int>> trainingSet;

while (std::getline(file, line)) {
std::istringstream iss(line);
std::vector features;
int label;
for (std::string token; std::getline(iss, token, ',');) {
if (token.empty()) continue;
features.push_back(std::stod(token));
}
std::getline(iss, line);
label = std::stoi(line);
trainingSet.push_back(std::make_pair(features, label));
}

std::vector testPoint = {1.0, 2.0};
int k = 3;
std::vector<#std::pair> kNearest = kNN(trainingSet, testPoint, k);

std::cout << "The predicted label is: " << kNearest[0].second << std::endl;

return 0;
}

总结

本文介绍了 KNN 分类算法在 C++ 中的优化实现。通过合理选择数据结构、优化距离计算和并行计算等方法,我们可以提高 KNN 算法的效率,使其能够处理更大的数据集。在实际应用中,我们可以根据具体需求进一步优化算法,以达到更好的效果。