1. 程式人生 > >模糊C均值聚類演算法及實現

模糊C均值聚類演算法及實現

模糊C均值聚類演算法的實現

研究背景

https://blog.csdn.net/liu_xiao_cheng/article/details/50471981

   聚類分析是多元統計分析的一種,也是無監督模式識別的一個重要分支,在模式分類 影象處理和模糊規則處理等眾多領域中獲得最廣泛的應用。它把一個沒有類別標記的樣本按照某種準則劃分為若干子集,使相似的樣本儘可能歸於一類,而把不相似的樣本劃分到不同的類中。硬聚類把每個待識別的物件嚴格的劃分某類中,具有非此即彼的性質,而模糊聚類建立了樣本對類別的不確定描述,更能客觀的反應客觀世界,從而成為聚類分析的主流。

  模糊聚類演算法是一種基於函式最優方法的聚類演算法,使用微積分計算技術求最優代價函式,在基於概率演算法的聚類方法中將使用概率密度函式,為此要假定合適的模型,模糊聚類演算法的向量可以同時屬於多個聚類,從而擺脫上述問題。

  模糊聚類分析演算法大致可分為三類

 1)分類數不定,根據不同要求對事物進行動態聚類,此類方法是基於模糊等價矩陣聚類的,稱為模糊等價矩陣動態聚類分析法。

2)分類數給定,尋找出對事物的最佳分析方案,此類方法是基於目標函式聚類的,稱為模糊C均值聚類。

3)在攝動有意義的情況下,根據模糊相似矩陣聚類,此類方法稱為基於攝動的模糊聚類分析法

我所學習的是模糊C均值聚類演算法,要學習模糊C均值聚類演算法要先了解慮屬度的含義,隸屬度函式是表示一個物件x隸屬於集合A的程度的函式,通常記做μA(x),其自變數範圍是所有可能屬於集合A的物件(即集合A所在空間中的所有點),取值範圍是[0,1],即0<=μA(x)<=1。μA(x)=1表示x完全隸屬於集合A,相當於傳統集合概念上的x∈A。一個定義在空間X={x}上的隸屬度函式就定義了一個模糊集合A,或者叫定義在論域X={x}上的模糊子集

。對於有限個物件x1,x2,……,xn模糊集合可以表示為:

                (6.1)

    有了模糊集合的概念,一個元素隸屬於模糊集合就不是硬性的了,在聚類的問題中,可以把聚類生成的簇看成模糊集合,因此,每個樣本點隸屬於簇的隸屬度就是[0,1]區間裡面的值。

FCM演算法需要兩個引數一個是聚類數目C,另一個是引數m。一般來講C要遠遠小於聚類樣本的總個數,同時要保證C>1。對於m,它是一個控制演算法的柔性的引數,如果m過大,則聚類效果會很次,而如果m過小則演算法會接近HCM聚類演算法。

演算法的輸出是C個聚類中心點向量和C*N的一個模糊劃分矩陣,這個矩陣表示的是每個樣本點屬於每個類的隸屬度。根據這個劃分矩陣按照模糊集合中的最大隸屬原則就能夠確定每個樣本點歸為哪個類。聚類中心表示的是每個類的平均特徵,可以認為是這個類的代表點。

從演算法的推導過程中我們不難看出,演算法對於滿足正態分佈的資料聚類效果會很好,另外,演算法對孤立點是敏感的。

聚類演算法是一種比較新的技術,基於曾次的聚類演算法文獻中最早出現的Single-Linkage層次聚類演算法是1957年在Lloyd的文章中最早出現的,之後MacQueen獨立提出了經典的模糊C均值聚類演算法,FCM演算法中模糊劃分的概念最早起源於Ruspini的文章中,但關於FCM的演算法的詳細的分析與改進則是由Dunn和Bezdek完成的。

模糊c均值聚類演算法因演算法簡單收斂速度快且能處理大資料集,解決問題範圍廣,易於應用計算機實現等特點受到了越來越多人的關注,並應用於各個領域。

 

 

演算法描述

模糊C均值聚類演算法的步驟還是比較簡單的,模糊C均值聚類(FCM),即眾所周知的模糊ISODATA,是用隸屬度確定每個資料點屬於某個聚類的程度的一種聚類演算法。1973年,Bezdek提出了該演算法,作為早期硬C均值聚類(HCM)方法的一種改進。

FCM把n個向量xi(i=1,2,…,n)分為c個模糊組,並求每組的聚類中心,使得非相似性指標的價值函式達到最小。FCM與HCM的主要區別在於FCM用模糊劃分,使得每個給定資料點用值在0,1間的隸屬度來確定其屬於各個組的程度。與引入模糊劃分相適應,隸屬矩陣U允許有取值在0,1間的元素。不過,加上歸一化規定,一個數據集的隸屬度的和總等於1:

                     (6.9)

那麼,FCM的價值函式(或目標函式)就是式(6.2)的一般化形式:

,              (6.10)

這裡uij介於0,1間;ci為模糊組I的聚類中心,dij=||ci-xj||為第I個聚類中心與第j個數據點間的歐幾里德距離;且是一個加權指數。

    構造如下新的目標函式,可求得使(6.10)式達到最小值的必要條件:

         (6.11)

這裡lj,j=1到n,是(6.9)式的n個約束式的拉格朗日乘子。對所有輸入參量求導,使式(6.10)達到最小的必要條件為:

                         (6.12)

                       (6.13)

由上述兩個必要條件,模糊C均值聚類演算法是一個簡單的迭代過程。在批處理方式執行時,FCM用下列步驟確定聚類中心ci和隸屬矩陣U[1]:

步驟1:用值在0,1間的隨機數初始化隸屬矩陣U,使其滿足式(6.9)中的約束條件

步驟2:用式(6.12)計算c個聚類中心ci,i=1,…,c。

步驟3:根據式(6.10)計算價值函式。如果它小於某個確定的閥值,或它相對上次價值函式值的改變數小於某個閥值,則演算法停止。

步驟4:用(6.13)計算新的U矩陣。返回步驟2。

上述演算法也可以先初始化聚類中心,然後再執行迭代過程。由於不能確保FCM收斂於一個最優解。演算法的效能依賴於初始聚類中心。因此,我們要麼用另外的快速演算法確定初始聚類中心,要麼每次用不同的初始聚類中心啟動該演算法,多次執行FCM。

模糊c均值聚類演算法如下:

Reapeat for l=12 3……..

Step 1:computethe cluseter prototypes(means):

Step 2:competethe distance:

Step 3:Updatethe partition matrix:

 

 

 

演算法改進

 

  1. 在模糊聚類的目標函式中Bezdek引入了加權指數m,使Dum的聚類準則變成m=2時候的特例,從數學上說m的出現不自然且沒有必要,但如果不給以慮屬度乘以權值,那麼從硬聚類準則函式到軟聚類目標函式的推廣準則是無效的,引數m又稱為平滑因子,控制著模式早模糊類間的分享程度,因此,要實現模糊c聚類就要選擇一適合的m,然而最佳的m的選取目前還缺乏理論,監管存在一些經驗值或經驗範圍,但沒有面向問題的優選方法,也缺少引數m的有效性評價準則

  2. 儘管模糊聚類是一種無監督的分類,但現在的聚類演算法卻=需要應用聚類原型的先驗條件,否則演算法會產生誤導,從未破壞演算法的無監督性和自動化。

  3. 因為模糊聚類目標是非凸的,而模糊C均值聚類演算法的計算過程又是迭代爬山,一次很容易陷入區域性極值點,從而得不到最優解或滿意解,同時,大資料量下演算法耗時也是困擾人們的一大難題,這2個問題目前還不能得到全面的解決。

  4. FCM型別的聚類演算法屬於劃份方法,對於1組給定的樣本集,不管資料中有無聚類結構,也不問分類結果是否有效,總把資料劃分到C個子類中,換言之,現有的聚類分析與聚類趨勢,以及有效分析是隔離的分離得。

  5. FCM的聚類演算法是針對特徵空間中的點集設計的,對於特殊型別的資料,比如在樣本每維特徵的賦值不是一個數,而是一個區間。集合和模糊數時,FCM型別的演算法無法直接處理

       模糊C均值聚類演算法存在上述缺點,改進的演算法正確率能達到更高。Fcm演算法在處理小資料集的時候是有效的,但隨著資料容量和維數的增加,迭代步驟會顯著增加,而且在迭代的每一步都要對整個資料集進行操作,無法滿足資料探勘時的需要。

       改進演算法的思想是首先採用隨機抽樣的辦法,從資料集中選取多個樣本,對每個樣本應用FCM演算法,將得到的結果作為初始群體,然後再利用遺傳演算法對聚類結果進行優化,選取其中的最優解做為問題的輸出,由於取樣技術顯著的壓縮了問題的規模,而遺傳又可以對結果進行全域性最優化處理,因此在時間效能和聚類質量上都能獲得較滿意的結果。

    遺傳演算法是美國Michigon大學的John Holland研究機器學習時創立的一種新型的優化演算法,它的主要優點是:遺傳演算法是從一系列點的群體開始搜尋而不是從單個樣本點進行搜尋,遺傳演算法利用適應值的相關資訊,無需連續可導或其他輔助資訊,遺傳演算法利用轉移概率規則,而非確定性規則進行迭代,遺傳演算法搜尋過程中,以對群體進行分化以實現並行運算,遺傳演算法經過遺傳變異和雜交運算元的作用,以保證演算法以概率1收斂到全域性最優解—具有較好的全域性特性,其次遺傳算法佔用計算機的記憶體小,尤其適用計算複雜的非線性問題。

    遺傳演算法的設計部分

  1. 種群中個體的確定

    聚類的關鍵問題是聚類中心的確定,因此可以選取聚類中心作為種群的個體,由於共有C個聚類中心,而每個聚類中心是一個S維的實數向量,因此每個個體的初始值是一個c*s維的市屬向量。

  2. 編碼

    常用的編碼方式有二進位制與實數編碼,由於二進位制編碼的方式搜尋能力最強,且交叉變異操作簡單高效,因此採用二進位制的編碼方式,同時防止在進行交叉操作時對優良個體造成較大的破壞,在二進位制編碼的方式中採用格雷碼的編碼形式。

    每個染色體含c*s個基因鏈,每個基因鏈代表一維的資料,由於原始資料中各個屬性的取值可能相差很大,因此需首先對資料進行交換以統一基因鏈的長度,可以有以下兩種變換方式。

    1掃描整個資料集,確定每維資料的取值範圍,然後將其變換到同一量級,在保留一定有效位的基礎上取整,根據有效位的個數動態的計算出基因鏈的長度。

    2對資料進行正規化處理,即將各維資料都變換到相同的區間,可以算出此時的基因鏈長度為10。

  3. 適應度函式

       由於在演算法中只使用了聚類中心V,而未使用慮屬矩陣u,因此需要對FCM聚類演算法的目標函式進行改進,以適用演算法的要求,和目標函式是等價的,由於遺傳演算法的適用度一般取值極大,因此可取上式的倒數作為演算法的使用度函式。

  4. 初始種群的確定

       初始種群的一般個體由通過取樣後執行FCM演算法得到的結果給出,另外的一般個體通過隨機指定的方法給出,這樣既保證了遺傳演算法在運算之初就利用背景知識對初始群體的個體進行了優化,使演算法能在一個較好的基礎上進行,又使得個體不至於過分集中在某一取值空間,保證了種群的多樣性。

  5. 遺傳操作

       選擇操作採用保持最優的錦標賽法,錦標賽規模為2,即每次隨機取2個個體,比較其適應度,較大的作為父個體,並保留每代的最優個體作為下一代,交叉方式一般採用單點交叉或多點交叉法進行,經過試驗表明單點交叉效果較好,因此採用單點交叉法,同時在交叉操作中,應該對每維資料分開進行,以保證較大的搜尋空間和結果的有效性,變異操作採用基本位變異法。

  6. 終止條件的確定

       遺傳演算法在以下二種情況下終止

    a最佳個體保持不變的代數達到設定的閾值

    b遺傳操作以到達給定的最大世代數

    演算法具體步驟如下

    1確定引數,如聚類個數 樣本集大小 種群規模 最大世代數 交叉概率和變異概率等。

    2對資料集進行多次取樣並執行FCM演算法,得到初始種群的一般個體,通過隨機制定產生另一半個體。

    3對資料集進行正規化處理並編碼。

    4計算初始種群中個體的適應度。

    5對種群進行遺傳操作產生下一代,在操作的過程中,應該排除產生的無效個體。

    6計算個體的適應度,如果滿足終止條件,則演算法結束,否則轉到5繼續

         在理論上講進行遺傳操作的樣本容量越大,聚類的誤差越小,由於取樣技術顯著壓縮了問題規模,而遺傳演算法又可以對全域性進行最優化處理,因此改進的演算法在時間與效能上都能獲得較滿意的結果,此演算法利用取樣技術來提高演算法的執行速度,利用遺傳演算法對聚類進行優化,避免陷入區域性最優解,在效能上相比於傳統的模糊C均值聚類演算法獲得較大提高。

     

     

     

    演算法實現

    ·採用VC++進行編寫

    文件的讀取

    #include "data.h"

    //函式定義

    double **DataRead(char*name,int row,intcol)

    {

        double**p=new double* [row];

     

        ifstreaminfile;

       

        infile.open(name,ios::in);

        for(inti=0;i<row;i++)

        {

           p[i]=newdouble[col];

           for(intj=0;j<col;j++)

           {

               infile>>p[i][j];

           }

        }

     

        infile.close();

     

        cout<<"成功讀取資料檔案:"<<name<<"!\n";

     

        returnp;

     

        //釋放記憶體

        for(i=0;i<row;i++)

        {

           delete[]p[i];

        }

        delete[]p;

     

    }

    文件的儲存

    #include "data.h"

    void DataSave(double**data,int row,intcol,char*name)

    {

        inti,j;

        ofstreamoutfile;

     

        //開啟檔案,輸出資料

        outfile.open(name,ios::out);

        outfile.setf(ios::fixed);

        outfile.precision(4);

       

        for(i=0;i<row;i++)

        {

           for(j=0;j<col;j++)

           {

               outfile<<data[i][j]<<"";             

           }

           outfile<<endl;   

        }

     

        outfile<<endl<<endl;

     

     

       

        outfile.close();

         

    }

     

    資料標準化處理

    #include "data.h"

     

    double **Standardize(double **data,introw,int col)

    {

        inti,j;

        double*a=new double[col];  //矩陣每列的最大值

        double*b=new double[col];  //矩陣每列的最小值

        double*c=new double[row];  //矩陣列元素

       

        for(i=0;i<col;i++)

        {

           //取出資料矩陣的各列元素

           for(j=0;j<row;j++)

           {

               c[j]=Data[j][i];

           }

     

            a[i]=c[0],b[i]=c[0];

          

           for(j=0;j<row;j++)

           {

               //取出該列的最大值

               if(c[j]>a[i])

               {

                  a[i]=c[j];

               }

              

               //取出該列的最小值

               if(c[j]<b[i])

               {

                  b[i]=c[j];

               }  

           }

          

        }

     

        //資料標準化

        for(i=0;i<row;i++)

        {

           for(j=0;j<col;j++)

           {

               data[i][j]=(data[i][j]-b[j])/(a[j]-b[j]);

           }

        }

     

        cout<<"完成資料極差標準化處理!\n";

        delete[]a;

        delete[]b;

        delete[]c;

     

        returndata;

    }

    生成樣本慮屬矩陣

    #include "data.h"

    void Initialize(double **u, int k, introw)

    {

        inti,j;  

        //初始化樣本隸屬度矩陣

        srand(time(0));

        for(i=0;i<k;i++)

        {

           for(j=0;j<row;j++)

           {

               u[i][j]=(double)rand()/RAND_MAX;//得到一個小於1的小數隸屬度

           }//rand()函式返回0和RAND_MAX之間的一個偽隨機數

        }

     

    }

    資料歸一化處理

    #include "data.h"

    void Normalize(double **u,int k,intcol)

    {

        inti,j;

        double*sum=new double[col];

        //矩陣U的各列元素之和

        for(j=0;j<col;j++)

        {

           doubledj=0;

           for(i=0;i<k;i++)

           {

               dj=dj+U[i][j];

               sum[j]=dj;//隸屬度各列之和

           }

        }

     

        for(i=0;i<k;i++)

        {

           for(j=0;j<col;j++)

           {

               u[i][j]=U[i][j]/sum[j];        

           }//規一化處理(每列隸屬度之和為1)

        }

       

     

    }

    迭代過程

    #include "data.h"

    #include "func.h"//對模糊C均值進行迭代運算,並返回有效性評價函式的值

    doubleUpdate(double**u,double**data,double**center,int row,int col, int k)

    {

        inti,j,t;

        double**p=NULL;

     

        for(i=0;i<k;i++)

        {

           for(j=0;j<row;j++)

           {

               //模糊指數取2

               u[i][j]=pow(u[i][j],2);

           }

        }

       

     

        //根據隸屬度矩陣計算聚類中心

        p=MatrixMul(u,k,row,data,row,col);

     

        for(i=0;i<k;i++)

        {

           //計算隸屬度矩陣每行之和

           doublesi=0;

           for(j=0;j<row;j++)

           {

               si+=u[i][j];

           }

     

           for(t=0;t<col;t++)

           {  

               center[i][t]=p[i][t]/si;   //類中心

           }

        }

     

     

        //計算各個聚類中心i分別到所有點j的距離矩陣dis(i,j)   

        double*a=new double[col];      //第一個樣本點

        double*b=new double[col];      //第二個樣本點

     

        double**dis=newdouble*[k];   //中心與樣本之間距離矩陣

       

       

        for(i=0;i<k;i++)

        {

           dis[i]=newdouble[row];

        }

     

     

        for(i=0;i<k; i++)

        {

           //聚類中心

           for(t=0;t<col; t++)

           {

               a[t]=center[i][t];   //暫存類中心

           }

            //資料樣本

           for(j=0;j<row; j++)

           {

               for(t=0;t<col; t++)

               {

                  b[t]=data[j][t];//暫存一樣本

               }

              

               doubled=0;

               //中心與樣本之間距離的計算

               for(t=0;t<col; t++)

               {

                  d+=(a[t]-b[t])*(a[t]-b[t]); //d為一中心與所有樣本的距離的平方和

               }         

          

               dis[i][j]=sqrt(d);     //距離  

          

           }

        }

       

       

        //根據距離矩陣計算隸屬度矩陣   

        for(i=0;i<k;i++)

        {

           for(j=0;j<row;j++)

           {         

               doubletemp=0;

               for(t=0;t<k;t++)

               {     

                  //dis[i][j]依次除以所在列的各元素,加和;

                  //模糊指數為2.0

                  temp+=pow(dis[i][j]/dis[t][j],2/(2.0-1));//一個類中心和一個元素的距離平方與

               }  

     

               u[i][j]=1/temp;//所有類與該元素距離平方的和的商

       

           }

     

        }

     

     

        //計算聚類有效性評價函式

        doublefunc1=0;

        for(i=0;i<k;i++)

        {

           doublefunc2=0;

           for(j=0;j<row;j++)

           {

               func2+=pow(u[i][j],2.0)*pow(dis[i][j],2);

           }

          

           func1+=func2;

       

        }

     

        doubleobj_fcn=1/(1+func1);

     

        returnobj_fcn;

     

     

     

        //記憶體釋放

        delete[]a;

        delete[]b;

       

        for(i=0;i<k;i++)

        {

           delete[]dis[i];

        }

       

        delete[]dis;

       

     

    }

    詳細過程

     

    #include "data.h"

    #include "func.h"

    #include "max.h"

     

    //全域性變數定義

    double **Data;                                      //資料矩陣

    double **Center;                                    //聚類中心矩陣

    double **U;                                         //樣本隸屬度矩陣

     

    int m;                                             //樣本總數

    int n;                                             //樣本屬性數

    int k;                                              //設定的劃分類別數

      

     

     

    int main()

    {

       

        intLab;                                       //資料檔案標號

        intnum;                                       //演算法執行次數

     

        ///////////////////////////////////////////////////////////////

        cout<<"模糊C均值聚類演算法:"<<endl;

        cout<<"1-iris.txt;  2-wine.txt; 3-ASD_12_2.txt; 4-ASD_14_2.txt"<<endl;

        cout<<"請選擇資料集: Lab=";

        cin>>Lab;

        cout<<"設定執行次數: mum=";

        cin>>num;

     

        //各次執行結束後的目標函式

        double*Index=new double[num];

        //各次執行結束後的聚類正確率

        double*R=new double [num];

     

        //num次執行的平均目標函式及平均正確率

        doubleM_Index=0;

        doubleM_R=0;

     

     

        //FCM聚類演算法執行num次,並儲存記錄與結果

        for(inti=0;i<num;i++)

        {

           intj;

           doubleepsilon=1e-4;

           inte=0;

           intnx=0;

           //記錄連續無改進次數

           intE[200]={0};

     

           if(i>0)

           {

               cout<<endl<<endl;

               cout<<setfill('#')<<setw(10)<<endl;

           }

     

           cout<<"第"<<i+1<<"次執行記錄:"<<endl;

          

           //讀取資料檔案

           if(Lab==1)

           {

               m=150;

               n=4;

               k=3;

               Data=DataRead("dataset\\iris.txt",m,n);

           }

           elseif(Lab==2)

           {

               m=178;

               n=13;

               k=3;

              

               Data=DataRead("dataset\\wine.txt",m,n);

           }

           elseif(Lab==3)

           {

               m=535;

               n=2;

               k=12;

              

               Data=DataRead("dataset\\ASD_12_2.txt",m,n);

           }

           elseif(Lab==4)

           {

               m=685;

               n=2;

               k=14;

              

               Data=DataRead("dataset\\ASD_14_2.txt",m,n);

           }

          

          

           //資料極差標準化處理

           Data=Standardize(Data,m,n);

          

          

           //聚類中心及隸屬度矩陣,記憶體分配

           Center=newdouble*[k];

           U=newdouble *[k];

           for(j=0;j<k;j++)

           {

               Center[j]=newdouble[n];

               U[j]=newdouble[m];

           }

          

          

           //隸屬度矩陣的初始化

           Initialize(U,k, m);

       

           //對隸屬度矩陣進行歸一化

           Normalize(U,k,m);

          

           //歷次迭代過程中的目標函式

           doubleObjfcn[100]={0};

          

           cout<<"第"<<i+1<<"次執行記錄:"<<endl;

           cout<<"開始迭代過程!"<<endl;

           cout<<"*******************************"<<endl;

          

           //輸出精度為小數點後5位

           cout.precision(5);

           //固定格式

           cout.setf(ios::fixed);

          

          

           //目標函式連續20代無改進,停止該次聚類迭代過程

           while(e<20)

           {

               nx++;

              

               //聚類迭代過程

               Objfcn[nx]=Update(U,Data,Center,m,n,k);

              

               //統計目標函式連續無改進次數e

               if(nx>0&& Objfcn[nx]-Objfcn[nx-1]<epsilon )

               {

                  e++;

               }

               else

               {

                  e=0;

               }

              

               E[nx]=e;

              

           }

          

          

           //輸出結果到檔案,儲存

           ofstreamoutfile("執行記錄.txt",ios::app);

     

           outfile<<"第"<<i+1<<"次執行記錄:"<<endl;

           outfile<<"開始迭代過程!"<<endl;

           outfile<<"*******************************"<<endl;

          

           outfile.precision(5);

           outfile.setf(ios::fixed);

           for(intn1=1;n1<=nx;n1++)

           {

               cout<<"e["<<setw(2)<<n1<<"]="<<setw(2)<<E[n1]<<"   Objfcn["

                  <<setw(2)<<n1<<"]="<<Objfcn[n1]<<"\n";

               //儲存資料檔案

               outfile<<"e["<<setw(2)<<n1<<"]="<<setw(2)<<E[n1]<<"   Objfcn["

                  <<setw(2)<<n1<<"]="<<Objfcn[n1]<<"\n";

           }

           cout<<endl;

           outfile<<endl;

           outfile.close();

     

           //本次執行的最大目標函式

           Index[i]=Objfcn[nx];

          

           //儲存聚類正確率,輸出聚類結果:  

           R[i]=Result(Lab,U, k, m, i);

          

          

           //記憶體釋放

           for(j=0;j<k;j++)

           {

               delete[]Center[j];

               delete[]U[j];

           }

          

           delete[]Center;

           delete[]U;

          

        }

     

     

        //////////////////////////統計平均///////////////////////////////////

        doubletemp1=0, temp2=0;

        for(i=0;i<num;i++)

        {

           temp1+=Index[i];

           temp2+=R[i];

        }

     

        //計算各次結果的統計平均

        M_Index=(double)temp1/num;

        M_R=(double)temp2/num;

     

        cout<<"//////////////////////////////////////////////////////////////"<<endl;

        cout<<num<<"次執行,平均聚類正確率: "<<100*M_R<<"%"<<endl;

       

        //輸出精度為小數點後6位

        cout.precision(6);

        //固定格式

        cout.setf(ios::fixed);

        cout<<"平均目標函式:"<<M_Index<<endl;

     

     

        //統計結果檔案儲存

        ofstreamresultfile("聚類結果.txt",ios::app);

        resultfile<<"//////////////////////////////////////////////////////////////"<<endl;

        resultfile<<num<<"次執行,平均聚類正確率: "<<100*M_R<<"%"<<endl;

       

        //輸出精度為小數點後6位

        resultfile.precision(6);

        //固定格式

        resultfile.setf(ios::fixed);

        resultfile<<"平均目標函式:"<<M_Index<<endl;

     

     

     

       

        return0;

    }

    採用著名的iris資料集對程式進行測試,

     

    運算次數輸入10次

     

    能對陣列實現分類,但是分類正確率不是很理想,沒達到預期的90%以上

     

    總結

這次綜合實習,首先我學會了模糊C均值聚類演算法,以前沒接觸過,也不知道何為資料集,資料集是做啥用的,增加了自己的見解,其次增強了自我學習能力,平時學習的學習都是老師已經安排好得內容,看啥知識都已經知道,只需要安心的看就能學會,都是書本上的知識,沒有聯絡實際,一般都是一些理論演算法,演算法比較簡單而且古老,但這次綜合實習通過自己從網上查詢資料學習,瞭解演算法的詳細步驟,研究演算法的不足,雖然查詢資料學習的過程比較繁瑣,但總算在最後學會了模糊C均值聚類演算法,也對演算法的改進有所瞭解,人工智慧學習的GA遺傳演算法進行了改進,通過這次綜合實習,我對不懂得知識的學習有了一個比較系統的學習過程,為以後的自我學習打下了基礎,模糊C均值聚類演算法的程式是用c++實現的,通過對程式的而研究,我對於檔案的讀取儲存 計算的迭代過程等都已經非常的瞭解,對於以前所學的進行了一次複習,這次綜合實現收穫很大,自己所學的東西學會了如何使用,不同的演算法進行銜接進行優化,實現對最優解的優化,感謝朱老師的幫助使我能順利的完成綜合實習。

 

 

 

參考文獻

[1] 高新波,模糊c均值聚類演算法中加權指數m的研究[J],電子學報,2000,28(4):80-83

[2] 朱劍英,應用模糊數學方法的若干關鍵問題及處理方法[j].模糊系統與數學,1992,11(2):57-63

[3] 劉蕊潔張金波劉銳,模糊c均值聚類演算法,重慶工學院學報,2007-21-1

[4] 高新波。模糊聚類分析及其應用[M].西安:西安電子科學出版社,2004

[5] 高新波,謝維信.模糊聚類理論發展及應用的研究進展[J].科學通報,1999,44(21):2241-2251

[6] 張潔,高新波,焦李成.基於特徵加權的模糊聚類新演算法[J],電子學報,2006,34(1):412-420

[7] Chan K P, CheungY S. Clustering of clusters [J]. Pattern Recognition,1992,25(2):211-217

[8] Spragins J.Learning withouta teacher[J].IEEE Transactions of Infornation Theory,2005,23(6):223-230.

[9] Babusk R . FUZZY AND NEURALCONTROL[M].Nethealands:Delft University of Technology,2001

[10]Theodoridis S.PatternRecongnition [M]. Second Edition.USA:Elsevier Scinece,2003

[11]MAULIK U.BANDYOPADHYAYS.Genetic algorithm-based clustering technique[J].patternRecognition,2000,33(9):144-1465

[12] J.C.Bezdek.Patternrecognition with fuzzy objective funcition algorithms.New York:Plenum,1981

[13] R.Duda and P.Hart .Patternclassification and scene analysis.New York:Wiley,1973

[14]J.K.Dunn.J.Cybern.1973,3(3):32-57

[15] J.C.Bezdek.IEEETrans.Syst.Man Cybern.1987,17(5):873-877

https://wenku.baidu.com/view/ee968c00eff9aef8941e06a2.html