• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 183,  comments - 10,  trackbacks - 0

            K-近鄰法的實現

            K-近鄰法是根據距離最近的 k 個樣例的類型來推測該樣例的類型。
            實現中中主要的環節有:
            ·訓練樣例格式和測試樣例格式的定義
            ·樣例結構體的定義
            ·訓練樣例和測試樣例的讀取
            ·樣例距離的計算,歐氏距離
            ·距離矩陣的生成
            ·針對每個測試樣例,得到其到每個訓練樣例的距離,根據距離由小到大排序,更具距離和權重成反比的關系,計算每個類型的總的權重,得到最大權重的那個類型,即是當前測試樣例的類型
            ·k 值的選擇和設定

            訓練樣本的格式是:
            每行代表一個樣例,每行的第一個元素是該樣例的類型,后面是該樣例的特征向量
            例如:

            train.txt
            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

             


            測試樣例的格式是:
            每行代表一個樣例,每行即是該樣例的特征向量
            例如:
            test.txt
            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

            測試樣例的輸出結果的格式是:
            格式與訓練樣例一樣,即每行代表一個樣例,每行的第一個元素是學習到的測試樣例的類型,后面是該樣例的特征向量
            例如:
            result.txt
            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 

            具體的程序實現如下:

              1 /*
              2     K-近鄰法的實現
              3     mark
              4     goonyangxiaofang@163.com
              5     QQ 591 247 876
              6     2012.02.13
              7 */
              8 
              9 
             10 #include <iostream>
             11 #include <string>
             12 #include <vector>
             13 #include <set>
             14 #include <map>
             15 #include <fstream>
             16 #include <sstream>
             17 #include <cassert>
             18 #include <cmath>
             19 using namespace std;
             20 
             21 // 樣例結構體,所屬類型和特征向量
             22 struct sample
             23 {
             24     string type;
             25     vector<double> features;
             26 };
             27 
             28 // 類型和距離結構體,未用到
             29 struct typeDistance
             30 {
             31     string type;
             32     double distance;
             33 };
             34 
             35 bool operator < (const typeDistance& lhs, const typeDistance& rhs)
             36 {
             37     return lhs.distance < rhs.distance;
             38 }
             39 
             40 // 讀取訓練樣本
             41 // 訓練樣本的格式是:每行代表一個樣例
             42 // 每行的第一個元素是類型名,后面的是樣例的特征向量
             43 // 例如:
             44 /*
             45 a    1 2 3 4 5
             46 b    5 4 3 2 1
             47 c    3 3 3 3 3
             48 d    -3 -3 -3 -3 -3
             49 a    1 2 3 4 4
             50 b    4 4 3 2 1
             51 c    3 3 3 2 4
             52 d    0 0 1 1 -2
             53 */
             54 void readTrain(vector<sample>& train, const string& file)
             55 {
             56     ifstream fin(file.c_str());
             57     if (!fin)
             58     {
             59         cerr << "File error!" << endl;
             60         exit(1);
             61     }
             62     string line;
             63     double d = 0.0;
             64     while (getline(fin, line))
             65     {
             66         istringstream sin(line);
             67         sample ts;
             68         sin >> ts.type;
             69         while (sin >> d)
             70         {
             71             ts.features.push_back(d);
             72         }
             73         train.push_back(ts);
             74     }
             75     fin.close();
             76 }
             77 
             78 // 讀取測試樣本
             79 // 每行代表一個樣例
             80 // 每一行是一個樣例的特征向量
             81 // 例如:
             82 /*
             83 1 2 3 2 4
             84 2 3 4 2 1
             85 8 7 2 3 5
             86 -3 -2 2 4 0
             87 -4 -4 -4 -4 -4
             88 1 2 3 4 4
             89 4 4 3 2 1
             90 3 3 3 2 4
             91 0 0 1 1 -2
             92 */
             93 void readTest(vector<sample>& test, const string& file)
             94 {
             95     ifstream fin(file.c_str());
             96     if (!fin)
             97     {
             98         cerr << "File error!" << endl;
             99         exit(1);
            100     }
            101     double d = 0.0;
            102     string line;
            103     while (getline(fin, line))
            104     {
            105         istringstream sin(line);
            106         sample ts;
            107         while (sin >> d)
            108         {
            109             ts.features.push_back(d);
            110         }
            111         test.push_back(ts);
            112     }
            113     fin.close();
            114 }
            115 
            116 // 計算歐氏距離
            117 double euclideanDistance(const vector<double>& v1, const vector<double>& v2)
            118 {
            119     assert(v1.size() == v2.size());
            120     double ret = 0.0;
            121     for (vector<double>::size_type i = 0; i != v1.size(); ++i)
            122     {
            123         ret += (v1[i] - v2[i]) * (v1[i] - v2[i]);
            124     }
            125     return sqrt(ret);
            126 }
            127 
            128 // 初始化距離矩陣
            129 // 該矩陣是根據訓練樣本和測試樣本而得
            130 // 矩陣的行數為測試樣本的數目,列數為訓練樣本的數目
            131 void initDistanceMatrix(vector<vector<double> >& dm, const vector<sample>& train, const vector<sample>& test)
            132 {
            133     for (vector<sample>::size_type i = 0; i != test.size(); ++i)
            134     {
            135         vector<double> vd;
            136         for (vector<sample>::size_type j = 0; j != train.size(); ++j)
            137         {
            138             vd.push_back(euclideanDistance(test[i].features, train[j].features));
            139         }
            140         dm.push_back(vd);
            141     }
            142 }
            143 
            144 // K-近鄰法的實現
            145 // 設定不同的 k 值,給每個測試樣例予以一個類型
            146 // 距離和權重成反比
            147 void knnProcess(vector<sample>& test, const vector<sample>& train, const vector<vector<double> >& dm, unsigned int k)
            148 {
            149     for (vector<sample>::size_type i = 0; i != test.size(); ++i)
            150     {
            151         multimap<doublestring> dts;
            152         for (vector<double>::size_type j = 0; j != dm[i].size(); ++j)
            153         {
            154             if (dts.size() < k)
            155             {
            156                 dts.insert(make_pair(dm[i][j], train[j].type));
            157             }
            158             else
            159             {
            160                 multimap<doublestring>::iterator it = dts.end();
            161                 --it;
            162                 if (dm[i][j] < it->first)
            163                 {
            164                     dts.erase(it);
            165                     dts.insert(make_pair(dm[i][j], train[j].type));
            166                 }
            167             }
            168         }
            169         map<stringdouble> tds;
            170         string type = "";
            171         double weight = 0.0;
            172         for (multimap<doublestring>::const_iterator cit = dts.begin(); cit != dts.end(); ++cit)
            173         {
            174             // 不考慮權重的情況,在 k 個樣例中只要出現就加 1
            175             // ++tds[cit->second];
            176 
            177             // 這里是考慮距離與權重的關系,距離越大權重越小
            178             tds[cit->second] += 1.0 / cit->first;
            179             if (tds[cit->second] > weight)
            180             {
            181                 weight = tds[cit->second];
            182                 type = cit->second;
            183             }
            184         }
            185         test[i].type = type;
            186     }
            187 }
            188 
            189 // 輸出結果
            190 // 輸出的格式和訓練樣本的格式一樣
            191 // 每行表示一個樣例,第一個元素是該樣例的類型,后面是該樣例的特征向量
            192 // 例如:
            193 /*
            194 a    1 2 3 2 4 
            195 b    2 3 4 2 1 
            196 b    8 7 2 3 5 
            197 a    -3 -2 2 4 0 
            198 d    -4 -4 -4 -4 -4 
            199 a    1 2 3 4 4 
            200 b    4 4 3 2 1 
            201 c    3 3 3 2 4 
            202 d    0 0 1 1 -2 
            203 */
            204 void writeTest(const vector<sample>& test, const string& file)
            205 {
            206     ofstream fout(file.c_str());
            207     if (!fout)
            208     {
            209         cerr << "File error!" << endl;
            210         exit(1);
            211     }
            212     for (vector<sample>::size_type i = 0; i != test.size(); ++i)
            213     {
            214         fout << test[i].type << '\t';
            215         for (vector<double>::size_type j = 0; j != test[i].features.size(); ++j)
            216         {
            217             fout << test[i].features[j] << ' ';
            218         }
            219         fout << endl;
            220     }
            221 }
            222 
            223 // 封裝
            224 void knn(const string& file1, const string& file2, const string& file3, int k)
            225 {
            226     vector<sample> train, test;
            227     readTrain(train, file1.c_str());
            228     readTest(test, file2.c_str());
            229     vector<vector<double> > dm;
            230     initDistanceMatrix(dm, train, test);
            231     knnProcess(test, train, dm, k);
            232     writeTest(test, file3.c_str());
            233 }
            234 
            235 // 測試
            236 int main()
            237 {
            238     knn("train.txt""test.txt""result.txt"5);
            239     return 0;
            240 }
            241 




            posted on 2012-02-14 09:47 unixfy 閱讀(4916) 評論(0)  編輯 收藏 引用
            欧美亚洲日本久久精品| 人妻无码久久精品| 国产激情久久久久影院老熟女免费| 国产精品久久久久影院色| 91精品久久久久久无码| 久久人妻少妇嫩草AV蜜桃| 99久久综合国产精品免费| 久久综合狠狠综合久久| 亚洲国产精品久久66| 一级A毛片免费观看久久精品| 午夜天堂精品久久久久| 久久这里只有精品久久| 亚洲国产精品无码久久青草| 久久精品国产亚洲av麻豆色欲| 国产激情久久久久影院老熟女| 久久婷婷五月综合国产尤物app | 伊人久久大香线蕉综合Av | 久久精品国产久精国产果冻传媒| 久久久久久九九99精品| 久久综合视频网站| 国产91色综合久久免费| 香蕉久久夜色精品国产尤物| 丁香五月网久久综合| 久久久无码精品亚洲日韩京东传媒| 久久国产精品99国产精| 香蕉久久影院| 91久久福利国产成人精品| 亚洲精品乱码久久久久久自慰 | 亚洲午夜久久久精品影院| 中文无码久久精品| 久久夜色精品国产| 51久久夜色精品国产| 2021久久国自产拍精品| 亚洲AV无码久久精品色欲| 色偷偷88欧美精品久久久| 亚洲国产成人久久综合一 | 久久午夜夜伦鲁鲁片免费无码影视| 久久综合九色综合97_久久久| 久久精品国产亚洲αv忘忧草| 久久午夜综合久久| 久久精品18|