6

Rで確率的勾配降下法を使用して独自のロジスティック回帰関数を構築しようとしていますが、現在私が持っているものは重みを際限なく増加させるため、停止することはありません:

# Logistic regression
# Takes training example vector, output vector, learn rate scalar, and convergence delta limit scalar
my_logr <- function(training_examples,training_outputs,learn_rate,conv_lim) {
  # Initialize gradient vector
  gradient <- as.vector(rep(0,NCOL(training_examples)))
  # Difference between weights
  del_weights <- as.matrix(1)
  # Weights
  weights <- as.matrix(runif(NCOL(training_examples)))
  weights_old <- as.matrix(rep(0,NCOL(training_examples)))

  # Compute gradient
  while(norm(del_weights) > conv_lim) {

    for (k in 1:NROW(training_examples)) {
      gradient <- gradient + 1/NROW(training_examples)*
        ((t(training_outputs[k]*training_examples[k,]
            /(1+exp(training_outputs[k]*t(weights)%*%as.numeric(training_examples[k,]))))))
    }

    # Update weights
    weights <- weights_old - learn_rate*gradient
    del_weights <- as.matrix(weights_old - weights)
    weights_old <- weights

    print(weights)
  }
    return(weights)
}

関数は、次のコードでテストできます。

data(iris) # Iris data already present in R    
# Dataset for part a (first 50 vs. last 100)
iris_a <- iris
iris_a$Species <- as.integer(iris_a$Species)
# Convert list to binary class
for (i in 1:NROW(iris_a$Species)) {if (iris_a$Species[i] != "1") {iris_a$Species[i] <- -1}}    
random_sample <- sample(1:NROW(iris),50)

weights_a <- my_logr(iris_a[random_sample,1:4],iris_a$Species[random_sample],1,.1)

次のように、 Abu-Mostafa のに対してアルゴリズムを再確認しました。

  1. 重みベクトルの初期化
  2. 時間ステップごとに勾配を計算します。
    gradient <- -1/N * sum_{1 to N} (training_answer_n * training_Vector_n / (1 + exp(training_answer_n * dot(weight,training_vector_n))))
  3. weight_new <- weight - learn_rate*gradient
  4. 重量デルタが十分に小さくなるまで繰り返します

ここで何か不足していますか?

4

2 に答える 2

3

数学的な観点からは、重みベクトルの制約のない大きさでは、一意の解は得られません。この 2 行を分類子関数に追加すると、次の 2 つのステップで収束しました。

# Normalize
weights <- weights/norm(weights)

...

# Update weights
weights <- weights_old - learn_rate*gradient
weights <- weights / norm(weights)

@SimonO101 の作業を行うことができませんでした。また、このコードを実際の作業に使用していないため (glmのようなビルトインがあります)、理解できるループを実行するだけで十分です。全体の機能は次のとおりです。

# Logistic regression
# Takes training example vector, output vector, learn rate scalar, and convergence delta limit scalar
my_logr <- function(training_examples,training_outputs,learn_rate,conv_lim) {
  # Initialize gradient vector
  gradient <- as.vector(rep(0,NCOL(training_examples)))
  # Difference between weights
  del_weights <- as.matrix(1)
  # Weights
  weights <- as.matrix(runif(NCOL(training_examples)))
  weights_old <- as.matrix(rep(0,NCOL(training_examples)))

  # Normalize
  weights <- weights/norm(weights)

  # Compute gradient
  while(norm(del_weights) > conv_lim) {

    for (k in 1:NCOL(training_examples)) {
      gradient <- gradient - 1/NROW(training_examples)*
        ((t(training_outputs[k]*training_examples[k,]
            /(1+exp(training_outputs[k]*t(weights)%*%as.numeric(training_examples[k,]))))))
    }
#     gradient <- -1/NROW(training_examples) * sum(training_outputs * training_examples / (1 + exp(training_outputs * weights%*%training_outputs) ) )

    # Update weights
    weights <- weights_old - learn_rate*gradient
    weights <- weights / norm(weights)
    del_weights <- as.matrix(weights_old - weights)
    weights_old <- weights

    print(weights)
  }
    return(weights)
}
于 2013-03-19T08:22:28.973 に答える
1

いくつかの問題があります。まず、R のベクトル化手法をより有効に活用できます。第二に、私は確率的勾配降下の専門家ではありませんが、質問の下にあるアルゴリズムは、関数で勾配を計算する方法に対応していません。このコードを注意深く確認してください。しかし、収束しているようで、Abu-Mostfafa に従っていると思います。これで勾配を計算したいと思います。

gradient <- -1/N * sum(training_outputs * training_examples / (1 + exp(training_outputs * dot( weights ,training_outputs) ) ) )

したがって、アルゴリズムのこの部分は次のようになります...

while(norm(del_weights) > conv_lim) {  
gradient <- -1 / NROW(iris_a) * sum( training_outputs * training_examples / ( 1 + exp( training_outputs * as.matrix(training_examples) %*% weights ) ) )

# Update weights
weights <- weights_old - learn_rate*gradient
del_weights <- as.matrix(weights_old - weights)
weights_old <- weights
print(weights)

}

以下を使用して、より簡単に Species 変数からバイナリ分類を作成できます。

iris_a$Species <- as.numeric( iris_a$Species )
iris_a$Species[ iris_a$Species != 1 ] <- -1    

返された結果が適切かどうかはわかりませんが、そのコードはステップ 2 に従う必要があります。各ステップを注意深く確認し、R がベクトル化されていることを覚えておいてください。これにより、ループなしでベクトルに対して要素ごとの操作を実行できます。例えば:

x <- 1:5
y <- 1:5
x*y
#[1]  1  4  9 16 25
于 2013-03-18T15:08:25.417 に答える