1.感知機:二類分類的線性模型,輸入爲實例的特徵向量,輸出爲某類別,取+1和-1.目的在求出將訓練數據進行線性劃分的分離超平面,導入基於誤分類的損失函數,利用梯度降低法對損失函數進行極小化求得感知機模型。ios
2.感知機模型:算法
,sign爲符號函數,w爲權值或權向量,b爲偏置。dom
其幾何解釋:對應一個越平面,w爲法向量,b截距。函數
3.感知機學習策略學習
1)數據集的線性可分性:spa
數據集,存在一個超平面S將數據集正實例和負實例徹底分佈在平面兩側。code
2)策略:blog
任意點到超平面的距離:或
it
總距離:,在不考慮1/||w||就獲得了感知機學習損失函數。io
損失函數:,y={-1,1}
4.學習算法
1)極小化問題的解:
a.選取初值w。,b。
b.在訓練集中選取數據(x,y)
c.若是y(w•x+b)≤0
d.迭代,直至數據集中沒有誤分點,即L(w,b)=0.
1 include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #define random(x) (rand() % (x)) 5 6 double dot_product(std::vector<double>& a, std::vector<double>& b){ 7 if (a.size() != b.size()) return 0; 8 double res = 0; 9 for (int i = 0; i < a.size(); ++i){ 10 res += a[i] * b[i]; 11 } 12 return res; 13 } 14 15 class Preception{ 16 public: 17 Preception(int iters = 100, int learnRate = 1, double initw = 0, double initb = 0){ 18 iterators = iters; 19 w.push_back(initw); 20 b = initb; 21 step = learnRate; 22 23 } 24 ~Preception(){ 25 w.clear(); 26 b = 0; 27 } 28 bool train(std::vector<std::vector<double> >& train_x, std::vector<int>& train_y){ 29 if (train_x.size() != train_y.size()) return false; 30 initWeight(train_x[0].size()); 31 32 for (int iter = 0; iter < iterators; ++iter){ 33 bool flag = true; 34 for (int i = 0; i < train_x.size();){ 35 if ((dot_product(w, train_x[i]) + b)*(double)train_y[i] <= 0){ 36 update(train_x[i], train_y[i]); 37 flag = false; 38 } 39 else{ 40 ++i; 41 } 42 } 43 if (flag) return true; 44 } 45 return false; 46 } 47 48 std::vector<int> predict(std::vector<std::vector<double> >& data_x){ 49 std::vector<int> ret; 50 for (int i = 0; i < data_x.size(); ++i){ 51 ret.push_back(predict(data_x[i])); 52 53 } 54 return ret; 55 56 } 57 58 int predict(std::vector<double>& x){ 59 return dot_product(x, w) + b > 0 ? 1 : -1; 60 61 } 62 void printPreceptronModel(){ 63 std::cout << "原始形式感知機模型:f(x)=sign("; 64 for (int i = 0; i < w.size(); ++i){ 65 if (i) std::cout << "+"; 66 if (w[i] != 1) std::cout << w[i]; 67 std::cout << "x" << i + 1; 68 } 69 if (b > 0) std::cout << "+"; 70 std::cout << b << ")" << std::endl; 71 } 72 private: 73 void initWeight(int size){ 74 for (int i = 1; i < size; ++i){ 75 w.push_back(w[0]); 76 } 77 } 78 79 void update(std::vector<double>& x, double y){ 80 for (int i = 0; i < w.size(); ++i){ 81 w[i] += step*y*x[i]; 82 83 } 84 b += step*y; 85 86 for (int i = 0; i < w.size(); ++i) 87 std::cout << w[i] << ","; 88 std::cout << std::endl; 89 90 std::cout << b << std::endl; 91 92 } 93 94 private: 95 int iterators; 96 std::vector<double> w; 97 double b; 98 double step; 99 }; 100 101 int main(){ 102 std::vector<std::vector<double> >test_x(3); 103 test_x[0].push_back(3); test_x[0].push_back(3); 104 test_x[1].push_back(4); test_x[1].push_back(3); 105 test_x[2].push_back(1); test_x[2].push_back(1); 106 std::vector<int> test_y(3); 107 test_y[0] = 1; 108 test_y[1] = 1; 109 test_y[2] = -1; 110 111 Preception *model = new Preception(); 112 model->train(test_x, test_y); 113 model->printPreceptronModel(); 114 }