В предыдущем блоге Линейная регрессия был дан общий обзор простой линейной регрессии. Теперь пришло время узнать, как обучить вашу простую модель линейной регрессии и как получить линию, соответствующую вашему набору данных.

Градиентный спуск — это просто метод нахождения точки минимальной ошибки (сумма квадратов остатков), которая представляет собой коэффициент (a) и точку пересечения (b) наилучшей линии в уравнении линии y=ax+b

Давайте заново изобретем колесо, чтобы определить коэффициенты нашей модели линейной регрессии с помощью нескольких строк кода. После этого сравните то, что мы сделали, с выходом модели линейной регрессии scikitlearn.

Давайте заново изобретем колесо, чтобы определить коэффициенты нашей модели линейной регрессии с помощью нескольких строк кода. После этого сравните то, что мы сделали, с выходом модели линейной регрессии scikitlearn.

Градиентный спуск — это просто метод нахождения точки минимальной ошибки (сумма квадратов остатков), которая представляет собой коэффициент (a) и точку пересечения (b) наилучшей линии в уравнении линии y=ax+b

Давайте заново изобретем колесо, чтобы определить коэффициенты нашей модели линейной регрессии с помощью нескольких строк кода. После этого сравните то, что мы сделали, с выходом модели линейной регрессии scikitlearn.

1- Нахождение коэффициентов простой линейной регрессии

Во-первых, мы импортируем простой набор данных о заработной плате группы инженеров по сравнению с их многолетним опытом. Наша линейная модель должна предсказывать зарплату любой новой точки данных инженера.
Набор данных можно скачать по следующей ссылке.

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
df=pd.read_csv("Salary_Data.csv")

Теперь давайте посмотрим на график наших точек данных. Можно показать, что существует линейная зависимость между количеством лет опыта и заработной платой.

plt.scatter(df['YearsExperience'],df['Salary'])
plt.xlabel('Years of Experience')
plt.ylabel('Salary')
plt.show()

Следы 100 линий, которые проходят через наши точки данных, показаны ниже.
У нас есть сумма квадратов невязок для разных линий, давайте нанесем ее на график относительно наклонов.

slopes=np.linspace(-20000,20000,100) #slopes of trail lines 
x_line=np.linspace(0,12,100)         #x-axis scale
intercept=np.linspace(-1*(df['Salary'].mean()),df['Salary'].mean(),100)  #The intercepts of our lines vary around the mean of y data points.
ss_residuals=[] # A list to store the values of SS Residuals for each ine
for i,slope in enumerate (slopes):
    y_line=slope*x_line+intercept[i] #The equation of each line
    residuals=0
#Calculating The SS Residuals of each line    
    for j,salary in enumerate (df['Salary']):
        error=(salary-(slope*df['YearsExperience'][j]+intercept[i]))**2
        residuals=residuals+error
    ss_residuals.append(residuals)
    plt.plot(x_line,y_line)
    plt.xlabel('Years of Experience')
    plt.ylabel('Salary')
plt.scatter(df['YearsExperience'],df['Salary'])
plt.show()

Следы 100 линий, которые проходят через наши точки данных, показаны ниже.

У нас есть сумма квадратов невязок для разных линий, давайте построим ее против наклонов.

plt.plot(slopes,ss_residuals,'-')
plt.xlabel('slope')
plt.ylabel('Sum of Square Residuals')
plt.show()

Для этого графика мы видим, что ошибки постепенно уменьшаются до точки глобального минимума, а затем ошибки снова растут.

Точка с минимальной суммой квадратов невязок представляет наклон линии наилучшего соответствия. Чтобы найти минимумы, мы применяем следующие строки кода, чтобы найти индекс этой точки в списке ss_residuals и найти соответствующий ее наклон.

#while loop will continue until gets the minimum point
j=0
while ss_residuals[j] != min(ss_residuals): 
    j=j+1
print(j)

Индекс минимального значения в списке ss_residuals равен 70.

Давайте построим линию наилучшего соответствия с точками данных, чтобы просмотреть результат.

slopes=np.linspace(-20000,20000,100)
x_line=np.linspace(0,12,100)
intercept=np.linspace(-1*(df['Salary'].mean()),df['Salary'].mean(),100)
y_line1=slopes[70]*x_line+intercept[70]
plt.plot(x_line,y_line,'-r')
plt.plot(x_line,y_line1,'-b')
plt.xlabel('Years of Experience')
plt.ylabel('Salary')
plt.scatter(df['YearsExperience'],df['Salary'])
plt.show()
ss_residuals[70]
>> 8282.828282828283
intercept[70]
>> 31475.989898989894

Отлично, у нас есть лучшая линия, но лучшая ли она? Мы должны сравнить наше изобретенное колесо с современным колесом :)

2- Применение линейной модели scikit-learn

В scikit-learn это намного проще, мы подгоняем наш набор данных к модели и получаем коэффициенты.

from sklearn.linear_model import LinearRegression
lm=LinearRegression(fit_intercept=True)
X=(np.array(df['YearsExperience'])).reshape(-1,1)
lm.fit(X, df['Salary'])
lm.coef_
>> array([9449.96232146])
lm.intercept_
>> 25792.20019866871
lm.score(X,df['Salary'])
>> 0.9569566641435086

Мы видим, что оба коэффициента почти одинаковы. Давайте построим обе линии вместе, чтобы сравнить их.

Оценка модели составляет 0,95, что отлично подходит для линии наилучшего соответствия.

slopes=np.linspace(-20000,20000,100)
x_line=np.linspace(0,12,100)
intercept=np.linspace(-1*(df['Salary'].mean()),df['Salary'].mean(),100)
y_line1=slopes[70]*x_line+intercept[70]
y_line=9449.96232146*x_line+25792.20019866871
plt.plot(x_line,y_line,'-r')
plt.plot(x_line,y_line1,'-b')
plt.xlabel('Years of Experience')
plt.ylabel('Salary')
plt.scatter(df['YearsExperience'],df['Salary'])
plt.show()

Круто, но обе линии кажутся разными, но это можно улучшить, увеличив количество линий тропы.

Спасибо за чтение!

Вы можете связаться со мной по адресу: https://www.linkedin.com/in/bassemessam/

Использованная литература:

https://www.kaggle.com/karthickveerakumar/salary-data-simple-linear-regression?select=Salary_Data.csv