Несколько функций – часть 1
Резюме
В предыдущей статье мы обсудили процесс создания модели линейной регрессии с одной функцией. Мы вычислили параметры θ₀ и θ₁, которые определяют модель линейной регрессии. Теперь мы переключаем наше внимание на создание модели, основанной на двух функциях, с возможностью расширения, чтобы включить больше функций в будущих статьях.
Состав
В этой статье мы расширяем анализ, проведенный в предыдущей статье, где мы получили модель линейной регрессии, которая зависела от одной функции. Теперь наша цель состоит в том, чтобы расширить эту модель, включив в нее две функции. Статья начинается с обсуждения построения регрессионной модели с двумя признаками, не углубляясь в математические детали. Затем представлен математический вывод, основанный на производной функции стоимости. Наконец, в конце статьи приведены соответствующие фрагменты кода Python, используемые в контексте этой статьи.
Функция гипотезы и параметризация
В литературе по машинному обучению, когда модель зависит только от одной функции, ее обычно записывают так:
Решение использовать h вместо f основано на том факте, что линейная модель представляет собой гипотезу. В общем, уравнение прямой может быть выражено как f(x) = a + bx, где a представляет точку пересечения, а b представляет собой наклон. Однако в моделях линейной регрессии цель состоит в том, чтобы определить параметры θ₀, θ₁, θ₂ и т. д., чтобы найти наиболее подходящую «линию». Следовательно, в качестве функции гипотезы используется h, параметризованная тета (θ), с нижними индексами, указывающими отдельные тета.
Упрощение и подготовка данных
Учитывая, что параметры четко определены в правой части приведенного выше уравнения, с этого момента и далее я буду использовать нижний индекс θ в левой части для представления всего набора тета, включая θ₀, θ₁ и т. д. далее:
Кроме того, я упрощаю обозначения, удаляя шапки у ys, которые обозначают метки. Это упрощение упрощает наш рабочий процесс. Прежде чем продолжить, мы извлекаем данные, исключая недопустимые записи. Для этого анализа мы выбрали два признака: площадь жилой площади и площадь участка.
Сосредоточьтесь на Sammamish и сегментации данных
Как и в предыдущей статье, наше внимание по-прежнему сосредоточено на изучении цен на жилье исключительно в Саммамише. Мы дополнительно уточняем данные, исключая записи с ценой 0 или пустые значения, а также несколько выбросов для улучшения читаемости. Оставшийся набор данных затем делится на обучающий набор (90%) и тестовый набор (10%). Вот пример из обучающих данных:
Образец обучающих данных
price sqft_living sqft_lot 4060 875000.0 3110 108464 4375 1020000.0 2950 78843 4284 505000.0 1240 57000 2471 883000.0 3670 54450 1646 568000.0 2340 50233 ... ... ... ... 2595 699850.0 2690 6164 4001 575000.0 2400 6137 4224 560000.0 1960 6058 4158 760005.0 3090 5859 3327 700000.0 2770 5686
Предположение о линейности и предыдущая модель регрессии
График цены в зависимости от жилой площади и площади участка соответственно дает:
На изображенном графике видно, что цена не имеет четкой линейной зависимости от размера лота. Однако для простоты будем предполагать линейность. В предыдущей статье мы вывели модель линейной регрессии для цены на основе квадратных футов жилой площади.
Теперь давайте продолжим анализ, чтобы включить две функции. Мы начинаем с создания графика, демонстрирующего взаимосвязь между ценой и жилой площадью и площадью участка.
Расширение до двух функций
Теперь давайте продолжим анализ, чтобы включить две функции. Мы начинаем с создания точечной диаграммы, которая демонстрирует взаимосвязь между ценой и жилой площадью и площадью участка. На том же графике мы также визуализируем функцию регрессии.
В отличие от предыдущей, регрессионная модель теперь представлена плоскостью (обозначенной синей областью) вместо простой линии. Это ожидаемо, поскольку каждое прогнозируемое значение зависит от двух переменных, обозначенных как x₁ и x₂, что требует плоскости для точного представления. В результате функция гипотезы может быть выражена как:
После применения линейной регрессии Python мы получаем следующую функцию гипотезы:
h = 167423 + 181.6 ⋅ x₁ + 1.65 ⋅ x₂
Поиск наилучшей посадки самолета
Как и в случае с одним признаком, чтобы определить наилучшую «плоскость», подходящую для нашей регрессионной модели с двумя параметрами, мы используем метод наименьших средних квадратов (LMS). Цель состоит в том, чтобы минимизировать сумму квадратов разностей между фактическими ценами и прогнозируемыми ценами, сгенерированными нашей функцией гипотезы.
Напомним, что в LMS мы вычисляем остаточную ошибку для каждой точки данных, которая представляет собой расстояние по вертикали между фактической ценой и прогнозируемой ценой, в данном случае на «плоскости». Эти остатки затем возводятся в квадрат, чтобы исключить любые отрицательные значения и подчеркнуть важность больших ошибок. Квадраты невязок суммируются для получения общей ошибки.
Чтобы получить «плоскость» наилучшего соответствия, когда функция линейно зависит как от жилой площади, так и от площади участка, мы используем метод оптимизации, используя производную функции стоимости по параметрам θ₀, θ₁ и θ₂.
Определив соответствующую функцию затрат, которая измеряет расхождение между прогнозируемыми ценами и фактическими ценами, мы стремимся минимизировать эту функцию затрат, чтобы получить оптимальную модель регрессии. В случае линейной регрессии обычно используемой функцией стоимости является среднеквадратическая ошибка.
Чтобы минимизировать функцию стоимости, мы берем производную по каждому параметру θ₀, θ₁ и θ₂. Приравняв эти производные к нулю и решив полученные уравнения, мы можем найти оптимальные значения θ₀, θ₁ и θ₂, которые минимизируют расстояние между прогнозируемыми ценами и фактическими ценами. Такой подход не всегда возможен, но есть и другие алгоритмы, которые будут рассмотрены в последующих статьях. Самый известный из них — градиентный спуск.
Полученные оптимальные значения параметров определяют «плоскость», которая лучше всего соответствует нашим данным, что позволяет нам точно прогнозировать цены на основе жилой площади и площади участка. Эта модель регрессии фиксирует линейную связь между функциями и целевой переменной, что позволяет делать надежные прогнозы для невидимых примеров.
Таким образом, используя метод наименьших квадратов, мы можем определить оптимальную «плоскость», подходящую для нашей регрессионной модели с двумя параметрами. Этот метод минимизирует общую ошибку путем корректировки значений параметров. Полученная модель обеспечивает точные прогнозы цен на жилье на основе жилой площади и площади участка, что позволяет нам принимать обоснованные решения и получать ценную информацию из данных.
Математика
Математическое определение параметров включает в себя выбор тета таким образом, чтобы минимизировать расстояние между точками данных и моделью, как показано в предыдущей статье. Этот принцип остается неизменным; однако теперь разница заключается в функции гипотезы, которая определяется как плоскость (как упоминалось ранее). В литературе эта функция широко известна как функция стоимости, обозначаемая
J(θ) = ∑ (yᵢ — hᵢ)², где yᵢ — цена записи i в наборе данных, а hᵢ представляет прогнозируемое значение, сгенерированное моделью гипотезы.
Теперь мы берем производную функции по каждому θ соответственно, считая остальные константами, и устанавливаем производные равными 0. Это дает следующую систему уравнений, которую необходимо решить:
Давайте назначим переменные для различных сумм следующим образом:
где индексы были удалены (но все еще помнят, что мы суммируем по всем элементам). Приведенная выше система уравнений теперь может быть записана как:
Исключение θ₀ из второго и третьего уравнений дает:
Еще задания:
Упростить еще больше
Исключив θ₁ из второго уравнения выше и найдя θ₁ в первом уравнении, мы получим:
И теперь у нас есть все, что нам нужно, чтобы определить все тета и, соответственно, модель плоской регрессии.
Код
fig, axes = plt.subplots(1, 2) axes[0].scatter(filtered_data['sqft_living'], filtered_data['price'], color = 'red', marker = 'x') axes[1].scatter(filtered_data['sqft_lot'], filtered_data['price'], color = 'red', marker = 'x') fig.suptitle('Right figure: Price as a function of size of living area. Left figure: Price as a function of size of lot.') axes[0].set_xlabel('sqft_living') axes[0].set_ylabel('Price') axes[1].set_xlabel('sqft_lot') axes[1].set_ylabel('Price') from sklearn.linear_model import LinearRegression X = train_data[['sqft_living', 'sqft_lot']] f = train_data['price'] model = LinearRegression() model.fit(X, f) print(regr.intercept_, regr.coef_) # 167422.71549613087 [181.61725411 1.65234854] %matplotlib notebook from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt import numpy as np import matplotlib.ticker as ticker X1 = train_data['sqft_living'].values.reshape(-1 , 1) X2 = train_data['sqft_lot'].values.reshape(-1 , 1) y = train_data['price'] X = train_data[['sqft_living' , 'sqft_lot']] model = LinearRegression() model.fit(X , y) intercept = model.intercept_ coef = model.coef_ # Regression model hypothesis def hypothesis(x1, x2): return intercept + coef[0]*x1 + coef[1]*x2 xaxis = np.linspace(0 , np.max(X1), 100) yaxis = np.linspace(0 , np.max(X2), 100) # Mesh grid X, Y = np.meshgrid(xaxis, yaxis) h = hypothesis(X, Y) # Plot fig = plt.figure() ax = fig.add_subplot(111, projection = '3d') #ax = plt.axes(projection = '3d') ax.scatter3D(X1, X2, y, marker='x', color = 'red') ax.plot_surface(X, Y, h, alpha=0.5) # Set labels and show the plot ax.set_xlabel('A$_{living}$ /sqft') ax.set_ylabel('A$_{lot}$ /sqft') ax.set_zlabel('price/\$ $ \cdot 10^{6}$') ax.set_title('House prices in Sammamish') # Format the tick values for the X and Y axes ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda xaxis, pos: f'{int(xaxis/1000):,}k')) ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda yaxis, pos: f'{int(yaxis/1000):,}k')) plt.show() # Create a linear regression model from sklearn import linear_model import numpy as np lvng = train_data['sqft_living'].values.reshape(-1,1) price = train_data['price'] model = linear_model.LinearRegression() model.fit(lvng, price) def func(x): return model.intercept_ + model.coef_ * x # Plot X = np.linspace(0, max(train_data['sqft_living'])+10, 100) h = func(X) plt.scatter(filtered_data['sqft_living'], filtered_data['price'], color='red', marker='x') plt.plot(X, h, color='blue', label='Regression Line') plt.xlabel('sqft_living') plt.ylabel('Price/$') plt.title('House prices in Sammamish as a function of living area') plt.legend() plt.show()