Regressione lineare con funzione di costo non simmetrica?


13

Voglio prevedere un valore e sto cercando di ottenere una previsione che ottimizzi tra l'essere il più basso possibile, ma che sia comunque maggiore di . In altre parole: Y ( x ) Y ( x ) costo { Y ( x ) Y ( x ) } > > costo { Y ( x ) Y ( x ) }Y(X)Y^(X)Y(X)

costo{Y(X)Y^(X)}>>costo{Y^(X)Y(X)}

Penso che una semplice regressione lineare dovrebbe fare del tutto bene. Quindi so in qualche modo come implementarlo manualmente, ma credo di non essere il primo con questo tipo di problema. Ci sono pacchetti / librerie (preferibilmente python) là fuori che fanno quello che voglio fare? Qual è la parola chiave che devo cercare?

E se conoscessi una funzione Y0(X)>0 dove Y(X)>Y0(X) . Qual è il modo migliore per attuare queste restrizioni?


Probabilmente, la soluzione più semplice è utilizzare pesi diversi, in base al fatto che la previsione sia positiva o negativa. Avrei dovuto pensarci prima.
asPlankBridge

Risposte:


11

Se ti capisco correttamente, vuoi sbagliare dal punto di vista della sopravvalutazione. In tal caso, è necessaria una funzione di costo asimmetrica appropriata. Un semplice candidato è quello di modificare la perdita quadrata:

L:(X,α)X2(SgnX+α)2

dove è un parametro che è possibile utilizzare per compensare la penalità di sottovalutazione e sovrastima. I valori positivi di penalizzano la sovrastima, quindi vorrai impostare negativo. In Python sembra-1<α<1ααdef loss(x, a): return x**2 * (numpy.sign(x) + a)**2

Funzioni di perdita per due valori di a

Quindi generiamo alcuni dati:

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

Funzione arbitraria

Infine, faremo la nostra regressione in tensorflowuna libreria di apprendimento automatico di Google che supporta la differenziazione automatizzata (semplificando l'ottimizzazione basata su gradiente di tali problemi). Userò questo esempio come punto di partenza.

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è l'errore quadratico regolare, mentre acostè la funzione di perdita asimmetrica sopra menzionata.

Se lo usi costottieni

1.00764 -3.32445

costo

Se lo usi acostottieni

1.02604 -1.07742

un costo

acostcerca chiaramente di non sottovalutare. Non ho verificato la convergenza, ma hai avuto l'idea.


Grazie per questa risposta dettagliata: una domanda alla definizione della acostfunzione però. Importa che calcoli y_model-Ydue volte?
asPlankBridge

Intendi in termini di velocità? Non lo so; dovresti prenderti il ​​tempo per vedere se tensorflow evita il ricalcolo. Va bene altrimenti.
Emre

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.