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( s g n x + α )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
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))
Infine, faremo la nostra regressione in tensorflow
una 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 cost
ottieni
1.00764 -3.32445
Se lo usi acost
ottieni
1.02604 -1.07742
acost
cerca chiaramente di non sottovalutare. Non ho verificato la convergenza, ma hai avuto l'idea.