Régression linéaire avec fonction de coût non symétrique?

13

Je veux prédire une valeur et j'essaie d'obtenir une prédiction qui optimise entre être aussi bas que possible, mais toujours plus grand que . En d'autres termes: Y ( x ) Y ( x ) coût { Y ( x ) Y ( x ) } > > coût { Y ( x ) Y ( x ) }Oui(X)Oui^(X)Oui(X)

Coût{Oui(X)Oui^(X)}>>Coût{Oui^(X)Oui(X)}

Je pense qu'une simple régression linéaire devrait faire l'affaire. Je sais donc comment l'implémenter manuellement, mais je suppose que je ne suis pas le premier à avoir ce genre de problème. Existe-t-il des packages / bibliothèques (de préférence python) faisant ce que je veux faire? Quel est le mot-clé que je dois rechercher?

Et si je connaissais une fonction où Y (x)> Y_0 (x) . Quelle est la meilleure façon de mettre en œuvre ces restrictions?Y ( x ) > Y 0 ( x )Oui0(X)>0Oui(X)>Oui0(X)

asPlankBridge
la source
Probablement, la solution la plus simple consiste à utiliser des poids différents, selon que la prédiction est positive ou négative. J'aurais dû y penser plus tôt.
asPlankBridge

Réponses:

11

Si je vous comprends bien, vous voulez pécher par excès de valeur. Si tel est le cas, vous avez besoin d'une fonction de coût asymétrique appropriée. Un candidat simple consiste à modifier la perte au carré:

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

où est un paramètre que vous pouvez utiliser pour échanger la pénalité de la sous-estimation contre la surestimation. Les valeurs positives de pénalisent la surestimation, vous voudrez donc définir négatif. En python, cela ressemble à-1<α<1ααdef loss(x, a): return x**2 * (numpy.sign(x) + a)**2

Fonctions de perte pour deux valeurs de a

Générons ensuite des données:

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

Fonction arbitraire

Enfin, nous ferons notre régression dans tensorflow, une bibliothèque d'apprentissage automatique de Google qui prend en charge la différenciation automatisée (ce qui simplifie l'optimisation basée sur le gradient de ces problèmes). Je vais utiliser cet exemple comme point de départ.

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

costest l'erreur quadratique régulière, tandis que acostla fonction de perte asymétrique susmentionnée.

Si vous utilisez, costvous obtenez

1,00764 -3,32445

Coût

Si vous utilisez, acostvous obtenez

1.02604 -1.07742

un coût

acostessaie clairement de ne pas sous-estimer. Je n'ai pas vérifié la convergence, mais vous avez compris.

Emre
la source
Merci pour cette réponse détaillée: Une question pour la définition de la acostfonction cependant. Est-il important que vous calculiez y_model-Ydeux fois?
asPlankBridge
Vous voulez dire en termes de vitesse? Je ne sais pas; vous devrez le chronométrer vous-même pour voir si tensorflow évite le recalcul. C'est bien autrement.
Emre
0

Choisissez une fonction de perte asymétrique. Une option est la régression quantile (linéaire mais avec des pentes différentes pour les erreurs positives et négatives).

Brian Spiering
la source