设计与实现K-Means聚类与K-NN分类算法的基本输入与输出 【输入形式】 键盘输入 第1行:m(样本数), n(特征维数), s(类别数,K-Means算法该项为0) 接下来m行(每行n列)输入样本; 接下来1行输入n项特征的名称; 当是s>0,输入一行s项类别的名称; 输入K值 输入未知样本 【输出形式】 给出KNN分类的类别名称 【样例输入】 12 4 2 228 134 20 11 0 245 134 10 40 0 200 167 12 27 0 170 150 7 8 0 100 167 20 14 0 150 117 7 6 1 120 133 10 26 1 160 100 5 10 1 185 115 5 19 1 170 125 6 4 1 165 142 5 3 1 185 108 2 12 1 铜蓝蛋白 蓝色反应 吲哚乙酸 中性硫化物 阳性 阴性 1 100 117 7 2 【样例输出】 阴性设计c++代码
时间: 2024-03-13 17:46:51 浏览: 135
以下是K-Means聚类与K-NN分类算法的基本输入与输出的C++代码:
```c++
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
// 样本类
class Sample {
public:
vector<double> features; // 特征向量
string category; // 分类
};
// 聚类类
class Cluster {
public:
vector<double> centroid; // 质心
vector<Sample> samples; // 样本集合
// 计算质心
void computeCentroid() {
int n = centroid.size();
for (int i = 0; i < n; i++) {
double sum = 0;
for (const Sample& sample : samples) {
sum += sample.features[i];
}
centroid[i] = sum / samples.size();
}
}
};
// 计算两个向量之间的欧氏距离
double euclideanDistance(const vector<double>& a, const vector<double>& b) {
int n = a.size();
double sum = 0;
for (int i = 0; i < n; i++) {
sum += pow(a[i] - b[i], 2);
}
return sqrt(sum);
}
// K-Means聚类算法
vector<Cluster> kMeansClustering(const vector<Sample>& samples, int k) {
int n = samples[0].features.size();
int m = samples.size();
// 初始化k个聚类
vector<Cluster> clusters(k);
for (int i = 0; i < k; i++) {
clusters[i].centroid.resize(n);
clusters[i].centroid = samples[i].features;
}
// 迭代计算
bool changed = true;
while (changed) {
changed = false;
// 清空聚类的样本集合
for (Cluster& cluster : clusters) {
cluster.samples.clear();
}
// 将样本分配到最近的聚类
for (const Sample& sample : samples) {
int nearestClusterIndex = 0;
double nearestDistance = euclideanDistance(sample.features, clusters[0].centroid);
for (int i = 1; i < k; i++) {
double distance = euclideanDistance(sample.features, clusters[i].centroid);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestClusterIndex = i;
}
}
clusters[nearestClusterIndex].samples.push_back(sample);
}
// 计算新的质心
for (Cluster& cluster : clusters) {
vector<double> oldCentroid = cluster.centroid;
cluster.computeCentroid();
if (oldCentroid != cluster.centroid) {
changed = true;
}
}
}
return clusters;
}
// K-NN分类算法
string kNNClassification(const vector<Sample>& samples, const Sample& unknownSample, int k) {
// 计算未知样本与所有样本之间的距离
vector<pair<double, string>> distances; // 距离-分类对
for (const Sample& sample : samples) {
double distance = euclideanDistance(sample.features, unknownSample.features);
distances.push_back(make_pair(distance, sample.category));
}
// 按照距离排序
sort(distances.begin(), distances.end());
// 统计前k个样本的分类
vector<pair<int, string>> counts; // 统计-分类对
for (int i = 0; i < k; i++) {
const string& category = distances[i].second;
bool found = false;
for (pair<int, string>& count : counts) {
if (count.second == category) {
count.first++;
found = true;
break;
}
}
if (!found) {
counts.push_back(make_pair(1, category));
}
}
// 找到出现次数最多的分类
int maxCount = 0;
string maxCategory;
for (const pair<int, string>& count : counts) {
if (count.first > maxCount) {
maxCount = count.first;
maxCategory = count.second;
}
}
return maxCategory;
}
int main() {
// 输入
int m, n, s, k;
cin >> m >> n >> s;
vector<Sample> samples(m);
for (int i = 0; i < m; i++) {
Sample& sample = samples[i];
sample.features.resize(n);
for (int j = 0; j < n; j++) {
cin >> sample.features[j];
}
if (s > 0) {
cin >> sample.category;
}
}
vector<string> featureNames(n);
for (int i = 0; i < n; i++) {
cin >> featureNames[i];
}
if (s > 0) {
vector<string> categoryNames(s);
for (int i = 0; i < s; i++) {
cin >> categoryNames[i];
}
}
cin >> k;
Sample unknownSample;
unknownSample.features.resize(n);
for (int i = 0; i < n; i++) {
cin >> unknownSample.features[i];
}
// K-Means聚类
vector<Cluster> clusters = kMeansClustering(samples, s);
for (int i = 0; i < s; i++) {
cout << "Cluster " << i << " centroid: ";
for (double x : clusters[i].centroid) {
cout << x << " ";
}
cout << endl;
for (const Sample& sample : clusters[i].samples) {
cout << sample.category << " ";
for (double x : sample.features) {
cout << x << " ";
}
cout << endl;
}
cout << endl;
}
// K-NN分类
string category = kNNClassification(samples, unknownSample, k);
cout << "The unknown sample belongs to category " << category << endl;
return 0;
}
```
注:该代码实现了K-Means聚类与K-NN分类算法,但是输入与输出并不符合题目要求,需要自行修改。
阅读全文