Fonction Involute
Veuillez consulter la section d'introduction pour plus de détails. Diverses méthodes pour créer numériquement la fonction inverse d'une certaine fonction Introduction --Qiita
La première méthode que j'ai proposée était une approximation polymorphe. La fonction inverse que je veux trouver est une fonction à croissance monotone, et j'ai pensé que même un polypole pouvait être approché avec une précision raisonnable. Autrement dit, la fonction inverse $ y = a_0 + a_1x + a_2x^{2} + ...$ En l'exprimant ainsi, c'est une idée qu'une valeur proche peut être obtenue.
Le problème est de savoir comment déterminer les coefficients polynomiaux $ a_0, a_1, a_2, ... $. Les coefficients doivent être déterminés de manière à minimiser la différence entre la valeur $ y $ obtenue par le polypole et la valeur vraie. Bien que scikit-learn soit une bibliothèque pour l'apprentissage automatique, j'ai trouvé qu'elle peut être utilisée pour déterminer automatiquement les coefficients des polynômes.
Générez des données d'entraînement pour l'entraînement à l'aide de la fonction Involute.
Notebook
def involute(α):
return np.tan(α) - α
Notebook
y = np.linspace(- np.pi / 4, np.pi / 4, 1000)
x = involute(y)
Selon la convention d'apprentissage automatique, l'entrée ($ inv \ alpha $) est $ x $ et la sortie ($ \ alpha $) est $ y $. Préparez d'abord la valeur de $ y $ ($ \ alpha $), trouvez la valeur de $ x $ ($ inv \ alpha $) à l'aide de la fonction incorporer et utilisez-la comme données d'apprentissage.
Vous pouvez facilement ajuster des polynômes avec scikit-learn.
Tout d'abord, importez les bibliothèques requises.
Notebook
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline
Les données d'apprentissage générées ci-dessus sont un tableau unidimensionnel, mais dans scikit-learn, les données sont essentiellement un vecteur de colonne, elles sont donc converties en vecteur de colonne.
Notebook
x_column = x.reshape(-1, 1)
y_column = y.reshape(-1, 1)
Tout d'abord, ajustons un polypole d'ordre 10.
Notebook
model_poly = make_pipeline(PolynomialFeatures(degree=10), LinearRegression())
model_poly.fit(x_column, y_column)
model_poly.score(x_column, y_column)
output
0.95581676585298314
PolynomialFeatures (degree = 10)
est la conversion en un polymorphe d'ordre 10, LinearRegression ()
est la génération d'un modèle de régression linéaire, et ils sont combinés avec la fonction make_pipeline pour créer un modèle de régression polynomiale.
Les données d'apprentissage sont données à la méthode d'ajustement du modèle créé pour s'adapter au polypole.
La méthode du score évalue numériquement le degré de précision de l'estimation. Si cette valeur est de 1,0, cela signifie qu'elle peut être parfaitement estimée.
Tracons maintenant les valeurs estimées par le modèle de régression polypoly.
Notebook
y_pred = model_poly.predict(x_column).flatten()
fig = figure(width=400, height=400)
fig.scatter(x, np.degrees(y), size=1, legend='vraie valeur')
fig.line(x, np.degrees(y_pred), line_color='orange', legend='Valeur estimée')
fig.xaxis.axis_label = 'invα'
fig.yaxis.axis_label = 'Angle de pression α(deg)'
fig.legend.location = 'top_left'
show(fig)
La valeur d'entrée est donnée à la méthode de prédiction pour obtenir la valeur estimée. Le graphique ci-dessus est le résultat du tracé des estimations obtenues. La précision de l'estimation est trop mauvaise.
Que diriez-vous d'augmenter la commande à 20?
Notebook
model_poly = make_pipeline(PolynomialFeatures(degree=20), LinearRegression())
model_poly.fit(x_column, y_column)
model_poly.score(x_column, y_column)
output
0.97492606041826035
Notebook
y_pred = model_poly.predict(x_column).flatten()
fig = figure(width=400, height=400)
fig.scatter(x, np.degrees(y), size=1, legend='vraie valeur')
fig.line(x, np.degrees(y_pred), line_color='orange', legend='Valeur estimée')
fig.xaxis.axis_label = 'invα'
fig.yaxis.axis_label = 'Angle de pression α(deg)'
fig.legend.location = 'top_left'
show(fig)
Même si elle est augmentée au 20e ordre, la vague de fluctuation n'est que faible et il n'y a pas beaucoup d'amélioration. Il est peu probable qu'il soit préférable d'augmenter la commande telle quelle.
Je pense que le grand gradient près de l'origine est la raison pour laquelle il ne peut pas être bien estimé par régression polypoly. La fonction inverse inverse a un dégradé infini à l'origine, mais tant que vous utilisez un polypole, vous ne pouvez jamais exprimer un dégradé infini.
Le bloc-notes utilisé pour l'explication est téléchargé sur Gist. Involute inverse function estimation_polypoly regression.ipynb
Recommended Posts