Используемая модель линейной регрессии
В настоящее время прокат велосипедов вводится во многих городах для повышения комфорта передвижения. Важно сделать арендованный велосипед доступным для публики в нужное время, поскольку это сокращает время ожидания. В конце концов, обеспечение города стабильным запасом прокатных велосипедов становится серьезной проблемой. Важнейшей частью является прогнозирование количества велосипедов, необходимого в каждый час для стабильного предложения велосипедов напрокат.
Описание данных
Набор данных содержит информацию о погоде (температура, влажность, скорость ветра, видимость, точка росы, солнечная радиация, снегопад, осадки), количество арендованных велосипедов в час и информацию о дате.
Информация об атрибутах:
- Дата: год-месяц-день
- Количество арендованных велосипедов — количество арендованных велосипедов в каждый час.
- Час — Час дня
- Температура-температура в градусах Цельсия
- Влажность - %
- Скорость ветра — м/с
- Видимость — 10м
- Температура точки росы — по Цельсию
- Солнечное излучение — МДж/м2
- Количество осадков — мм
- Снегопад — см
- Времена года — Зима, Весна, Лето, Осень
- Праздник — Выходной/Не выходной
- Функциональный день — NoFunc (нерабочие часы), Fun (рабочие часы)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
Блок-схема проекта:
- Загрузка данных и диагностика данных
- Фильтрация данных
- EDA данных Row для понимания внутренних корреляций.
- Разработка функций
- Выбор функции: мы мало используем из-за ограниченных функций в наших данных (только одна функция исключает использование хитмана для обострения проблемы мультиколлинеарности)
- Построение модели
- Обучение и тестирование моделей
- Оценка модели и настройка гиперпараметров.
- Развертывание модели
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