Линейная регрессия с несимметричной функцией стоимости?

13

Я хочу предсказать некоторое значение и я пытаюсь получить некоторое предсказание которое оптимизирует между минимально возможным, но все же большим, чем . Другими словами: У ( х ) У ( х ) стоимость { Y ( х ) Y ( х ) } > > Стоимость { Y ( х ) Y ( х ) }Y(Икс)Y^(Икс)Y(Икс)

Стоимость{Y(Икс)Y^(Икс)}>>Стоимость{Y^(Икс)Y(Икс)}

Я думаю, что простая линейная регрессия должна работать совершенно нормально. Так что я немного знаю, как реализовать это вручную, но, думаю, я не первый, кто сталкивается с такой проблемой. Есть ли какие-нибудь пакеты / библиотеки (предпочтительно python), которые делают то, что я хочу? Какое ключевое слово мне нужно искать?

Что если бы я знал функцию Y0(Икс)>0 где Y(Икс)>Y0(Икс) . Каков наилучший способ реализации этих ограничений?

asPlankBridge
источник
Вероятно, наиболее простым решением является использование различных весовых коэффициентов в зависимости от того, является ли прогноз положительным или отрицательным. Я должен был подумать об этом раньше.
asPlankBridge

Ответы:

11

Если я вас правильно понимаю, вы хотите ошибиться в сторону переоценки. Если это так, вам нужна соответствующая асимметричная функция стоимости. Одним простым кандидатом является настройка квадрата потерь:

L:(Икс,α)Икс2(sграммNИкс+α)2

где - это параметр, который вы можете использовать, чтобы компенсировать штраф недооценки и переоценки. Положительные значения приводят к переоценке, поэтому вы должны установить отрицательным. В питоне это выглядит так-1<α<1ααdef loss(x, a): return x**2 * (numpy.sign(x) + a)**2

Функции потерь для двух значений

Далее давайте сгенерируем некоторые данные:

import numpy
x = numpy.arange(-10, 10, 0.1)
y = -0.1*x**2 + x + numpy.sin(x) + 0.1*numpy.random.randn(len(x))

Произвольная функция

Наконец, мы сделаем нашу регрессию в tensorflowбиблиотеке машинного обучения от Google, которая поддерживает автоматическое дифференцирование (упрощая оптимизацию таких задач на основе градиента). Я буду использовать этот пример в качестве отправной точки.

import tensorflow as tf

X = tf.placeholder("float") # create symbolic variables
Y = tf.placeholder("float") 

w = tf.Variable(0.0, name="coeff")
b = tf.Variable(0.0, name="offset")
y_model = tf.mul(X, w) + b

cost = tf.pow(y_model-Y, 2) # use sqr error for cost function
def acost(a): return tf.pow(y_model-Y, 2) * tf.pow(tf.sign(y_model-Y) + a, 2)

train_op = tf.train.AdamOptimizer().minimize(cost)
train_op2 = tf.train.AdamOptimizer().minimize(acost(-0.5))

sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)

for i in range(100):
    for (xi, yi) in zip(x, y): 
#         sess.run(train_op, feed_dict={X: xi, Y: yi})
        sess.run(train_op2, feed_dict={X: xi, Y: yi})

print(sess.run(w), sess.run(b))

costявляется обычной квадратической ошибкой, в то время acostкак вышеупомянутая асимметричная функция потерь.

Если вы используете, costвы получаете

1.00764 -3.32445

Стоимость

Если вы используете, acostвы получаете

1.02604 -1.07742

acost

acostявно старается не недооценивать. Я не проверял на конвергенцию, но вы поняли идею.

Эмре
источник
Спасибо за этот подробный ответ: один вопрос к определению acostфункции. Имеет ли значение, что вы рассчитываете y_model-Yдважды?
asPlankBridge
Вы имеете в виду скорость? Я не знаю; вам придется рассчитать время самостоятельно, чтобы убедиться, что тензорный поток избегает пересчета. В противном случае это нормально.
Эмре
0

Выберите асимметричную функцию потерь. Одним из вариантов является квантильная регрессия (линейная, но с разными наклонами для положительных и отрицательных ошибок).

Брайан Спиринг
источник