2017 年 11 月

第 33 卷,第 11 期

本文章是由機器翻譯。

測試回合 - 使用 C# 的核心羅吉斯迴歸

James McCaffrey

James McCaffrey

核心羅吉斯迴歸 (KLR) 是能夠用於進行二進位預測的機器學習服務技術。例如,KLR 無法預測是否人員將 repay 貸款 (無法 repay = 0,成功 repay = 1) 根據預測變數,例如年齡、 收入和現有負債量。KLR 是進階的一種一般的羅吉斯迴歸。

若要查看示範程式中是好的方法,請參閱這篇文章會向其中圖 1及相關的資料在圖 2。示範程式的目標是要預測的類別、 0 或 1 的兩個預測量變數 (有時稱為功能),x0 虛設資料和 x1。例如,第一個的定型資料項目是 (2.0、 3.0、 0),這表示,如果預測量值是 x0 = 2.0 和 x1 = 3.0,正確的類別為 0。KLR 可以處理任意數目的預測量變數的資料,但使用兩個只可讓您輕鬆地以視覺化方式檢視技術。

定型資料點 21 有循環的幾何,這表示簡單的線性分類技術,例如一般羅吉斯迴歸,並沒有效果。這類資料稱為非以線性方式分隔。

在幕後 KLR 會使用稱為星形基礎函式 (RBF) 核心的函式。RBF 核心函式有參數,呼叫標準差。標準差的值必須由試驗,和標準差設為 1.0,此示範中。定型 KLR 模型是反覆的程序,並示範的反覆運算次數上限為 1000,並學習速率,知道,設 0.001。

定型 KLR 模型建立一組 < alpha 值 > 其中每個訓練資料項目,加上額外的"偏差 」 值。示範程式會顯示前三個定型項目 (-0.3071、-0.3043、-0.3071) 和最後兩個的 alpha 值項目 (0.8999、 0.6108) 和偏差 (-1.0722)。

定型之後, KLR 模型正確預測 21 資料的所有項目。模型會套用至四個測試資料項目,顯示為黑色點圖 2。第一個測試項目具有輸入 (1.5,4.5) 和正確的類別為 0。預測模型正確預測的項目和其他三個測試項目太。

本文假設您有中繼或更高版本程式設計技巧,但不會假設您知道 KLR。使用 C# 程式碼示範程式,但如果您想應該必須重構程式碼以另一種語言,例如 Java 或 Python 沒有問題。示範程式太長而無法完整顯示,但完整的原始程式碼檔案下載本文章中。

RBF 核心

核心函式會測量兩個陣列或向量的相似度。先前所述的 RBF 核心功能是最常見的並為示範程式所用的類型。1.0 表示兩個向量的 RBF 值完全相同。較小的 RBF 值指出兩個向量比較不類似。

RBF 的方程式是:

K (v1、 v2) = exp (-| | v1-v2 | |^2 / (2 * sigma ^2))

在這裡,K 代表核心。v1 和 v2 是兩個向量的長度必須相同。標準差是類似 1.0 或 1.5; 值參數| |表示歐幾里得距離。exp 函式,且 [歐拉數 (e = 2.71828) 乘冪。

RBF 函式最適合的範例所說明。假設 v1 = (3.0,1.0,2.0) 和 v2 = (1.0,0.0,5.0),和標準差為 1.5。首先,您要計算平方歐幾里德距離:

||v1-v2 | |^2 = (3.0 1.0) ^2 + (1.0-0.0) ^2 + (2.0 5.0) ^2

                      = 4.0 + 1.0 + 9.0

                      = 14.0

接下來,您除以平方的距離平方的 2 倍 sigma:

14.0 / (2 * (1.5)^2) = 14.0 / 4.5 = 3.11

最後,您會採用歐拉數,並提高至上述結果中的負數:

K (v1、 v2) = e^(-3.11) = 0.0446

小型的核心值會指出 v1 和 v2 不太相似。示範程式定義 RBF 核心函式:

static double Kernel(double[] v1, double[] v2,
  double sigma)
{
  double num = 0.0;
  for (int i = 0; i < v1.Length - 1; ++i)
    num += (v1[i] - v2[i]) * (v1[i] - v2[i]);
  double denom = 2.0 * sigma * sigma;
  double z = num / denom;
  return Math.Exp(-z);
}

函式會假設每個陣列之最後資料格包含類別標籤 (0 或 1),因此最後一個資料格不納入計算。KLR 比較所有定型項目,具有給定的資料項目會使用核心函式,並使用該資訊來判斷預測的類別標籤。

一般的羅吉斯迴歸

一般的羅吉斯迴歸 (LR) 最適合的範例所說明。假設您有三個預測量變數: x0 = 2.5,x1 = 1.7 和 x2 = 3.4。規則的 LR 模型會建立一組稱為加權 (wi-fi),一個適用於每個預測量變數,而其他的數值常數,稱為偏差 (b) 的數值常數。請注意,在一般 LR 偏差不 KLR 偏差所示相同圖 1。 

核心羅吉斯迴歸示範

圖 1 核心羅吉斯迴歸示範

假設 w0 = 0.11、 w1 = 0.33,w2 = 0.22,b = 每天 0.44。要預測的類別標籤中,0 或 1,2.5、 1.7 (3.4) 的輸入資料您先計算每個 x 和其相關聯的 + w、 產品的總和並新增偏差:

z = (2.5)(0.11) + (1.7)(0.33) + (3.4)(0.22) + 每天 0.44

   = 2.024

接下來,您可以計算 p = 1.0 / (1.0 + exp(-z)):

p = 1.0 / (1.0 + exp(-2.024))

   = 0.8833

P 值是資料的項目有類別標籤的機率 = 1,因此,如果 p 小於 0.5,您預測為 0,而且如果 p 大於 0.5 (因為它是在此範例中),您預測為 1。

[確定],但其中沒有加權和偏差值來自一般 LR 中?這個概念是,您會使用定型資料的輸入的值和已知的正確類別標籤有已知的一組決定的加權和偏差值,然後使用最佳化演算法來尋找值的加權和徵才偏差,以便預測的類別標籤密切比對的已知的正確的標籤值。有許多可以用來尋找加權的演算法,和一般 LR,包括漸層停駐 (堆疊) 與記錄檔的可能性,以平方誤差,梯度下降的偏差值重複 Newton Raphson、 單工最佳化、 L-BFGS 和物件的群集最佳化。

一般 LR 的主要缺點是它可以處理是以線性方式分隔的資料。一般 LR 無法處理不是以線性方式分隔,例如所示的示範資料的資料圖 2

核心羅吉斯迴歸定型資料

圖 2 核心羅吉斯迴歸定型資料

了解核心羅吉斯迴歸

KLR 最佳範例所說明。讓我事先,第一眼看起來 KLR 不會出現一般 LR 非常密切相關的狀態。不過,兩個技巧密切以數學方式相關。

假設有只需四個定型資料的項目:

td [0] = (2.0、 4.0,0)

td [1] = 4.0、 1.0 (1)

td [2] = 5.0、 3.0 (0)

td [3] = 6.0、 7.0 (1)

您的目標是要預測 x = (3.0,5.0) 的類別標籤。假設定型的 KLR 模型提供給您的 alpha 值和的偏差值: alpha [0] =-0.3,alpha [1] = 0.4、 alpha [2] =-0.2,[3] 的 alpha = 0.6,b = 0.1。

第一個步驟是用來計算 RBF 之間的相似度資料項目來預測每個訓練項目:

K (td [0],x) = 0.3679

K (td [1],x) = 0.0002

K (td [2],x) = 0.0183

K (td [3],x) = 0.0015

請注意,此時,x 最類似 td [0] 並 td [2],而這兩者會有類別標籤 0。接下來,您可以計算總和的每個值,K 和相關聯的 alpha、 產品及新增的偏差值:

z = (0.3679)(-0.3) + (0.0002)(0.4) + (0.0183)(-0.2) + (0.0015)(0.6) + 0.1

   = -0.1120

現在您計算 p = 1.0 / (1.0 + exp(-z)):

p = 1.0 / (1.0 + exp(0.1120))

   = 0.4720

如果 p 值大於 0.5,預測的類別為 1,而且如果 p 值小於 0.5,預測的類別為 0,因為它是 (勉強) 此範例中。

KLR 模型定型

定型 KLR 模型是使用定型資料來尋找 alpha 值和偏差值的程序。表示在最高層級的虛擬程式碼,是 KLR 定型演算法:

compute K(td[i], td[j]) for all i, j
loop maxIter times
  for-each curr training item, i
    for-each j: sum += alphas[j] * K(i j)
    sum += bias
    y = 1.0 / (1.0 + exp(-sum))
    t = target class (0 or 1)
    for-each j:
      alpha[j] += eta * (t - y) * K(i, j)
    bias += eta * (t - y) * 1.0
end-loop

示範程式碼中的索引鍵陳述式是 alpha [j] + = 知道 * (t-y) * kernelMatrix [i] [j],更新的 alpha 值的索引 [j] 的定型資料項目會根據目前的定型資料項目索引 [i]。在這裡,t 是已知的正確的目標類別,0 或 1,而 y 是計算的機率所處的項目 [i] 具有類別 1。

例如,假設 alpha 值的定型項目目前是 0.1234 和目標類別是 1,計算的機率是 0.60。目前的預測是正確的但您想要更接近 1 的 p 值。假設兩個項目之間的相似度是 K (i,j) = 0.70 和學習速率知道是 0.10。新的 alpha 值會是:

alpha = 0.1234 + 0.10 * (1-0.60) * 0.70

          = 0.1234 + 0.0280

          = 0.1514

Alpha 是乘數中值的機率計算,因為新、 較大的 alpha 值將會增加 p 有點,做出更精確的預測。

示範程式

程式碼示範程式,我啟動 Visual Studio 建立新 C# 主控台應用程式並將它命名為 KernelLogistic。我使用 Visual Studio 2015,但示範程式沒有顯著的.NET Framework 相依性,好讓任何最新版本的 Visual Studio 能夠。

範本程式碼載入到編輯器視窗之後,我以滑鼠右鍵按一下方案總管] 視窗中的 Program.cs 檔案中,重新命名檔案 KernelLogisticProgram.cs,因此則允許 Visual Studio 會自動為我重新命名類別的程式。在範本產生的程式碼頂端,刪除所有不必要使用陳述式離開只有一個參考最上層系統命名空間。然後我具現化 Random 物件:

using System;
namespace KernelLogistic
{
  class KernelLogisticProgram
  {
    static Random rnd = new Random(0);
    static void Main(string[] args)
    {
      Console.WriteLine(“Begin KLR demo”);
      int numFeatures = 2;
...

為了簡單起見,我自動程式碼示範使用靜態方法的方式,而非物件導向程式設計,並移除所有一般錯誤檢查。Main 方法會設定 21 定型項目和 4 的測試項目,就像這樣:

double[][] trainData = new double[21][];
trainData[0] = new double[] { 2.0, 3.0, 0 };
...
trainData[20] = new double[] { 5.0, 6.0, 1 };
double[][] testData = new double[4][];
testData[0] = new double[] { 1.5, 4.5, 0 };
...
testData[3] = new double[] { 5.5, 5.5, 1 };

在非示範案例中,您可能會從文字檔讀取資料。接下來,會初始化 alpha 值:

int numTrain = trainData.Length;
int numTest = testData.Length;
double[] alphas = new double[numTrain + 1];
for (int i = 0; i < alphas.Length; ++i)
  alphas[i] = 0.0;

當編碼機器學習系統時,通常會幾種方式可以處理的偏差值。在這裡,我儲存 KLR 偏差 alpha 陣列的最後一個儲存格。替代的設計是要建立個別的獨立變數。接下來,會計算核心之間的相似性定型項目的所有組合:

double[][] kernelMatrix = new double[numTrain][];
for (int i = 0; i < kernelMatrix.Length; ++i)
  kernelMatrix[i] = new double[numTrain];
double sigma = 1.0;
for (int i = 0; i < numTrain; ++i) {
  for (int j = 0; j < numTrain; ++j) {
    double k = Kernel(trainData[i], trainData[j], sigma);
    kernelMatrix[i][j] = kernelMatrix[j][i] = k;
  }
}

因為僅有 21 資料項目,我會犧牲簡單的效率。我無法了核心計算次數利用降低事實 (v1、 v2) 該 K = K (v2、 v1) 和 K (v,v) = 1。接下來,範例程式會準備用於定型:

double eta = 0.001;
int iter = 0;
int maxIter = 1000;
int[] indices = new int[numTrain];
for (int i = 0; i < indices.Length; ++i)
  indices[i] = i;

知道和 maxIter 的值取決於試驗。名為索引的陣列背後的概念是定型時一定要在每個階段,以避免擷取到的情況下,其中訓練停止或 oscillates 來回瀏覽定型中的項目以隨機順序。主要的訓練迴圈開始:

while (iter < maxIter) {
  Shuffle(indices); 
  for (int idx = 0; idx < indices.Length; ++idx) {
    int i = indices[idx];

隨機播放方法是將金鑰加密所使用的費雪 Yates 迷你演算法定型項目順序的 helper。目標類別標籤和目前的定型項目的預測的可能性會計算就像這樣:

double sum = 0.0;
for (int j = 0; j < alphas.Length-1; ++j)
  sum += alphas[j] * kernelMatrix[i][j];
sum += alphas[alphas.Length - 1]; 
double y = 1.0 / (1.0 + Math.Exp(-sum));
double t = trainData[i][numFeatures];

請注意,這項設計會假設類別標籤是在定型資料陣列的最後一個資料格中。接下來,會更新 alpha 和 beta 值:

for (int j = 0; j < alphas.Length - 1; ++j)
      alphas[j] = alphas[j] +
        (eta * (t - y) * kernelMatrix[i][j]);
    alphas[alphas.Length-1] = alphas[alphas.Length - 1] +
      (eta * (t - y)) * 1; 
  }
  ++iter;
} // While (train)

更新的偏差值只是為了清除的關聯性的對稱性使用 1 來取代核心相似度值、 空值。當然,您可以移除乘法 1,因為它沒有任何作用。之後定型集的一些的 alpha 值和偏差值,會顯示,如下所示圖 1

示範程式結束時,會計算在定型和測試資料上定型的 KLR 模型的分類精確度:

double accTrain = Accuracy(trainData, trainData,
  alphas, sigma, false);
Console.WriteLine(“accuracy = “ +
  accTrain.ToString(“F4”) + “\n”);
double accTest = Accuracy(testData, trainData,
  alphas, sigma, true); // Verbose

布林值的引數傳遞給方法的精確度會指出是否要計算 (與診斷訊息) 的詳細資訊模式或無訊息模式中。

總結

核心羅吉斯迴歸不會使用通常至少在我的同事。它的主要優點是簡單。KLR 的主要缺點是因為您必須預先計算的所有項目項目至核心相似度值並儲存它們,或者您必須讓所有定型資料並計算所有的即時的相似度值不會調整它用於大型資料集每個預測。

KLR 是二元分類的設計。可以擴充以處理具有三個或多個類別的值,但我認為分類問題 KLR、 有更好的替代項目使用,特別單一隱藏的層前饋類神經網路。KLR 有一些相似之處,K 最近鄰近項目 (K NN) 分類演算法,以及支援向量機器 (SVM) 分類。


Dr。James McCaffrey* 適用於 Microsoft Research Redmond,Wash.他已投入許多 Microsoft 產品,包括 Internet Explorer 和 Bing。Dr。在可到達 McCaffrey jamccaff@microsoft.com。*

非常感謝下列 Microsoft 技術專家已檢閱本文章:Chris Lee 和 Adith Swaminathan


MSDN Magazine 論壇中的這篇文章的討論