Используемая модель линейной регрессии

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

Описание данных

Набор данных содержит информацию о погоде (температура, влажность, скорость ветра, видимость, точка росы, солнечная радиация, снегопад, осадки), количество арендованных велосипедов в час и информацию о дате.

Информация об атрибутах:

  • Дата: год-месяц-день
  • Количество арендованных велосипедов — количество арендованных велосипедов в каждый час.
  • Час — Час дня
  • Температура-температура в градусах Цельсия
  • Влажность - %
  • Скорость ветра — м/с
  • Видимость — 10м
  • Температура точки росы — по Цельсию
  • Солнечное излучение — МДж/м2
  • Количество осадков — мм
  • Снегопад — см
  • Времена года — Зима, Весна, Лето, Осень
  • Праздник — Выходной/Не выходной
  • Функциональный день — NoFunc (нерабочие часы), Fun (рабочие часы)

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.

Блок-схема проекта:

  1. Загрузка данных и диагностика данных
  2. Фильтрация данных
  3. EDA данных Row для понимания внутренних корреляций.
  4. Разработка функций
  5. Выбор функции: мы мало используем из-за ограниченных функций в наших данных (только одна функция исключает использование хитмана для обострения проблемы мультиколлинеарности)
  6. Построение модели
  7. Обучение и тестирование моделей
  8. Оценка модели и настройка гиперпараметров.
  9. Развертывание модели

1. Импорт библиотек и данных

попробуйте решить с помощью первой линейной регрессии.

# Import necessary libraries
import pandas as pd     #provides wide variety tools for data analysis,many inbuilt methods for grouping, combining and filtering data.
import numpy as np      #for some basic mathematical operations
from matplotlib import pyplot as plt #comprehensive library for creating static, animated, and interactive visualizations
import seaborn as sns                #  high-level interface for drawing attractive and informative statistical graphics
from sklearn.model_selection import train_test_split, GridSearchCV,  cross_val_score
from sklearn import preprocessing, linear_model
from sklearn.preprocessing import  LabelEncoder,OneHotEncoder
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler 
from sklearn.metrics import r2_score, mean_squared_error, accuracy_score
from  sklearn.linear_model import LinearRegression
import warnings
warnings.filterwarnings('ignore')
pd.pandas.set_option('display.max_columns',None)
%matplotlib inline

1.1 _ Загрузка данных

Теперь мы можем создать фрейм данных Pandas, используя загруженный файл, для просмотра и анализа данных.

In [2]:

# Read the csv file
data=pd.read_csv('SeoulBikeData.csv',encoding= 'unicode_escape')

1.1.1 _ Данные первого просмотра и идентифицирующие признаки

Набор данных содержит 8760 строк и 14 столбцов. Каждая строка набора данных содержит информацию о погодных условиях.

Наша цель – найти способ прогнозирования ценности количества велосипедов, необходимого в каждый час для стабильного предложения велосипедов напрокат. используя значения в других столбцах. Если мы сможем сделать это для исторических данных, то сможем оценить необходимое количество велосипедов в каждый час.

1.1.2 _First Проверка повторяющихся записей в данных

  • Дублирование записей с неправильным прогнозом, а также использование ненужного хранилища и времени при тестировании и обучении данных.
# Check for duplicated entries.
print("Duplicate entry in data:",len(data[data.duplicated()]))
Duplicate entry in data: 0

В данных не обнаружено повторяющихся записей

1.2 _ Диагностика данных

# Custom Function for Dtype,Unique values and Null values
def datainfo():
    temp_ps = pd.DataFrame(index=data.columns)
    temp_ps['DataType'] = data.dtypes
    temp_ps["Non-null_Values"] = data.count()
    temp_ps['Unique_Values'] = data.nunique()
    temp_ps['NaN_Values'] = data.isnull().sum()
    temp_ps['NaN_Values_Percentage'] = (temp_ps['NaN_Values']/len(data))*100 
    return temp_ps
# Shape of the data.
print("Total Rows and Columns in DataFrame is :",data.shape,"\n") 
# Custom Function
datainfo()
Total Rows and Columns in DataFrame is : (8760, 14)

Поиск деталей из данных:

  • Есть 14 функций с 8760 строками данных.
  • Есть 3 категориальных столбца и 11 числовых столбцов. Столбцы «Дата», «Времена года» и «Рабочий день» имеют тип данных 𝑜𝑏𝑗𝑒𝑐𝑡.
  • Столбцы «Счетчик арендованных велосипедов», «Час», «Влажность (%)» и «Видимость (10𝑚)» имеют числовой тип данных 𝑖𝑛𝑡64.
  • Столбцы «Температура Температура (℃)», «Скорость ветра (𝑚/𝑠)», «Температура точки росы (℃)», «Солнечная радиация (𝑀𝐽/𝑚2)», «Осадки (𝑚𝑚)» и «Снегопад (𝑐𝑚) имеют числовой тип данных 𝑓𝑙𝑜𝑎𝑡64
  • Ни в одном столбце нет нулевого значения
  • Уникальный счет: Сезоны - 4, Праздники - 2, Рабочий день - 2
# Statistical info.
data.describe().T   #.T use for transpose the describe table

Диапазоны значений в числовых столбцах также кажутся разумными, поэтому нам, возможно, не придется сильно очищать данные. Столбцы «Скорость ветра», «Температура точки росы (°C)», «Солнечная радиация», «Осадки» и «Снегопад» кажутся значительно искаженными, поскольку медиана (50 процентиль) намного ниже максимального значения. .

2. Фильтрация данных

2.1_Дни аренды велосипеда Фильтрация

#for chech functioning and non functioning day ,plot (Hour Vs Rented Bike Count Graph)
def barplots(x,y,hue):
    plt.figure(figsize=(15,7))
    sns.set_palette("husl")
    sns.barplot(x=x,y=y,hue=hue,data=data);
barplots('Hour','Rented Bike Count','Functioning Day')

# Grouping by functioning day and calculating the total Rented Bike Count
data.groupby('Functioning Day').sum()['Rented Bike Count'].sort_values(ascending = False).reset_index()

Согласно диагностическим данным, прокат велосипеда выдается только в рабочий день, поэтому удалите нерабочие дни, а затем удалите столбец "рабочие дни"

#Removing data of non functional days (non rented days)
df=data.drop(data[data['Functioning Day'] == 'No'].index)
#Due to not unsefull in Functioning Day Column ,remove Functioning Day Column
df1=df.drop(['Functioning Day'], axis = 1
#Checking DataFrame Shape After Removing Non Functional Day Rows And Functional Day Column
print("Filtered Dataframe with only rented bike days :",df1.shape,"\n")
Filtered Dataframe with only rented bike days : (8465, 13)

2.2 _ Отделить дату, месяц, год от столбца даты

Сначала конвертируем Date в date column и извлекаем разные части даты.

#convert in datetime64[ns] datatype
df1['Date'] = pd.to_datetime(df1['Date']) 
df1['Date']
0      2017-01-12
1      2017-01-12
2      2017-01-12
3      2017-01-12
4      2017-01-12
          ...    
8755   2018-11-30
8756   2018-11-30
8757   2018-11-30
8758   2018-11-30
8759   2018-11-30
Name: Date, Length: 8465, dtype: datetime64[ns]
#Seperate Day, Month, Year from DataFrame Column
df1['Day']=df1['Date'].dt.day
df1['Month']=df1['Date'].dt.month
df1['Year']=df1['Date'].dt.year

In [14]:

# drop the Date column after extracting necessory information
df1.drop(columns=['Date'],inplace=True)

3. Исследовательский анализ и визуализация Давайте изучим данные, визуализируя распределение значений в некоторых столбцах набора данных и взаимосвязь между «Счетчиком арендованных велосипедов» и другими столбцами.

Для визуализации будем использовать библиотеки Matplotlib, Seaborn.

3.1 _ Проверка корреляции данных

Корреляция — это статистическая мера, выражающая силу взаимосвязи между двумя переменными.

Два основных типа корреляции: положительная и отрицательная.

Положительная корреляция возникает, когда две переменные движутся в одном направлении; по мере увеличения одного увеличивается и другой.

Отрицательная корреляция возникает, когда две переменные движутся в противоположных направлениях; по мере увеличения одного значение другого уменьшается.

Корреляцию можно использовать для проверки гипотез о причинно-следственных связях между переменными. Корреляция часто используется в реальном мире для прогнозирования тенденций.

#.corr() use to find correlation with data
data_corr= df1.corr()       
plt.figure(figsize=(12,12))
#cmap use for colour palette , linewidths : set the width of the lines that divide the cells, 
#annot :helps in annotating the heatmap with values if set to True, otherwise values are not provided , linecolor : helps in setting the color of each line that divides heatmap cells
sns.heatmap(data_corr, cmap='coolwarm', linewidths=0.1, annot=True, linecolor='white')

Корреляция temperature и Dew point temperature составляет почти 0,91, поэтому возникает проблема мультиколлинеарности. поэтому мы опускаем функцию Dew point temperature, потому что, если мы видим, что Dew point temperature почти на 0,4 связано с нашей целевой переменной, которая меньше, чем temperature 0,56.

#Drop Dew point temperature(°C) from dataset df1
df1.drop(columns=['Dew point temperature(°C)'],inplace=True)

Поиск внутренней информации:

  • Мы видим, что с нашей целевой переменной (счетчик арендованных велосипедов) наиболее коррелированными переменными являются час, температура, температура точки росы.

3.2 _ Отдельные числовые и категориальные переменные

Категориальные данные – это тип данных, который используется для группировки информации со схожими характеристиками.

Числовые данные – это тип данных, который выражает информацию в виде чисел.

Числовые переменные

#if dtype is not Equal to object type then its a num data
numerical_features=df1.columns[df1.dtypes!='object'].tolist()
numerical_features
['Rented Bike Count',
 'Hour',
 'Temperature(°C)',
 'Humidity(%)',
 'Wind speed (m/s)',
 'Visibility (10m)',
 'Solar Radiation (MJ/m2)',
 'Rainfall(mm)',
 'Snowfall (cm)',
 'Day',
 'Month',
 'Year']

In [18]:

# Seprate dataframe for Numerical feature
num_data=df1[numerical_features]
num_data

#plot num data to analysis data distribution
fig = plt.figure(figsize = (20,5))
for index,column in enumerate(numerical_features) :
  plt.subplot(3,5,index+1)
  sns.distplot(df1[column])
  feature = df1[column]
  ax = fig.gca() # get current axes
  ax.axvline(feature.mean(), color='#ff033e', linestyle='dashed', linewidth=2)  #Rose-Red Color indicate mean of data
  ax.axvline(feature.median(), color='#00ffff', linestyle='dashed', linewidth=2) #Cyan indicate median of data
  plt.title(f'{column.title()}')
  plt.tight_layout()

df1.agg(['skew', 'kurtosis']).transpose()

Правильное/положительное асимметричное распределение: режим ‹ Медиана ‹ Среднее значение: количество арендованных велосипедов, скорость ветра (м/с), солнечная радиация (МДж/м2)

Без перекоса: среднее значение = медиана = режим: час, температура, влажность (%), осадки (мм), снегопад (см)

Левое/отрицательное перекошенное распределение: среднее ‹ медиана ‹ режим: видимость (10 м)

Распределение с перекосом влево:

  • Среднее значение обычно меньше медианы, а мода обычно больше среднего и медианы.
  • Большинство данных сосредоточено в правой части распределения с несколькими крайними значениями в левом хвосте.
  • Распределение может иметь длинный хвост в левой части, что указывает на наличие некоторых экстремальных значений, которые намного ниже основной части данных.
  • Распределение с асимметрией влево может быть вызвано наличием выбросов с низкими значениями.
  • Распределение с асимметрией влево может повлиять на статистический анализ, предполагающий нормальность n, и может потребовать преобразования данных перед проведением определенных анализов.

Распределение с перекосом вправо:

  • Среднее значение обычно больше медианы, а мода обычно меньше и среднего, и медианы.
  • Большая часть данных сосредоточена в левой части распределения с несколькими экстремальными значениями в правом хвосте.
  • Распределение может иметь длинный хвост в правой части, что указывает на наличие некоторых экстремальных значений, которые намного превышают основную массу данных.
  • Правостороннее распределение может быть вызвано наличием выбросов с высокими значениями.
  • Правостороннее распределение может повлиять на статистический анализ, предполагающий нормальность, и может потребовать преобразования данных перед проведением определенных анализов.

Дискретные значения

## Lets analyse the discrete values by creating histograms to understand the distribution
num_discrete_value=[feature for feature in numerical_features if len(df1[feature].unique())<32]
print("Discrete Variables Count: {}".format(len(num_discrete_value)))
fig = plt.figure(figsize = (20,10))
for index,column in enumerate(num_discrete_value) :
  plt.subplot(2,2,index+1)
  dataset=df1.copy()
  dataset.groupby(feature)['Rented Bike Count'].sum().plot(kind='bar',color="#ff033e") #kind=bar use for ploting barchart
  feature = df1[column]
  ax = fig.gca()
  plt.ylabel('Total Rented Bike Count')
  plt.tight_layout()
  plt.grid(color='#95a5a6', linestyle='--', linewidth=2, axis='y', alpha=0.2)
  for p in ax.patches:
      ax.annotate(round(p.get_height()),(p.get_x() + p.get_width()/2,p.get_height()),ha='center',size= 12, rotation=90) #ha use to write count in center and rotation use to rotate count to 90 degree and make clear visible on graph
Discrete Variables Count: 4

Категориальные переменные

#For categorical Data
categorical_features=[col for col in df1.columns if df1[col].dtype=='O']
categorical_features

Исход[22]:

['Seasons', 'Holiday']

In [23]:

# Seprate dataframe for Categorical feature
cat_data=df1[categorical_features]

In [24]:

# Unique number of categorical features
for feature in categorical_features:
    print('The feature is {} and number of categories are {}'.format(feature,len(data[feature].unique())))
The feature is Seasons and number of categories are 4
The feature is Holiday and number of categories are 2

In [25]:

# GROUPING BY SEASONS AND CALCULATING THE TOTAL RENTED BIKE COUNT
data.groupby('Seasons').sum()['Rented Bike Count'].sort_values(ascending = False).reset_index()

Исход[25]:

In [26]:

# GROUPING BY HOLIDAY AND CALCULATING THE TOTAL RENTED BIKE COUNT
data.groupby('Holiday').sum()['Rented Bike Count'].sort_values(ascending = False).reset_index()

Исход[26]:

Праздник — — Количество арендованных велосипедов0

Не выходной — -› 59564191

Праздник — — -›215895

Значения категорий

In [27]:

#Find out the relationship between categorical variable and dependent feature Rented Bike Count
fig = plt.figure(figsize = (20,10))
for index,column in enumerate(categorical_features) :
    plt.subplot(1,2,index+1)
    dataset=df1.copy()
    dataset.groupby(feature)['Rented Bike Count'].sum().plot(kind='bar',color="#ff033e")
    feature = df1[column]
    ax = fig.gca()
    plt.ylabel('Total Rented Bike Count')
    plt.tight_layout()
    plt.grid(color='#95a5a6', linestyle='--', linewidth=2, axis='y', alpha=0.2)
    for p in ax.patches:
        ax.annotate(round(p.get_height()),(p.get_x() + p.get_width()/2,p.get_height()),ha='center',size= 12, rotation=90)

In [28]:

fig, axs = plt.subplots(nrows=2,ncols=1,figsize=(15,8), dpi=100)
sns.pointplot(data=dataset, x="Hour", y="Rented Bike Count", ax=axs[0], 
              hue="Holiday")
sns.lineplot(data=dataset, x="Hour", y="Rented Bike Count", ax=axs[1], 
              hue="Seasons", marker="x",markeredgecolor="black")
plt.tight_layout()

Точечный график – это тип статистической визуализации, отображающий среднее значение и доверительный интервал (или планки погрешностей) числовой переменной для различных категорий или групп. На точечном графике среднее значение представлено точкой или маркером, а планки погрешностей показывают доверительный интервал или стандартную ошибку среднего. Это особенно полезно для сравнения средних значений различных групп или категорий в наборе данных.

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

4. Разработка функций на основе данных

  • Кодировать категориальные данные в горячие векторы.
  • Определите входы и цель
  • Масштабировать значения в числовых столбцах до диапазона (0,1)(0,1).
  • Разделите набор данных на наборы для обучения и проверки.

4.1 _ Кодирование данных

Кодировать категориальные данные в обоих кодировщиках и проверять точность кодировщиков:

  • oh_df : данные OneHotEncoder
  • le_df : данные LabelEncoder

4.1.1 _ Применение OneHotEncoder к данным

Поскольку модели машинного обучения можно обучать только с числовыми данными, нам необходимо преобразовать категориальные данные в числа. Обычный метод — использовать однократное кодирование для категориальных столбцов.

Одно горячее кодирование включает добавление нового двоичного (0/1) столбца для каждой уникальной категории категориального столбца.

In [29]:

oh_df=pd.get_dummies(df1, columns=['Seasons', 'Holiday'], drop_first=True)
oh_df

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

4.1.2 _ Применить кодировщик меток

In [30]:

# Encode labels of multiple columns at ones using LabelEncoder
le_df=pd.get_dummies(df1,columns=['Holiday','Seasons','Functioning Day','Hour'],drop_first=True)

Проверка данных столбца сезона

In [31]:

df1.groupby("Seasons").count()  #for checking raw data

Исход[31]:

In [32]:

le_df.groupby('Seasons').count() #Seasons convert to numerical after apply transformation on data

Вышел [32]:

0: Осень, 1: Весна, 2: Лето, 3: Зима. Обратите внимание, что 0,1,2,3 — это просто способ представления. Он не содержит какого-либо доминирования или влияния

Проверка распределения и аутлайнера на фрейме данных

#checking for outliers
plt.figure(figsize=(10,5))   # for define chart size
plt.xticks(rotation =90)     #plot X-axis ticks in 90 degree rotation for clear visible
sns.boxplot(data = le_df)    #box plot of le_df data frame raw data
plt.show()

Анализ распределения целевого параметра Rented Bike Count....

plt.figure(figsize=(10,5))
plt.boxplot(le_df['Rented Bike Count'],vert=False)
plt.show()

Обнаружение контура с использованием межквартильного диапазона

Квадратный корень — — -›Метод квадратного корня обычно используется, когда ваши данные умеренно искажены. Теперь использование квадратного корня (например, sqrt(x)) — это преобразование, которое оказывает умеренное влияние на форму распределения. Обычно он используется для уменьшения искажения данных вправо. Наконец, квадратный корень можно применять к нулевым значениям, и чаще всего он применяется к подсчитанным данным.

Преобразование квадратного корня: преобразование значений y в √y.

Логарифмическое преобразование Логарифмическое преобразование — это сильное преобразование, оказывающее большое влияние на форму распределения. Этот метод, как и метод квадратного корня, часто используется для уменьшения правой асимметрии. Однако стоит отметить, что его нельзя применять к нулевым или отрицательным значениям.

Преобразование журнала: преобразование значений y в log(y).

Преобразование кубического корня включает преобразование x в x^ (1/3). Это довольно сильное преобразование, существенно влияющее на форму распределения, но слабее логарифмического. Его также можно применять к отрицательным и нулевым значениям. Отрицательно искаженные данные

Преобразование кубического корня: преобразование значений y в y^(1/3).

#apply diffrent tranformation technique and checking data distributation
fig,axes = plt.subplots(1,4,figsize=(20,5))
sns.distplot((le_df['Rented Bike Count']),ax=axes[0],color='brown').set_title(" Input data")
sns.distplot(np.log1p(le_df['Rented Bike Count']+0.0000001),ax=axes[1],color='red').set_title("log1p") #transform only posible in positive value and >0 value so add 0.0000001 in data
sns.distplot(np.sqrt(le_df['Rented Bike Count']),ax=axes[2], color='blue').set_title("Square root")
sns.distplot(np.cbrt(le_df['Rented Bike Count']*2),ax=axes[3], color='green').set_title("cube root")
Text(0.5, 1.0, 'cube root')
import scipy.stats as stats
def plotvariable(df,variable):
  plt.figure(figsize=(10,5))
  plt.subplot(1,2,1)   #means 1 row, 2 Columns and 1st plot
  df[variable].hist(bins=30)
  ##QQ plot
  plt.subplot(1,2,2)
  stats.probplot(df[variable], dist='norm',plot=plt)
  plt.show()
  print(df[variable].skew())
plotvariable(le_df,'Rented Bike Count')

0.7938148420670103

наша цель Rented Bike Count обычно не распределяется, поэтому нам нужно сделать некоторые преобразования перед подачей в модель

data["RBC_qb"]=np.cbrt(data['Rented Bike Count']) #try cube root technique to convert positive screwd to normal distributation
plotvariable(data,"RBC_qb")
data['RBC_qb'].skew()
-0.31775917995579267
-0.31775917995579267
plt.figure(figsize=(10,5))
plt.boxplot(data["RBC_qb"],vert=False)
plt.show()
le_df_=le_df.copy()
le_df_['Rented Bike Count']=np.sqrt(le_df['Rented Bike Count'])
plotvariable(le_df_,'Rented Bike Count')
le_df_['Rented Bike Count'].skew()
0.16925358699257584
0.16925358699257584
plt.figure(figsize=(10,5))
plt.boxplot(le_df_["Rented Bike Count"],vert=False)
plt.show()

Теперь это похоже на нормальное распределение

plotvariable(le_df,'Wind speed (m/s)')
0.8616479716535727

не похоже на нормальное и неправильное распределение, поэтому необходимо применить преобразование.

le_df_['Wind speed (m/s)']=np.sqrt(le_df['Wind speed (m/s)'])
plotvariable(le_df_,'Wind speed (m/s)')
-0.014489471518114892

выглядит как нормальное распределение.

Но мы идем с классом силового трансформатора sklearn.

le_df.drop(columns='Year',inplace=True)
var=list(le_df.select_dtypes(include=['float64','int64']).columns)


from sklearn.preprocessing import PowerTransformer
sc_X=PowerTransformer(method = 'yeo-johnson')
le_df[var]=le_df.fit_transform(df1[var])

4.2 _ Определите входные данные и цели

  • Столбец Rented Bike Count содержит значение, которое нам нужно предсказать, т. е. это целевой столбец.
  • Данные из всех остальных столбцов (кроме первого и последнего) могут использоваться в качестве входных данных для модели.

Создайте список X имен столбцов, содержащих данные, которые можно использовать в качестве входных данных для обучения модели, и определите целевой столбец как переменную y.

Убедитесь, что столбцы Date и Rented Bike Count не включены.

Теперь, когда мы определили входной и целевой столбцы, мы можем разделить входные и целевые данные.

# Identify the input columns (a list of column names)
X=le_df.drop('Rented Bike Count',axis=1)
y=le_df['Rented Bike Count']

4.3 _ Разделение набора для обучения и тестирования

Наконец, давайте разделим набор данных на обучающий и тестовый. Мы будем использовать случайно выбранное 30% подмножество данных для проверки. Кроме того, мы будем использовать только числовые и закодированные столбцы.

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
# Let's check the shape of the train and test dataset
print(f'The shape of the train and test set for the independent variables are : X_train = {X_train.shape}, X_test = {X_test.shape}')
print(f'The shape of the train and test set for the dependent variables are : y_train = {y_train.shape}, y_test = {y_test.shape}')
The shape of the train and test set for the independent variables are : X_train = (6772, 13), X_test = (1693, 13)
The shape of the train and test set for the dependent variables are : y_train = (6772,), y_test = (1693,)

5. Масштабирование данных и построение модели с использованием различных методов регрессии

Регрессионный поиск взаимосвязей между переменными.

Зависимые функции называются зависимыми переменными, выходными данными или ответами.

Независимые функции называются независимыми переменными, входными данными, регрессорами или предикторами.

def predict(ml_model,X,y):
    X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.20,random_state=10)
    rob =RobustScaler()
    X_train = rob.fit_transform(X_train)
    X_test = rob.transform(X_test)
    model=ml_model.fit(X_train,y_train)
    y_pred=model.predict(X_test)
    plt.scatter(y_pred,y_test,color='b')
    plt.xlabel('Predicted')
    plt.ylabel('Actual')
    print(f'R^2 is {model.score(X_test,y_test)}\n Adj R^2 is {1-(1-model.score(X_test,y_test))*(len(y_test)-1)/(len(y_test)-X_test.shape[1]-1)}\n RMSE is: {mean_squared_error(y_test,y_pred,squared=False)}')

R2 показывает, насколько хорошо термины (точки данных) соответствуют кривой или линии. Скорректированный R2 также показывает, насколько хорошо термины соответствуют кривой или линии, но с поправкой на количество терминов в модели. Если вы добавляете в модель все больше и больше бесполезных переменных, скорректированный r-квадрат будет уменьшаться. Если вы добавите больше полезных переменных, скорректированный r-квадрат увеличится.

Скорректированный R2 всегда будет меньше или равен R2.

R2 предполагает, что каждая отдельная переменная объясняет изменение зависимой переменной.

Скорректированный R2 – это процент вариации, объясняемый только теми независимыми переменными, которые фактически влияют на зависимую переменную.

MSE – это функция риска, которая позволяет вычислить среднеквадратичную разницу между прогнозируемым и фактическим значением функции или переменной.

RMSE — это сокращение от Root Mean Square Error, которое представляет собой квадратный корень из значения, полученного с помощью функции Mean Square Error.

Линейная регрессия:

Здесь несколько зависимых переменных, так что это называется множественной линейной регрессией.

predict(LinearRegression(),X,y)
R^2 is 0.7841055740368184
 Adj R^2 is 0.781175270450891
 RMSE is: 0.47085002746837