Regressão linear com função de custo não simétrico?

13

Quero prever algum valor e estou tentando obter alguma previsão que otimize entre ser o mais baixo possível, mas ainda ser maior que . Em outras palavras: Y ( x ) Y ( x ) custo { Y ( x ) Y ( x ) } > > custo { Y ( x ) Y ( x ) }Y(x)Y^(x)Y(x)

custo{Y(x)Y^(x)}>>custo{Y^(x)Y(x)}

Eu acho que uma regressão linear simples deve funcionar totalmente bem. Então, eu sei como implementar isso manualmente, mas acho que não sou o primeiro com esse tipo de problema. Existem pacotes / bibliotecas (de preferência python) por aí fazendo o que eu quero fazer? Qual é a palavra-chave que preciso procurar?

E se eu conhecesse uma função Y0 0(x)>0 0 onde Y(x)>Y0 0(x) . Qual é a melhor maneira de implementar essas restrições?

asPlankBridge
fonte
Provavelmente, a solução mais simples é usar pesos diferentes, com base em se a previsão é positiva ou negativa. Eu deveria ter pensado nisso antes.
asPlankBridge

Respostas:

11

Se eu entendi direito, você quer errar ao superestimar. Nesse caso, você precisa de uma função de custo assimétrica apropriada. Um candidato simples é ajustar a perda ao quadrado:

eu:(x,α)x2(sgnx+α)2

onde é um parâmetro que você pode usar para trocar a penalidade de subestimação contra superestimação. Valores positivos de penalizam a superestimação, portanto, você deseja definir negativo. Em python, isso parece-1<α<1ααdef loss(x, a): return x**2 * (numpy.sign(x) + a)**2

Funções de perda para dois valores de

Em seguida, vamos gerar alguns dados:

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))

Função arbitrária

Por fim, faremos nossa regressão tensorflow, uma biblioteca de aprendizado de máquina do Google que oferece suporte à diferenciação automatizada (simplificando a otimização baseada em gradiente de tais problemas). Vou usar este exemplo como ponto de partida.

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é o erro quadrático regular, enquanto acosté a função de perda assimétrica mencionada acima.

Se você usar, costvocê obtém

1.00764 -3.32445

custo

Se você usar, acostvocê obtém

1.02604 -1.07742

um custo

acostclaramente tenta não subestimar. Não verifiquei a convergência, mas você entendeu.

Emre
fonte
Obrigado por esta resposta detalhada: acostPorém, uma pergunta para a definição da função. Importa que você calcule y_model-Yduas vezes?
asPlankBridge
Você quer dizer em termos de velocidade? Eu não sei; você precisará verificar o tempo para verificar se o fluxo tensor evita o recálculo. Está tudo bem caso contrário.
Emre
0

Escolha uma função de perda assimétrica. Uma opção é a regressão quantílica (linear, mas com diferentes inclinações para erros positivos e negativos).

Brian Spiering
fonte