В предыдущем блоге Линейная регрессия был дан общий обзор простой линейной регрессии. Теперь пришло время узнать, как обучить вашу простую модель линейной регрессии и как получить линию, соответствующую вашему набору данных.
Градиентный спуск — это просто метод нахождения точки минимальной ошибки (сумма квадратов остатков), которая представляет собой коэффициент (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/
Использованная литература: