日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

關(guān)于weka中Instances的屬性刪除

系統(tǒng) 2344 0

最近這些天一直在用weka實現(xiàn)一個算法,也是從這次開始接觸weka,剛上手難免有些磕磕絆絆,這次實現(xiàn)也是遇到了各種各樣的問題,其中的一個就 和weka中的Instances有關(guān),剛剛把程序跑起來了,因為數(shù)據(jù)比較多,沒有個一天兩天估計是跑不完了,趁這個空閑時間,把我遇到的問題及解決方法 記錄下來,一是這樣可能會幫助到其他人,還有就是也方便我自己以后查閱,畢竟俗話說得好,爛筆頭勝過好記性。

首先,weka是從事數(shù)據(jù)挖掘相關(guān)研究的人一定會接觸到的一個軟件,這個軟件由新西蘭waikato大學(xué)編寫,里面實現(xiàn)了種類繁多的算法,這里就不一一介紹,相信用過weka的人都知道我在說什么。

這篇隨筆將會從三個具體的和屬性選擇相關(guān)的實際問題出發(fā),給出具體的解決辦法及代碼。在討論實際問題之前,先來說說為什么需要屬性刪除,也就是需求的問題。

?

一、為什么需要屬性刪除

我們知道,在做交叉驗證的時候,在訓(xùn)練集上做過什么處理,這些處理必須原封不動地施加到測試集上,這樣分類得到的結(jié)果才是可信的。

大 數(shù)據(jù)時代已經(jīng)來臨,我們經(jīng)常會遇到那種實例多,維度高(屬性多)的大數(shù)據(jù),處理這樣的數(shù)據(jù)時,從效果和效率兩方面來考慮,我們都需要先對數(shù)據(jù)進行預(yù)處理, 最常見的一種預(yù)處理的方式就是屬性選擇,也就是我現(xiàn)在一直在做的東西,所謂屬性選擇,從字面上理解,就是從高維的數(shù)據(jù)中選擇出一部分的屬性,用這部分屬性 代替屬性總體,這樣一來,很顯然能夠減少數(shù)據(jù)處理的時間,另外,如果算法選擇得當(dāng),我們能得到更好的結(jié)果,比如說,分類的精度更高。

如果我 們用屬性選擇后的訓(xùn)練集構(gòu)建了一個分類器,我們怎么測試這個分類器的好壞呢,還是要靠實驗說話,在測試集上測試這個分類器的精度,前面說過,在分類的時候 在訓(xùn)練集上的處理必須原封不動的施加到測試集上,訓(xùn)練集上屬性選擇了,測試集也要屬性選擇,并且選出來的屬性必須和訓(xùn)練集上選出來的屬性完全一致,為了得 到屬性選擇后的測試集,顯然,除了訓(xùn)練集上選擇出來的屬性,測試集上的其他屬性都要刪除。

?

二、三個具體的問題

為了更好的描述這幾個問題,我們定義一些變量,這些變量在三個問題中通用。

      train:訓(xùn)練集   test:測試集
      
trainInstance:在訓(xùn)練集上屬性選擇之后返回的訓(xùn)練集 testInstances:依據(jù)trainInstances在test上刪除相應(yīng)的屬性返回的測試集
trainIndex:在訓(xùn)練集上屬性選擇之后返回的訓(xùn)練集的下標(biāo)數(shù)組

1.屬性選擇算法返回的是trainInstances,這個時候,為了得到testInstances,可以使用下面這段代碼

      
        public
      
      
        static
      
      
         Instances delAttr(Instances model, Instances origin){

        
      
      
        boolean
      
       flag = 
      
        false
      
      
        ;

        ArrayList
      
      <Integer> al = 
      
        new
      
       ArrayList<Integer>
      
        ();

        
      
      
        for
      
      (
      
        int
      
       q = 0; q < origin.numAttributes() - 1; q++
      
        ){

            String temp2 
      
      =
      
         origin.attribute(q).name();
      
      
        for
      
      (
      
        int
      
       x = 0; x < model.numAttributes() - 1; x++
      
        ){

                String temp1 
      
      = model.attribute(x).name();  

                
      
        if
      
      
        (temp1.equals(temp2)){

                    flag 
      
      = 
      
        true
      
      
        ;
      
      
        break
      
      
        ;

                }

            }

            
      
      
        if
      
      
        (flag)

            {

                flag 
      
      = 
      
        false
      
      
        ;

                
      
      
        continue
      
      
        ;

            }

            
      
      
        else
      
      
        //
      
      
                        dataCopy.deleteAttributeAt(q);   
      
      
        //
      
      
        you can not do like this
      
      

                al.add(
      
        new
      
      
         Integer(q));

        }

        

        
      
      
        for
      
      (
      
        int
      
       q = 0; q < al.size(); q++
      
        ){
      
      
        int
      
       deltemp = al.get(q) - q;        
      
        // pay attention to this line


      
      
                    origin.deleteAttributeAt(deltemp);

        }



        
      
      
        return
      
      
         origin;

    }
      
    

model相當(dāng)于trainInstances,origin相當(dāng)于test,返回的origin相當(dāng)于testInstances.

上面這段代碼的思想無非就是通過屬性的名字把需要刪除的屬性的下標(biāo)全部存放在一個ArrayList的數(shù)據(jù)結(jié)構(gòu)中,然后根據(jù)這個ArrayList刪除對應(yīng)的屬性,返回新構(gòu)造的Instances.

注意上面我寫的兩行注釋,因為你刪除一條屬性之后,排在這條屬性之后的所有屬性的index都是會變化的(-1),這就相當(dāng)于你從String刪除一個字符一樣,知道這一點,你就知道為什么第二條注釋對應(yīng)的刪除方法可以正常工作了。

注意:如果你用的數(shù)據(jù)集中有兩個或多個屬性的名字完全一樣,這種方法會把擁有這個名字的所有屬性都保留,但是,有可能你真正需要的只是其中一個。

?

2.直接使用1返回的結(jié)果交給分類器,往往會報錯,其中的原因有點微妙,解釋如下:

假 設(shè)train有四個屬性,分別是{attr1,attr2,attr3,attr4},attr4是類標(biāo)簽,test也是這樣 在train上屬性選擇,返回trainInstances{attr3,attr2,attr4},把trainInstances和test交給1, 返回的是testInstances{attr2,attr3,attr4},把testInstances交給分類器,報錯,報錯的原因是 trainInstances和testInstances的屬性錯位了.

這種情況下,我們需要交換兩個屬性的位置,下面這段代碼解決了這個問題

      
        public
      
      
        static
      
      
         Instances sort(Instances model, Instances process){

      Attribute attr;

      
      
      
        for
      
      (
      
        int
      
       i = 0; i < model.numAttributes()-1; i++
      
        ){

          
      
      
        for
      
      (
      
        int
      
       j = 0; j < process.numAttributes()-1; j++
      
        ){

              
      
      
        if
      
      
        (process.attribute(j).name().equals(model.attribute(i).name())){

                  
      
      
        if
      
      (j!=
      
        i){

                     attr 
      
      =
      
         process.attribute(j);

                     process.insertAttributeAt(attr, i);

                     
      
      
        for
      
      (
      
        int
      
       k = 0; k < process.numInstances(); k++
      
        ){

                         process.instance(k).setValue(i, process.instance(k).stringValue(j
      
      +1
      
        ));    //pay attention to j+1

                     }

                     
      
      
        break
      
      
        ;

                  }

              }

          }

      }

      
      
      
        for
      
      (
      
        int
      
       i = process.numAttributes() - 2; i > model.numAttributes()-2; i--
      
        ){

          process.deleteAttributeAt(i);;

      }

      
      
      
        return
      
      
         process;

  }
      
    

?

model相當(dāng)于trainInstances,process相當(dāng)于1中返回的testInstances,2中返回的process就是能和trainInstances的每個屬性對應(yīng)起來的testInstances。

這段代碼的思想是找到 process中每個屬性在model中的對應(yīng)位置,然后再process的對應(yīng)位置插入這個屬性,插入屬性的時候需要把屬性值復(fù)制過去。

注意因為我用到的數(shù)據(jù)都是nominal類型的,所以在復(fù)制屬性值的時候選的是stringValue這個方法,如果是numeric或者其他的類型需要選擇對應(yīng)的方法,這個在weka的Instance類中可以找到。

?

3.屬性選擇算法返回的是下標(biāo)數(shù)組trainIndex

3和1的不同之處在于省去了自己用屬性名去匹配的這個步驟,也因此,即使數(shù)據(jù)集中有多個屬性的名字完全一致,也沒有影響,因為返回的是下標(biāo)。

這種情況可以用下面的代碼:

      
        public
      
      
        static
      
       Instances delAttr(ArrayList<Integer>
      
         al, Instances inst){

        
      
      
        for
      
      (
      
        int
      
       i = inst.numAttributes() - 1; i > -1; i--){    
      
        //
      
      
        delete from back to forward
      
      
        if
      
      (!
      
        al.contains(i))

                inst.deleteAttributeAt(i);

        }

        

        
      
      
        return
      
      
         inst;

    }
      
    

?

注意:這段代碼我是從后往前刪的,這種刪除方法不會出現(xiàn)問題,因為每次刪除的都是需要刪除的屬性的最后一個,對前面需要刪除的屬性的下標(biāo)不會有任何影響。

注意:拿到屬性下標(biāo)之后,先看看是不是排序過,沒有排序的話,最好先排序一下,按從小到大的順序排,這樣雖然需要花費一點額外的時間,有時卻能避免意想不到的錯誤,具體原因我說不清楚,但是我遇到過。

?

三、總結(jié)

很顯然,第三種情況最簡單,代碼清晰,花費的時間也相對較少,所以在屬性選擇之后能夠直接拿到下標(biāo)數(shù)組最好,否則將拿到的結(jié)果轉(zhuǎn)化成下標(biāo)數(shù)組也可以。

?

?

關(guān)于weka中Instances的屬性刪除


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 革吉县| 阿荣旗| 屏边| 泉州市| 隆昌县| 天镇县| 五大连池市| 雷波县| 东乡县| 静安区| 库尔勒市| 方城县| 文水县| 扶绥县| 泽普县| 云南省| 襄垣县| 苍南县| 东兰县| 三原县| 绥芬河市| 英山县| 古蔺县| 板桥市| 大同市| 洛宁县| 甘洛县| 沧州市| 郑州市| 永吉县| 武穴市| 施秉县| 孝昌县| 云梦县| 桦川县| 曲水县| 闵行区| 中山市| 崇礼县| 清水县| 中方县|