統計學習方法筆記2:感知機

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 }
相關文章
相關標籤/搜索