Si te entiendo correctamente, quieres equivocarte por sobreestimar. Si es así, necesita una función de costo asimétrica adecuada. Un candidato simple es ajustar la pérdida al cuadrado:
L :(x,α)→ x2( s g n x + α )2
donde es un parámetro que puede utilizar para compensar la penalización de la subestimación por la sobreestimación. Los valores positivos de α penalizan la sobreestimación, por lo que querrá establecer α negativo. En python esto parece- 1 < α < 1ααdef loss(x, a): return x**2 * (numpy.sign(x) + a)**2
A continuación, generemos algunos datos:
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))
Finalmente, haremos nuestra regresión en tensorflow
una biblioteca de aprendizaje automático de Google que admite la diferenciación automatizada (simplificando la optimización basada en gradiente de tales problemas). Usaré este ejemplo como punto 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
es el error al cuadrado regular, mientras que acost
es la función de pérdida asimétrica mencionada anteriormente.
Si cost
usas obtienes
1.00764 -3.32445
Si acost
usas obtienes
1.02604 -1.07742
acost
claramente trata de no subestimarlo. No verifiqué la convergencia, pero entiendes la idea.