機器學習開端

機器學習算法中經常出現“有時候”能用,但又不能完全與要求一致。需要指出哪些地方出了問題並解決問題。首先介紹一些重要的規律:大量數據比少量數據好;好的特徵比好的算法那更重要。如果選擇的特徵好,最大化他們的獨立性,最小化他們在不同環境之下的變化,那麼大部分算法都可以獲得比較好的效果。除此之外,還有兩個經常遇到的問題:
欠擬合:模型假設太嚴格,所以模型不能擬合到實際數據上
過擬合:算法不僅學習了數據,而且把噪聲也當做信號學習了,這樣算法的推廣能力很差。

交叉驗證、自抽樣法、ROC曲線和混淆矩陣
介紹一些用來評估機器學習結果的工具。在監督學習中,最基本的問題就是知道算法的性能:分類器準確嗎?測試集或驗證集可能並不能精確地反映數據的實際分佈。爲了更準確的評估分類器性能。我們可以採用交叉驗證(Cross-Validation)的技術或者與之比較相近的自抽樣法(bootstrapping)。
交叉驗證首先把數據分成k個不同的子集。然後用k-1個子集進行訓練,用沒有用來訓練的子集進行測試,這樣做k次,每個子集都有一次機會作爲測試集,然後把結果平均。

自抽樣法跟交叉驗證法類似,但是驗證集是從訓練集中隨機選取的,選擇的點僅用於測試,不在訓練中使用。這樣做N次,每次隨機選擇一些驗證集,最後把得到的結果平均。這意味着一些數據樣本會出現在不同的驗證集中,自抽樣法的效果一般勝於交叉驗證。
opencv2中機器學習都是基於統計學的機器學習算法,在ML庫中,ML庫中的所有程序都是用C++寫的,他們都繼承於StatModel類。
opencv源碼中有如下定義:

typedef CvStatModel StatModel;

CvStatModel 類包含了所有算法都需要的一些函數。CvStatModel 有兩套方法來對磁盤進行模型的讀寫操作:保存操作的save和write,讀操作的load和read。對於機器學習的模型,應該使用簡單的save和load。他們實際上是把複雜的write和read函數進行了封裝,能夠從硬盤讀寫xml和yaml格式的文件。

class CV_EXPORTS_W CvStatModel
{
public:
    CvStatModel();
    virtual ~CvStatModel();

    virtual void clear();

    CV_WRAP virtual void save( const char* filename, const char* name=0 ) const;
    CV_WRAP virtual void load( const char* filename, const char* name=0 );

    virtual void write( CvFileStorage* storage, const char* name ) const;
    virtual void read( CvFileStorage* storage, CvFileNode* node );

protected:
    const char* default_model_name;
};

load()首先需要調用clear()函數,然後通過此函數裝載xml或YAML格式的模型。還有比較重要的函數就是 train和predict方法。

機器學習的train()方法根據具體的算法呈現不同的形式,所有的算法都已一個指向CvMat矩陣的指針作爲訓練數據。矩陣必須是32FC1的類型。CvMat結構可以支持多通道矩陣,但是機器學習只採用單通道矩陣。一般情況下,這個矩陣以行排列數據樣本,每個數據樣本被表示爲一個行向量。矩陣的每一列,表示某個變量在不同的數據樣本中的不同取值,這樣組成了一個二維的數據矩陣。

float CvStatMode::predict(const CvMat::sample[,<prediction_params>]) const;

這個預測函數。如果是分類問題,他會返回一個類別標籤。如果是迴歸問題,他會返回一個數值標籤。函數後綴const可以知道:預測不影響模型的內部狀態。因此,這個方法可以並行調用。

typedef struct CvTermCriteria
{
 int type;//CV_TERMCRIT_ITER or CV_TERMCRIT_EPS
 int max_iter; // 最大迭代次數
 double epsilon; //當誤差低於這個值的時候就會停止迭代
}

首先講解Mahalanobis距離矩陣,然後介紹無監督算法K均值。這兩個算法在cxcore庫中。

  • Mahalanobis距離是數據所在的空間的協方差的度量。
    Mahalanobis即是馬氏距離。
    對於兩個不同特徵的度量,往往需要將通過數據的協方差歸一化空間,才能進行融合比較。比如:如果我們以米爲單位來測量人的身高,以天爲單位測量人的年齡,我們看到身高的範圍很小,而年齡的範圍很大。通過方差歸一化,變量之間的關係便會更加符合實際情況。K近鄰之類的算法很難處理方差相差很大的數據,但是決策樹則不受這種情況影響。
    我們首先需要得到協方差矩陣,然後計算其逆矩陣。我們就可以求得兩個向量的Mahalanobis距離。Mahalanobis距離與歐幾里得距離類似,只不過他還需要除以空間的協方差矩陣。Mahalanobis距離是一個數值,如果協方差矩陣是單位矩陣,則 Mahalanobis距離就會退化爲歐幾里得距離。
    (1)馬氏距離定義

    這裏寫圖片描述

    而其中向量Xi與Xj之間的馬氏距離定義爲:
    這裏寫圖片描述
    若協方差矩陣是單位矩陣(各個樣本向量之間獨立同分布),則公式就成了:
    這裏寫圖片描述
    也就是歐氏距離了。
      若協方差矩陣是對角矩陣,公式變成了標準化歐氏距離。
    (2)馬氏距離的優缺點:量綱無關,排除變量之間的相關性的干擾。

OpenCV中使用Mahalanobis函數。

//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix
CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar);

這是函數原型,可以看出,v1和v2是輸入向量,而icovar是協方差矩陣的逆矩陣。而calcCovarMatrix()是用來計算協方差矩陣的,invert()是用來計算逆矩陣的。

K均值是一個比較常用的算法。但是也有一個問題,我們給出該問題的一個解決辦法:
K均值假設空間的協方差矩陣不會影響結果,或者已經歸一化。所以我們首先(如果需要)對結果進行協方差歸一化。
K均值不保證能找到定位聚類中心的最佳方案,但是他能保證能收斂到某個解決方案。
所以我們可以在K均值中,每個聚類中心擁有他的數據點,我們計算這些點的方差,最好的聚類在不引起太大的複雜度的情況下使方差達到最小。我們就可以多運行幾次K均值,每次初始的聚類中心點都不一樣。然後選擇方差最小的那個結果。

如何對數據協方差歸一化:
我們可以將每個數據乘以協方差的逆矩陣就能夠實現歸一化。

OpenCV2中使用kmeans函數計算聚類中心。

//! clusters the input data using k-Means algorithm
CV_EXPORTS_W double kmeans( InputArray data, int K, CV_OUT InputOutputArray bestLabels,
 TermCriteria criteria, int attempts,
 int flags, OutputArray centers=noArray() );
發佈了83 篇原創文章 · 獲贊 12 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章