筆記:
尚未解決的問題 :編譯環境 ubuntu gcc 5.4 編譯選項 g++ -std=c++141. 只支援二維,而不支援三維或更高,需要模板元
2. 尚未實現如何刪除極端點, 即預處理
3. 尚未視覺化
#include #include #include #include #include #include #include #include #include #include #include #include #include #include "scopeguard.h"
using point = std::tuple;
using onecluster = std::vector;
void print(const std::vector& clusters) }}
// 讀取檔案內容
std::vector< point > readdata(const std::string& path) );
auto items = 0;
in >> items;
auto x = 0.00, y = 0.00;
std::vector< point > dataset;
for(int i = 0;i < items; ++i)
for(const auto& it : dataset)
std::cout << std::get<0>(it) << "\t" << std::get<1>(it) << "\n";
return dataset;
}// 計算兩個點之間的距離, 在這裡選擇的是歐氏距離
inline double getdistance(const point& a, const point& b)
// 在這些簇中心點 centers 中, one 這個點選離自己最近的乙個,返回這個最近的中心店
const int getlabel(const point& one, const onecluster& centers)
} return label;
}// 給定乙個簇,計算簇的中心,在這裡選擇的是 x, y 均值點
point getcenter(const onecluster& one)
int scale = one.size();
return std::make_tuple(mean_x / scale, mean_y / scale);
}// 給定聚類結果 clusters, 和這些簇的中心 centers,預估聚類效果,方式多樣
const double getevaluate(const std::vector& clusters,
const onecluster& centers)
} return ans;
}// 給定資料集 dataset, 聚成 k 類, 閾值 thresholdvalue(預估差 < 閾值 就結束)
std::vector< onecluster > k_means(const onecluster& dataset, const int k,
const double thresholdvalue)
// clusters 儲存的每乙個元素都是乙個簇, 預先分配 k 個簇的空間
std::vector< onecluster > clusters;
clusters.assign(k, onecluster());
double oldvalue = 0.00, newvalue = 0.00; int cnt = 0;
while(true)
print(clusters);
// 重新計算每個簇的中心點
for(int i = 0;i < k; ++i)
// 重新衡量這次的最小函式值
oldvalue = newvalue; // 先儲存上次的最小均方差之和
newvalue = getevaluate(clusters, centers);
if(abs(newvalue - oldvalue) < thresholdvalue) // 如果變化小於閾值,就結束
return clusters; // nvo
// 每次聚類,得到的聚類都是不一樣的,所以上次的記錄要清空
for(auto &it : clusters)
it.clear();
} return std::vector< onecluster >();
}int main()
/* 尚未解決的問題 :
1. 只支援二維,而不支援三維或更高,需要模板元
2. 尚未實現如何刪除極端點, 即預處理
3. 尚未視覺化
*/
生成測試資料的**:
利用 c++ 生成隨機小數, 聲稱自己的資料集:
#include #include #include #include #include "scopeguard.h"
int main() );
int num = 380;
out << num << "\n";
std::default_random_engine e(time(0));
std::uniform_real_distributiona(0, 4);
std::uniform_real_distributionb(6, 8);
std::uniform_real_distributionc(-3, -6);
for(int i = 0;i < num - 80; ++i)
case 1 :
case 2 :
} }std::uniform_real_distributiond(-10, 10); // 剩下的是大範圍內隨機, 1, 2, 3, 4象限都有
for(int i = 0; i < 80; ++i)
out << d(e) << " " << d(e) << "\n";
return 0;
}
測試結果:![](https://pic.w3help.cc/2d0/b7d02ff8da029bb42ffb3f06f02b9.jpeg)
可見元素基本集中在三個象限中
機器學習之聚類演算法 K Means
參考 聚類演算法可以分為 中心點方法 層次聚類方法 基於密度方法 基於網格 基於模型方法。其中最為經典的是k means演算法 k means屬於中心點方法 也有叫劃分方法 演算法經典簡單。演算法 人工選取k值,並選取k個點作為k個簇的質心 對所有樣本分別計算到k個簇的質心的距離 歐式或者曼哈頓 取...
機器學習演算法 之K means聚類
1.模型 k means演算法並沒有顯式的數學模型,演算法的目的是從資料集中得到k個中心點,每個中心點及其周圍的點形成乙個聚簇。k means是一種無監督的學習模型。k means的學習目標如下圖所示 2.策略 k mean演算法採用的損失函式是平方損失函式。每個簇的點距離中心的平方距離之和構成損失...
機器學習之K means聚類演算法
k均值演算法的計算過程非常直觀 1 從d中隨機取k個元素,作為k個簇的各自的中心。2 分別計算剩下的元素到k個簇中心的相異度,將這些元素分別劃歸到相異度最低的簇。3 根據聚類結果,重新計算k個簇各自的中心,計算方法是取簇中所有元素各自維度的算術平均數。4 將d中全部元素按照新的中心重新聚類。5 重複...