Туториал по полиномиальной регрессии на TensorFlow
Лучший способ понять полиномиальную регрессию — это вернуться к линейной регрессии. Итак, давайте сначала сделаем несколько случайных дата поинтов.
Случайные точки данных
import numpy as np import matplotlib.pyplot as plt dataNum = 100 # Кол точек x = np.linspace(-3, 3, dataNum) # Делаем случайные точки y = np.sin(x) + np.random.uniform(-0.5, 0.5, dataNum) plt.plot(x,y, 'bo') # Изображаем точки на графике plt.show()
Теперь давайте посмотрим, как будет себя вести линейная регрессия.
Линейная регрессия
import tensorflow as tf X = tf.placeholder("float") Y = tf.placeholder("float") w = tf.Variable(np.random.randn(), name = "w") b = tf.Variable(np.random.randn(), name = "b") learning_rate = 0.01 training_epochs = 300 # y = wx + b (формула нашей линии) y_pred = tf.add(tf.multiply(X, w), b) # MSE loss = tf.reduce_mean(tf.square(y_pred - Y)) # Gradient Descent Optimizer optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) # Инициализируем переменные init = tf.global_variables_initializer() # Тренировка модели with tf.Session() as sess: sess.run(init) for epoch in range(training_epochs): # Передаем каждую точку оптимизатору for (ix, iy) in zip(x, y): sess.run(optimizer, feed_dict = {X : ix, Y : iy}) # Возвращаем натренированные коэффициенты weight = sess.run(w) bias = sess.run(b) # Создаем линию по коэффициентам line = weight * x + bias # Изображаем линию на графике plt.plot(x, y, 'bo', label ='Original data') plt.plot(x, line, 'k', label ='Fitted line') plt.title('Linear Regression') plt.legend() plt.show()
Мы видим, что, поскольку наши данные не линейны, даже наилучшая линия не может правильно заполнить все данные. Эта проблема недостаточно обученной модели также известна как недообучение или underfit. Это в основном означает, что наша модель слишком проста или недостаточно обучена, как в примере выше. Вот откуда приходит идея полиномиальной регрессии. Она позволяет нам построить более сложную линию, такую как квадратичная кривая, кубическая кривая или любая другая кривая. Давайте посмотрим, как полиномиальная регрессия работает с нашими случайными точками данных.
Полиномиальная регрессия
sub_plt = plt.subplot() sub_plt.scatter(x, y, label = 'Original data') plt.draw() X = tf.placeholder("float") Y = tf.placeholder("float") # Тут основная часть полиномиальной регрессии # Вместо того, чтобы использовать линейную формулу: y = wx + b # Мы используем формулу кривой: y = x^n + x^(n-1) + ... + x + b # Где n это степень нашей кривой degree = 3 y_pred = tf.Variable(tf.random_normal([1]), name='bias') for powi in range(1, degree + 1): W = tf.Variable(tf.random_normal([1]), name='Wpowi') y_pred = tf.add(tf.multiply(tf.pow(X, powi), W), y_pred) learning_rate = 0.01 training_epochs = 1000 loss = tf.reduce_sum(tf.square(y_pred - Y)) / (dataNum) optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) prevLoss = 0.0 # Тренировка for epoch in range(training_epochs): for (ix, iy) in zip(x, y): sess.run(optimizer, feed_dict={X: ix, Y: iy}) # Подсчет потерь currentLoss = sess.run(loss, feed_dict={X: x, Y: y}) # Когда модель начинает медленно учится - останавливаем # И возвращаем последний результат if np.abs(prevLoss - currentLoss) < 0.0001: sub_plt.plot(x, y_pred.eval(feed_dict={X: x}, session=sess),'k', label = 'Fitted line') print('Loss:', currentLoss) break prevLoss = currentLoss # Строим график sub_plt.set_ylim([-3, 3]) plt.title('Polynomial Regression') plt.legend() plt.show() Loss: 0.09154288
Это гораздо лучше. Теперь мы видим, что полиномиальная регрессия используется, когда наши данные не распределены линейно, поэтому мы строим кривую, которая лучше соответствует данным. Теперь, в примере полиномиальной регрессии, мы остановили нашу модель, когда разница между предыдущими и текущими потерями была очень маленькой. Такой прием используется, чтобы не оверфитится на данные.
Чтобы понять, что такое overfit и underfit, нам нужно немного погрузиться в математику.
Смещение vs Разброс
Смещение (bias) означает, что у нас есть ошибка прогноза, потому что наша модель не может уловить все паттерны в данных. Например, если наши данные выглядят как кубическая кривая, линейная регрессия не сможет уловить все данные, и, следовательно, наши потери будут высокими. Сильное смещение возникает, когда модель недостаточно натренирована (underfit).
Разброс (variance) означает, что у нас есть ошибка прогноза, потому что наша модель перетренирована, поэтому она очень хорошо работает с тренировочными данными, но не так хорошо с тестовыми данными. Когда модель оверфитится, возникает большой разброс.
Заключение
Несколько вещей, которые следует запомнить из этого урока:
- Если вам нужно построить линию регрессии для некоторых случайных данных или данных, которые соответствуют некоторому правилу (экспоненциальному, квадратичному, кубическому ...), вам, возможно, придется использовать полиномиальную регрессию.
- Старайтесь недопускать overfit и underfit. Это сильно повлияет на точность предсказаний. Для этого можно как в примере выше специально останавливать обучение, когда изменения небольшие чтобы избежать перетренеровок.
93 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів