【雲端大資料實戰】大資料誤區、大資料處理步驟分析

李博Garvin發表於2014-07-21

1.背景

      
      首先感謝這次部落格的主辦方CSDN以及在初賽為我投票的網友們,你們的支援是Garvin前進的動力。本文思路的依據來源於本次天貓大資料競賽長達三個月的參賽體驗。博主作為一個在校的學生,可能如果不是這次比賽,很難能夠擁有一套完整的雲環境來對TB級的資料進行分析和實踐。下面是博主的一點心得,在此拋磚引玉,希望能給大家在雲端大資料處理方面帶來一點啟示。


2.對於大資料和雲的一些誤區

 

  (1)誤區一:雲的計算能力是無窮的,不用考慮效率?

      
       我們都知道,雲端計算的本質就是分散式計算,將現有的工作量,分割開來讓n個不同的伺服器協同完成。說白了雲端計算的計算能力雖然比我們的pc有優越許多,但是它是有計算成本的。當我們處理TB級資料的時候,我們還是儘量要考慮一下效率,否則會陷入漫長的等待。
ps:博主參加比賽的時候,因為一開始沒有使用抽樣演算法,將整個訓練集拿去訓練,佔用了大量的資源,常常一等就是24小時。

 

   (2)誤區二:資料量越大,預測效果越好?

     

       大資料計算,顧名思義。就是需要一個很大的資料量,通過一些演算法,找到它們和目標序列的特定規則和聯絡。這就容易造成一個誤區,是不是資料量越大,結果準確。其實對於推薦系統來講,當我們使用隨機森林或是gbrt這些演算法的時候,資料集在幾百萬的時候往往能得到比資料集在幾千萬的時候更好的計算效果。因為對於一個演算法來講,如果資料集過大,容易造成過擬合。

       所以在面對一個真正的大資料集的時候,不要盲目的拿來全部訓練,做好抽樣和正負樣本的比例調整,可能會得到更好的效果。 

  

  (3)誤區三: 演算法的引數是一成不變的?       

       
        在對大資料進行處理的時候,我們往往使用一些已經比較成熟的演算法。例如常用的分類演算法有svm(支援向量機)、rf(隨機森林)、lr(邏輯迴歸)等等。在使用這些演算法的時候往往要面對一個比較頭疼的問題就是調參。是否能調到一個理想的引數,對於最後的計算結果有著至關重要的作用。
      對於引數,我覺得沒有最好的引數,只有最合適的引數。不要迷信論文或是網上的一些評論,如果你的訓練集是獨一無二的,就要靜下心來,認真除錯最適合自己的引數。影響一個演算法的引數的因素很多,包括樣本數量或是正負樣本比例等。
      
  (4)誤區四:特徵越多越好麼?
      
      特徵重在質量而不是數量,好的特徵對於結果的影響可能會比普通特徵大100倍,所以千萬不要隨便的組合資料集的一些欄位。有的時候一些不好的特徵,會對結果產生消極的影響。區分特徵對與結果的影響的方法有很多,下面給一個資訊熵的方法:
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1      #the last column is used for the labels
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):        #iterate over all the features
        featList = [example[i] for example in dataSet]#create a list of all the examples of this feature
       
        uniqueVals = set(featList)       #get a set of unique values
        
        newEntropy = 0.0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)     
        infoGain = baseEntropy - newEntropy     #calculate the info gain; ie reduction in entropy
        
        if (infoGain > bestInfoGain):       #compare this to the best gain so far
            bestInfoGain = infoGain         #if better than current best, set to best
            bestFeature = i
    return bestFeature                      #returns an integer

3.大資料雲處理步驟

   
  (1)首先要了解整合環境
              
       既然是大資料處理,那麼一定是要有一個雲環境作為依託。我覺得首先要了解自己的整合環境的基本使用方法,像是spark、hadoop或是odps,他們都有自己的特點。比如博主使用的odps,對於資料庫的處理可以用命令列執行sql語句,也可以用MapReduce的方法將寫好的jar檔案放到雲端處理。
   
   (2)資料集去噪
     
       對於一個比較大的資料集,肯定是存在一些噪聲部分影響我們的計算操作。將這部分噪音去掉可以保證計算結果的準確性。去噪的方法有很多,這裡舉出一個常用的方法,就是將數值在   [均值-  3倍方差,均值 + 3倍方差] 以外的資料濾掉。下面是我寫的一個實現以上去噪方法的程式碼,執行DenoisMat函式可以實現此功能。
from __future__ import division
def GetAverage(mat):
    
    n=len(mat)
    m= width(mat) 
    num = [0]*m
    for j in range(0,m): 
           for i in mat:
              num[j]=num[j]+i[j]           
           num[j]=num[j]/n   
    return num

def width(lst):
    i=0
    for j in lst[0]:
       i=i+1
    return i

def GetVar(average,mat):    
    ListMat=[]
    for i in mat:    
        ListMat.append(list(map(lambda x: x[0]-x[1], zip(average, i))))
   
    n=len(ListMat)
    m= width(ListMat) 
    num = [0]*m
    for j in range(0,m): 
        for i in ListMat:
                  num[j]=num[j]+(i[j]*i[j])       
        num[j]=num[j]/n   
    return num 

def DenoisMat(mat):
    average=GetAverage(mat)
    variance=GetVar(average,mat)
    section=list(map(lambda x: x[0]+x[1], zip(average, variance)))    
    
    n=len(mat)
    m= width(mat) 
    num = [0]*m
    denoisMat=[]    
    for i in mat:
        for j in range(0,m):
               if i[j]>section[j]:
                     i[j]=section[j]
        denoisMat.append(i)  
    return denoisMat  

   (3)訓練集取樣
            
      上文中已經提到了,正確的取樣可以提高計算的準確性。常用的取樣的方法有隨機取樣、系統取樣、分層取樣。

隨機取樣:根據樣本的編號random出來需要的樣本數量。
系統取樣:即先將總體的觀察單位按某一順序號分成n個部分,再從第一部分隨機抽取第k號觀察單位,依次用相等間距,從每一部分各抽取一個觀察 單位組成樣本。
分層取樣:先按對觀察指標影響較大的某種特徵,將總體分為若干個類別,再從每一層內隨機抽取一定數量的觀察單位,合起來組成樣本。有按比例 分配和最優分配兩種方案。

        效果的比較是,分層取樣>系統取樣>隨機取樣。以下程式碼實現了系統取樣和隨機取樣,分層取樣可以根據自己的資料集結合聚類演算法來實現。如果是監督學習的話,記得調整正副樣本的比例哦。
'''
Sampling archive

@author: Garvin Li
'''
import random

def RandomSampling(dataMat,number):
    try:
         slice = random.sample(dataMat, number)    
         return slice
    except:
         print 'sample larger than population'

def SystematicSampling(dataMat,number):    
    
       length=len(dataMat)
       k=length/number
       sample=[]     
       i=0
       if k>0 :       
         while len(sample)!=number:
            sample.append(dataMat[0+i*k])
            i+=1            
         return sample
       else :
         return RandomSampling(dataMat,number)   


  (4)選擇演算法訓練樣本
  
         上面已經提到了很多的演算法。針對不同的資料集,應該選用不同的演算法。舉個例子,這次比賽線上下賽的時候,因為資料集比較小,我們使用的邏輯迴歸演算法就取得了不錯的成績。但是到了線上比賽,隨著資料量增加到TB級別,發現邏輯迴歸已經不給力了。使用GBRT可以取得更理想的效果,具體用法可以參考阿里大資料比賽sesson2_RF&GBRT.一些常用的演算法也可以clone我的github程式碼庫(不斷更新中),本文最下方給出地址。

圖  3-1 My git-repo

   (5)模型融合
   
       模型融合的概念也是這次參加比賽第一次聽說的。其實原理很簡單,每種演算法因為自身的收斂方式不同、對特徵的調配方式不同,在結果上是有比較大的差異的。如果將不同的模型計算結果加權求和的話,可以充分體現每個演算法的長處,對於結果的提升是有比較大幫助的。

4.總結

      
       我始終堅信大資料和雲端計算可以改變我們的生活方式甚至我們的意識形態。在進行大資料處理的過程中,看著自己的成績一點一滴的提升,內心會有極大的滿足感。希望有相同志趣的朋友可以留言討論,大家一起學習進步,謝謝大家。
我的Github頁:點選開啟連結



本文參考了:《機器學習與演算法》和 csdn 

u010691898的專欄




/********************************

* 本文來自部落格  “李博Garvin“

* 轉載請標明出處:http://blog.csdn.net/buptgshengod

******************************************/




相關文章