1. 程式人生 > >kaggle | 基於樸素貝葉斯分類器的語音性別識別

kaggle | 基於樸素貝葉斯分類器的語音性別識別

概要: 本實驗基於kaggle上的一個資料集,採用樸素貝葉斯分類器,實現了通過語音識別說話人性別的功能。本文將簡要介紹這一方法的原理、程式碼實現以及在程式設計過程中需要注意的若干問題,程式碼仍然是用MATLAB寫成的。 關鍵字: MATLAB; 語音性別識別; 樸素貝葉斯分類器  

1 背景說明

   由於我之前曾做過用樸素貝葉斯分類器進行手寫體識別(基於MINIST資料集,之後也將整理到此部落格上來)的小作業,所以對這個分類器比較熟悉,因而在此不再贅述其原理。網上有很多關於這個分類器的資料,包括樸素貝葉斯分類器Naive Bayes classifier以及各種視訊資料等等,都是比較優質的資源,隨手即可查閱。本文我主要討論怎樣把這個方法用到

該資料集上去。

2 關於資料集

2.1 什麼是kaggle

   這是我在部落格中首次提到kaggle,因此有必要向讀者作簡要介紹。

   WiKi上說得很清楚:Kaggle是一個數據建模和資料分析競賽平臺。企業和研究者可在其上釋出資料,統計學者和資料探勘專家可在其上進行競賽以產生最好的模型。這一眾包模式依賴於這一事實,即有眾多策略可以用於解決幾乎所有預測建模的問題,而研究者不可能在一開始就瞭解什麼方法對於特定問題是最為有效的。Kaggle的目標則是試圖通過眾包的形式來解決這一難題,進而使資料科學成為一場運動。

   而對於我來說它最大的好處就是有免費的資料集可供下載,涉及的內容方方面面——不管你有什麼需求都可以去上面試著找一波,而且能找到滿意資源的概率還不小。

2.2 資料集處理

   這個資料集是基於對男女語音段進行合理的聲音預處理而得到的語音特徵(並不包含原始語音段)。集合中共有3168條資料,男女各1584條,每條資料可視作一個長度為21的一維陣列。其中前20個數值是這條語音的20個特徵值,這些特徵值包括了語音訊號的長度、基頻、標準差、頻帶中值點/一分位頻率/三分位頻率等;最後一個數值是性別標記。元資料集中直接以字串,即male和female進行標註,我則用0表示男性、1表示女性以方便後續處理,這當然並無大礙。

   若有興趣繼續深入瞭解該資料集相關資訊,請參見此連結

   現在進行資料集的預處理。剛下載下來的原始檔案是CSV檔案,首先讀入MATLAB成為一個3168*21的矩陣。而貝葉斯分類器比較難以處理非整數特徵的資料,所以下一步就是量化。

   貝葉斯分類器是基於條件概率而進行分類的,所以最重要的一點是資料處理不能改變其分佈律,因此一定要進行線性量化。而在這裡事實上對結果有影響的是每個特徵的相對數值而非絕對大小,故僅量化相對量即可。也就是說,以某一特徵在所有實驗資料(如上文所說,共計3168條)中的最大、最小值分別作為量化之後的最大、最小值,而不用去管小於最小值的所謂“基礎量”。

   圖1和圖2分別展示了所有3168條資料的第4號特徵在量化前後的圖景,量化階取20。從中明顯可見線性量化不改變原始資料的分佈律。

圖1 量化前
圖2 量化後

     量化階也是一個需要考慮的引數。量化階越大,量化越粗糙,計算量越小;量化階越小,量化越細緻,計算量越大。其對最後結果準確性的影響將在後文加以討論。

   另外,仔細觀察資料會發現其中有不少數值為0項,這是原始資料的缺項,我直接採用均值加以彌補,在不確定的時候優先考慮均值總不失為一種穩妥的處理方法。注意,對缺項資料的補寫應當最優先處理。

   最後一步也可以看做是所有學習演算法的第一步:劃分訓練集和驗證集。在這裡不妨多補充幾句關於訓練集、驗證集和測試集的區別和聯絡。一般而言,在不考慮測試集時訓練集、驗證集常採用7:3或8:2的數量劃分,考慮到測試集時一般劃分為6:2:2。原始資料集的劃分還是很有講究的,周志華教授在他著名的科普大作《機器學習》中對此有很詳細的討論。本實驗中我優先按照7:3的比例劃分訓練集和驗證集。

3 程式碼實現

3.1 檔案目錄

   現在來介紹一下程式碼的檔案目錄以及各個檔案之間的聯絡。本實驗用到的全部程式如圖1所示:

圖3 所需檔案列表

   其中倒數第三個.xls檔案就是下載得到的檔案,將它通過檔案xls2,mat.m之後即可獲得voice_data.mat檔案,這就是上文所提到的那個3168*21矩陣。之後再經過檔案mydiscretization.m進行量化處理就得到了量化後的資料檔案,該資料檔案覆蓋voice_data.mat。通過檔案training.m得到訓練集TrainingSets.mat以及通過檔案validation.m得到驗證集ValidationSets.mat。在實驗中,先後執行training.m和validation.m即可得到結果。另外的3個.m檔案是輔助性檔案,是在我寫程式過程中測試程式碼的正確性順手寫的,它們的功能分別是:

   myhowmany.m:查詢某個資料在某個矩陣中的數量。    myisinterger.m:查詢某矩陣中整數的個數,並找出非整數元素的座標。    myrowcheck.m:找出某2個矩陣的相同行並返回其在原矩陣中的行座標。

   這三個程式碼檔案不是本實驗所必須的,但是在寫與陣列有關的程式碼時不失為不錯的輔助工具。

3.2 核心程式碼

   核心程式碼其實很少,只有二三十行,是有關計算後驗概率的。

   資料訓練步驟的核心程式碼如下:

for j=1:20
    for i=1:stepnum
        TrainingSets(1).feature_prob(i,j) = ...
            (myhowmany(i,TrainingSets(1).feature(:,j))+1)/(M_train_num+1);
        TrainingSets(2).feature_prob(i,j) = ...
            (myhowmany(i,TrainingSets(2).feature(:,j))+1)/(F_train_num+1);
    end
end

   這就得到了每一個特徵在量化範圍內的每一個可能取值的概率。

   資料驗證步驟的核心程式碼如下:

for i=1:2
    for j=1:ValidationSets(i).number              % for each voice
        data = ValidationSets(i).feature(j,:);
        for k=1:20
            % probability of being male voice
            ValidationSets(i).results(j,1)=...
                TrainingSets(1).feature_prob(data(k),k)*ValidationSets(i).results(j,1);
            % probability of being female voice
            ValidationSets(i).results(j,2)=...
                TrainingSets(2).feature_prob(data(k),k)*ValidationSets(i).results(j,2);
        end
        if ValidationSets(i).results(j,1) > ValidationSets(i).results(j,2)
            % this is male voice
            ValidationSets(i).results(j,3) = 0;
        else
            % this is female voice
            ValidationSets(i).results(j,3) = 1;
        end
    end
end

   這就得到了每一條待驗證的資料分別為男聲和女聲的概率,通過比較大小即可得出最終判斷。

3.3 注意點

   從實際應用角度來看,樸素貝葉斯分類法其實並不太適合於特徵數量過多的分類問題,不管是二分類還是多分類。這是由於該方法本質上是概率的疊乘,每有一個特徵就需要進行一次概率相乘,而這裡有20個特徵就需要乘上20次。而概率都是小於1的,所以在計算上頗為麻煩——會得到小於10的負20次方的小數。對這個問題可以採用每次都乘以某個略大於1的常數如sqrt(2)來補償,或者取對數。

   另外一個就是計算量,這一點可以通過不考慮全概率以及人為操作使得先驗概率相同這兩樣手法來減少一些運算。

   第三點比較細節,在於若某個新資料在某個特徵處取到了訓練集所未曾取到的資料,就會得出此處的後驗概率為0的結果,從而通過概率連乘導致最終的概率為0,而這顯然是不正確的。解決措施也很簡單,只要在每次計算時分子分母同時加1即可,而因此所造成的誤差可以認為是忽略不計的。

4 實驗與結果分析

   影響實驗結果的因素主要有2個:量化階數目和資料集比例,因此實驗主要圍繞這兩個引數的改變進行。另外還有一點需要注意的就是:由於資料集是隨機劃分的,所以每次訓練-驗證的結果有少許不同是正常的,這是因為每次劃分到訓練集和驗證集中的資料條目並不完全相同。所以我在引數沒有改變時連做3次訓練-驗證實驗,取結果的平均值作為在該組量化數目和資料集比例條件下所得模型的識別效果。

   簡略起見,我在量化數目和資料集比例這兩個引數上各取兩點:量化階為10和20,訓練集和驗證集比例為7:3和8:2。得到的結果如圖4所示:

圖4 實驗結果

     從上圖中可以看出:首先,樸素貝葉斯分類器對男聲的判斷效果明顯好於女聲;第二,在這四組引數中,量化階數目選為20、訓練集和驗證集比例選為8:2(即1267:317)時相對而言效果最好;第三,量化階選取10和20對識別結果並無顯著影響。

   顯然只選取4組引數是很無法準確體現該演算法效能的,但是我比較懶,讀者如有興趣不妨可以多做幾組實驗,看看能不能找出一組引數使得分辨效果優越的同時儘可能減小量化階數目,即在效果和運算之間達到一個較好的平衡。

5 後記

   本實驗的一個遺憾就是沒有建立測試程式碼,也就不能實時檢測現場錄入的語音性別。這是因為此資料集的來歷我還沒有研究透徹,也就是說還不明白這20個特徵是如何提取出來的。主要還是時間比較緊張,接下來我將花幾天時間爭取把它弄明白。

   轉載時務必註明來源及作者。尊重智慧財產權從我做起。

   程式碼已上傳至網路,歡迎下載,密碼是0lu5