9

Rでは、関数の観測ではなく、特定の変数に重みを設定するにはどうすればよいですか?lm()

コンテクストは以下の通り。携帯電話など、特定の製品の個人ランキング システムを構築しようとしています。従属変数として価格に基づいて線形モデルを構築し、独立変数として画面サイズ、メモリ、OS などの他の機能を構築できます。次に、それを使用して電話の実際のコストを (宣言された価格とは対照的に) 予測し、最適な価格/良さの係数を見つけることができます。これは私がすでに行ったことです。

ここで、私にとってのみ重要ないくつかの機能を「強調」したいと思います。たとえば、大容量のメモリを備えた電話が必要な場合があるため、メモリ変数に対して線形モデルが最適化されるように、より高い重みを付けたいと考えています。

lm()Rの関数にはweightsパラメーターがありますが、これらは変数ではなく観測の重みです(これが間違っている場合は修正してください)。また、式をいじってみましたが、インタープリター エラーしか発生しませんでした。に変数の重みを組み込む方法はありlm()ますか?

もちろん、lm()機能だけが選択肢ではありません。他の同様のソリューション (例: ) でそれを行う方法を知っている場合glm()、これもかなり問題ありません。

アップデート。いくつかのコメントの後、私は問題について考えていた方法が間違っていることを理解しました. への呼び出しによって取得された線形モデルは、lm()トレーニングの例に最適な係数を提供します。変数の重みを変更する方法はありません (必要もありません)。混乱して申し訳ありません。私が実際に探しているのは、既存の線形モデルの係数を変更して、一部のパラメーターを他のパラメーターよりも重要にする方法です。前の例を続けて、次の価格の式があるとします。

price = 300 + 30 * memory + 56 * screen_size + 12 * os_android + 9 * os_win8

この式は、価格と電話パラメータ間の依存関係について可能な限り最良の線形モデルを表しています。ただし、memory変数の前にある番号 30 を手動で 60 に変更したいので、次のようになります。

price = 300 + 60 * memory + 56 * screen_size + 12 * os_android + 9 * os_win8

もちろん、この式は、価格と電話パラメーター間の最適な関係を反映していません。また、従属変数は実際の価格を示すのではなく、メモリが平均的な人よりも 2 倍重要であることを考慮して (最初の式の係数に基づいて)、実際の価格を示しません。しかし、この良さの値 (より正確には、分数の値goodness/price) はまさに私が必要としているものです。

これがすべて理にかなっていることを願っています。ここで、1 つの (おそらく非常に単純な) 質問があります。で取得した既存の線形モデルに手動で係数を設定するにはどうすればよいlm()ですか? つまり、次のようなものを探しています。

coef(model)[2] <- 60

もちろん、このコードは機能しませんが、アイデアは得られるはずです。注:データフレームの列の値を2倍にすることは明らかに可能memoryですが、データではなくモデルに影響を与える、よりエレガントなソリューションを探しています。

4

2 に答える 2

4

次のコードは、残差平方和をlm() 最小化し、固定された非最適係数を使用すると最小化されないため、少し複雑になります。これlm()は、実行しようとしていることに反し、残りのすべての係数も修正することです。

そのためには、まず無制限モデルの係数を知る必要があります。すべての調整は、モデルの式を変更することによって行う必要があります。たとえば、私たちが持っているよう price ~ memory + screen_sizeに、もちろん、隠れた切片があります。現在、データを直接変更したり、使用したりすることI(c*memory)はお勧めできません。データの一時的な変更にも似ていますが、変数を変換して1つのI(c*memory)係数のみを変更することは、はるかに困難です。

したがって、最初にに変更price ~ memory + screen_sizeprice ~ offset(c1*memory) + offset(c2*screen_size)ます。ただし、切片は変更していません。これにより、残差平方和が最小化され、元のモデルとは異なる可能性があります。最後のステップは、切片を削除し、新しい偽の変数を追加することです。つまり、他の変数と同じ数の観測値を持ちます。

price ~ offset(c1*memory) + offset(c2*screen_size) + rep(c0, length(memory)) - 1

# Function to fix coefficients
setCoeffs <- function(frml, weights, len){
  el <- paste0("offset(", weights[-1], "*", 
               unlist(strsplit(as.character(frml)[-(1:2)], " +\\+ +")), ")")
  el <- c(paste0("offset(rep(", weights[1], ",", len, "))"), el)                                 
  as.formula(paste(as.character(frml)[2], "~", 
                   paste(el, collapse = " + "), " + -1"))
}
# Example data
df <- data.frame(x1 = rnorm(10), x2 = rnorm(10, sd = 5), 
                 y = rnorm(10, mean = 3, sd = 10))
# Writing formula explicitly 
frml <- y ~ x1 + x2
# Basic model
mod <- lm(frml, data = df)
# Prime coefficients and any modifications. Note that "weights" contains 
# intercept value too
weights <- mod$coef
# Setting coefficient of x1. All the rest remain the same
weights[2] <- 3
# Final model
mod2 <- update(mod, setCoeffs(frml, weights, nrow(df)))
# It is fine that mod2 returns "No coefficients"

また、おそらくmod2予測にのみ使用する予定です(実際、他にどこで使用できるかはわかりません)。これにより、次のことを行わずに、より簡単な方法で作成できますsetCoeffs

# Data for forecasting with e.g. price unknown
df2 <- data.frame(x1 = rpois(10, 10), x2 = rpois(5, 5), y = NA)
mat <- model.matrix(frml, model.frame(frml, df2, na.action = NULL))
# Forecasts
rowSums(t(t(mat) * weights))
于 2012-09-07T23:15:34.717 に答える
4

モデルのフィッティングではなく、最適化を行っているようです (ただし、モデルのフィッティング内で最適化が行われる場合があります)。おそらく、optim関数のようなものが必要になるか、線形計画法または二次計画法 (linprogおよびquadprogパッケージ) を調べます。

次のようなモデリング ツールを使用することに固執する場合は、式lmの引数を使用してoffset、計算するのではなく、独自の乗数を指定します。

于 2012-09-07T19:36:49.603 に答える