Я хочу идентифицировать пакет моделирования в R, чтобы определить идеальные веса, которые позволят мне разместить мои точки данных в максимальном сегменте.
По сути, я хочу настроить свой вес таким образом, чтобы достичь своей цели.
Ниже приведен пример.
Score1,Score2,Score3,Final,Group
0.87,0.73,0.41,0.63,"60-100"
0.82,0.73,0.85,0.796,"70-80"
0.82,0.37,0.85,0.652,"60-65"
0.58,0.95,0.42,0.664,"60-65"
1,1,0.9,0.96,"90-100"
Weight1,Weight2,Weight3
0.2,0.4,0.4
Final Score= Score1*Weight1+ Score2*Weight2+Score3*Weight3
Сумма моих весов равна 1. W1 + W2 + W3 = 1
Я хочу настроить свои веса таким образом, чтобы большинство моих кейсов лежало в ведре «90–100». Я знаю, что не будет идеальной комбинации, но хочу охватить максимальное количество случаев. В настоящее время я пытаюсь сделать то же самое в Excel вручную, используя Pivot, но хочу знать, есть ли в R какой-либо пакет, который помогает мне достичь моей цели.
Групповое распределение «70-80» «80-90» - это то, что я сделал в Excel, используя условие if else.
Результат R Pivot:
"60-100",1
"60-65",2
"70-80",1
"90-100",1
Был бы признателен, если бы кто-нибудь мог мне помочь в том же.
Спасибо,





Вот подход, который пытается получить все окончательные оценки как можно ближе к 0,9, используя подход вложенной оптимизации.
Вот ваши исходные данные:
# Original data
df <- read.table(text = "Score1, Score2, Score3
0.87,0.73,0.41
0.82,0.73,0.85
0.82,0.37,0.85
0.58,0.95,0.42
1,1,0.9", header = TRUE, sep = ",")
Это функция стоимости для первого веса.
# Outer cost function
cost_outer <- function(w1){
# Run nested optimisation
res <- optimise(cost_nested, lower = 0, upper = 1 - w1, w1 = w1)
# Spit second weight into a global variable
res_outer <<- res$minimum
# Return the cost function value
res$objective
}
Это функция стоимости для второго веса.
# Nested cost function
cost_nested <- function(w2, w1){
# Calculate final weight
w <- c(w1, w2, 1 - w2 -w1)
# Distance from desired interval
res <- 0.9 - rowSums(w*df)
# Zero if negative distance, square distance otherwise
res <- sum(ifelse(res < 0, 0, res^2))
}
Далее запускаю оптимизацию.
# Repackage weights
weight <- c(optimise(cost_outer, lower = 0, upper = 1)$minimum, res_outer)
weight <- c(weight, 1 - sum(weight))
Наконец, я показываю результаты.
# Final scores
cbind(df, Final = rowSums(weight * df))
# Score1 Score2 Score3 Final
# 1 0.87 0.73 0.41 0.7615286
# 2 0.82 0.73 0.85 0.8229626
# 3 0.82 0.37 0.85 0.8267400
# 4 0.58 0.95 0.42 0.8666164
# 5 1.00 1.00 0.90 0.9225343
Обратите внимание, однако, что этот код получает окончательные оценки как можно ближе для интервала, что отличается от получения оценок наиболее в этом интервале. Этого можно добиться, отключив вложенную функцию стоимости с помощью чего-то вроде:
# Nested cost function
cost_nested <- function(w2, w1){
# Calculate final weight
w <- c(w1, w2, 1 - w2 -w1)
# Number of instances in desired interval
res <- sum(rowSums(w*df) < 0.9)
}
Я проверил вес ... он составляет 0,33 для W1, W2 и W3 ... не может ли он варьироваться таким образом, чтобы дать максимальный балл, кроме 0,33 для каждого веса. На самом деле это было бы похоже на линейную алгебру, где мы говорим, что максимальное значение для ax + by + cz = 1 будет, когда x = y = z = 1/3 ..
@Jay Я не знаю, какие веса вы имеете в виду, но когда я запускаю его, я получаю 9.999339e-01 2.525061e-05 4.085635e-05 для второго случая и 2.253008e-01 4.217429e-05 7.746570e-01 для первого случая. В последнем случае я думаю, что нет решения (для данного набора данных), которое могло бы поместить более одной записи в выбранный диапазон.
Это можно сформулировать как проблему смешанного целочисленного программирования (MIP). Математическая модель может выглядеть так:
Двоичная переменная δi указывает, находится ли окончательный вес Fi внутри интервала [0.9,1]. M - «большое» значение (если все ваши данные находятся в диапазоне от 0 до 1, мы можем выбрать M=1). ai,j - это ваши данные.
Целевая функция и все ограничения линейны, поэтому мы можем использовать стандартные решатели MIP для решения этой проблемы. Решатели MIP для R.
PS в примере группы перекрываются. Для меня это не имеет особого смысла. Я думаю, что если у нас есть «90–100», то не должно быть и «60–100».
PS2. Если все данные находятся в диапазоне от 0 до 1, мы можем немного упростить уравнение сэндвича: мы можем отбросить правую часть.
Для небольшого примера набора данных я получаю:
---- 56 PARAMETER a
j1 j2 j3
i1 0.870 0.730 0.410
i2 0.820 0.730 0.850
i3 0.820 0.370 0.850
i4 0.580 0.950 0.420
i5 1.000 1.000 0.900
---- 56 VARIABLE w.L weights
j1 0.135, j2 0.865
---- 56 VARIABLE f.L final scores
i1 0.749, i2 0.742, i3 0.431, i4 0.900, i5 1.000
---- 56 VARIABLE delta.L selected
i4 1.000, i5 1.000
---- 56 VARIABLE z.L = 2.000 objective
(нули не печатаются)
Спасибо Lyngbakr .. Можете ли вы также помочь мне узнать, как извлечь значения для W1, W2 и W3? W1, W2 и W3 - это постоянные значения, которые применяются ко всему значению. под константой я подразумеваю фиксированные числа, а не динамическое число (изменение точки данных на точку данных).