k-nearest neighbor algorithm
右圖中,綠色圓要被決定賦予哪個類,是紅色三角形還是藍色四方形?如果k=3,由於紅色三角形所佔比例為2/3,綠色圓將被賦予紅色三角形那個類,如果k=5,由於藍色四方形比例為3/5,因此綠色圓被賦予藍色四方形類。
k最近鄰(k-nearest neighbor,knn)分類演算法,是乙個理論上比較成熟的方法,也是最簡單的機器學習演算法之一。該方法的思路是:如果乙個樣本在特徵空間中的k個最相 似(即特徵空間中最鄰近)的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別。knn演算法中,所選擇的鄰居都是已經正確分類的物件。該方法在定類決 策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。knn方法雖然從原理上也依賴於極限定理,但在類別決策時,只與極少量的相鄰樣本有關。由於knn方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方 法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,knn方法較其他方法更為適合。
knn演算法不僅可以用於分類,還可以用於回歸。通過找出乙個樣本的k個最近鄰居,將這些鄰居的屬性的平均值賦給該樣本,就可以得到該樣本的屬性。更有用的方法是將不同距離的鄰居對該樣本產生的影響給予不同的權值(weight),如權值與距離成正比。
該演算法在分類時有個主要的不足是,當樣本不平衡時,如乙個類的樣本容量很大,而其他類樣本容量 很小時,有可能導致當輸入乙個新樣本時,該樣本的k個鄰居中大容量類的樣本占多數。因此可以採用權值的方法(和該樣本距離小的鄰居權值大)來改進。該方法 的另乙個不足之處是計算量較大,因為對每乙個待分類的文字都要計算它到全體已知樣本的距離,才能求得它的k個最近鄰點。目前常用的解決方法是事先對已知樣 本點進行剪輯,事先去除對分類作用不大的樣本。該演算法比較適用於樣本容量比較大的類域的自動分類,而那些樣本容量較小的類域採用這種演算法比較容易產生誤 分。
#include #include #include #include #include #include #include #include #include using namespace std;
//樣例結構體,所屬型別和特徵向量
struct sample
;// 型別和距離結構體,未用到
struct typedistance
;bool operator < (const typedistance& lhs, const typedistance& rhs)
// 讀取訓練樣本
// 訓練樣本的格式是:每行代表乙個樣例
// 每行的第乙個元素是型別名,後面的是樣例的特徵向量
// 例如:
/*a 1 2 3 4 5
b 5 4 3 2 1
c 3 3 3 3 3
d -3 -3 -3 -3 -3
a 1 2 3 4 4
b 4 4 3 2 1
c 3 3 3 2 4
d 0 0 1 1 -2
*/void readtrain(vector& train, const string& file)
string line;
double d = 0.0;
while (getline(fin, line))
train.push_back(ts);
} fin.close();
}// 讀取測試樣本
// 每行代表乙個樣例
// 每一行是乙個樣例的特徵向量
// 例如:
/*1 2 3 2 4
2 3 4 2 1
8 7 2 3 5
-3 -2 2 4 0
-4 -4 -4 -4 -4
1 2 3 4 4
4 4 3 2 1
3 3 3 2 4
0 0 1 1 -2
*/void readtest(vector& test, const string& file)
double d = 0.0;
string line;
while (getline(fin, line))
test.push_back(ts);
} fin.close();
}// 計算歐氏距離
double euclideandistance(const vector& v1, const vector& v2)
return sqrt(ret);
}// 初始化距離矩陣
// 該矩陣是根據訓練樣本和測試樣本而得
// 矩陣的行數為測試樣本的數目,列數為訓練樣本的數目
// 每一行為乙個測試樣本到各個訓練樣本之間的歐式距離組成的陣列
void initdistancematrix(vector>& dm, const vector& train, const vector& test)
dm.push_back(vd); }}
// k-近鄰法的實現
// 設定不同的 k 值,給每個測試樣例予以乙個型別
// 距離和權重成反比
void knnprocess(vector& test, const vector& train, const vector>& dm, unsigned int k)
else
}} maptds;
string type = "";
double weight = 0.0;
//下面for迴圈主要是求出與測試樣本i最鄰近的k個樣本點中大多數屬於的類別,即將其作為測試樣本點i的類別
for (multimap::const_iterator cit = dts.begin(); cit != dts.end(); ++cit)
}test[i].type = type; }}
// 輸出結果
// 輸出的格式和訓練樣本的格式一樣
// 每行表示乙個樣例,第乙個元素是該樣例的型別,後面是該樣例的特徵向量
// 例如:
/*a 1 2 3 2 4
b 2 3 4 2 1
b 8 7 2 3 5
a -3 -2 2 4 0
d -4 -4 -4 -4 -4
a 1 2 3 4 4
b 4 4 3 2 1
c 3 3 3 2 4
d 0 0 1 1 -2
*/void writetest(const vector& test, const string& file)
for (vector::size_type i = 0; i != test.size(); ++i)
fout << endl; }}
// 封裝
void knn(const string& file1, const string& file2, const string& file3, int k)
// 測試
int main()
資料探勘十大經典演算法之KNN演算法
knn 是通過測量不同特徵值之間的距離進行分類。它的思路是 如果乙個樣本在特徵空間中的 k個最相似 即特徵空間中最鄰近 的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別,其中 k通常是不大於 20的整數。knn演算法中,所選擇的鄰居都是已經正確分類的物件。該方法在定類決策上只依據最鄰近的乙個或...
資料探勘十大經典演算法 8 kNN
1 k最近鄰 k nearest neighbor,knn 分類演算法,是乙個理論上比較成熟的方法,也是最簡單的機器學習演算法之一。該方法的思路是 如果乙個樣本在特徵空間中的k個最相似 即特徵空 間中最鄰近 的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別。2 knn演算法中,所選擇的鄰居都是...
資料探勘十大經典演算法
最近想看看資料探勘是個什麼東西,因此特別的關注了下,首先看看資料探勘包含哪些演算法,網上找到了十大經典演算法 01.c4.5 是機器學習演算法中的一種分類決策樹演算法,其核心演算法是 id3演算法 02.k means演算法 是一種聚類演算法。03.svm 一種 監督式學習 的方法,廣泛運用於統計分...