本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.
大家好,实战是学习机器学习的最好方法。今天在本文中,我们将使用机器学习方法来对航班票价进行预测。 为方便大家实操,文末提供完整版代码和数据。
关于数据集
数据来kaggle比赛数据,我首先对数据集的字段进行说明,方便后续分析和理解
Airline:所有类型的航空公司,例如 Indigo、Jet Airways、Air India
Date_of_Journey:乘客旅程的开始日期
Source:乘客旅程开始的地点名称
Destination:乘客想要前往的地点的名称
Route:乘客选择从他/她的来源到目的地的路线是什幺
Arrival_Time:乘客到达目的地的时间
Duration:持续时间是航班完成从源头到目的地的旅程的整个时间
Total_Stops:整个旅程中将在多少地方停留
Additional_Info:获得有关食物、食物种类和其他便利设施的信息
Price:完整旅程的航班价格,包括登机前的所有费用
引入库
为方便后续航空价格做预测,我们先引入对应库
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as mse from sklearn.metrics import r2_score from math import sqrt from sklearn.linear_model import Ridge from sklearn.linear_model import Lasso from sklearn.tree import DecisionTreeRegressor from sklearn.ensemble import RandomForestRegressor from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import KFold from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.model_selection import RandomizedSearchCV from prettytable import PrettyTable
读取数据
train_df = pd.read_excel("Data_Train.xlsx") train_df.head(10)
探索性数据分析(EDA)
我们查看数据集所具有的列类型。
train_df.columns #Output Index(['Airline', 'Date_of_Journey', 'Source', 'Destination', 'Route', 'Dep_Time', 'Arrival_Time', 'Duration', 'Total_Stops', 'Additional_Info', 'Price'], dtype='object')
在这里,我们可以获得数据集的更多信息
train_df.info()
了解有关数据集的更多信息
train_df.describe()
现在在使用 IsNull 函数时,我们将看到数据集中空值的数量
train_df.isnull().head()
现在在使用 IsNull 函数和 sum 函数时,我们将看到数据集中空值的数量
train_df.isnull().sum() #output Airline 0 Date_of_Journey 0 Source 0 Destination 0 Route 1 Dep_Time 0 Arrival_Time 0 Duration 0 Total_Stops 1 Additional_Info 0 Price 0 dtype: int64
删除 NAN 值
train_df.dropna(inplace = True)
重复值
train_df[train_df.duplicated()].head()
在这里,我们将从数据集中删除那些重复的值,并保持原地属性为真,这样就不会发生任何变化。
train_df.drop_duplicates(keep='first',inplace=True) train_df.head()
当前数据集数量
train_df.shape #output (10462, 11)
检查 Additional_info 列并计算唯一类型的值。
train_df["Additional_Info"].value_counts() #output No info 8182 In-flight meal not included 1926 No check-in baggage included 318 1 Long layover 19 Change airports 7 Business class 4 No Info 3 1 Short layover 1 2 Long layover 1 Red-eye flight 1 Name: Additional_Info, dtype: int64
检查不同的航空公司
train_df["Airline"].unique() #output array(['IndiGo', 'Air India', 'Jet Airways', 'SpiceJet', 'Multiple carriers', 'GoAir', 'Vistara', 'Air Asia', 'Vistara Premium economy', 'Jet Airways Business', 'Multiple carriers Premium economy', 'Trujet'], dtype=object)
检查不同的航线
train_df["Route"].unique() # output
现在让我们看看我们的测试数据集
test_df = pd.read_excel("Test_set.xlsx") test_df.head(10)
测试数据所具有的列类型
test_df.columns #output Index(['Airline', 'Date_of_Journey', 'Source', 'Destination', 'Route', 'Dep_Time', 'Arrival_Time', 'Duration', 'Total_Stops', 'Additional_Info'], dtype='object')
有关数据集的信息
test_df.info()
了解有关测试数据集的更多信息
test_df.describe()
现在在使用 IsNull 函数和 sum 函数时,我们将看到测试数据中空值的数量
test_df.isnull().sum() # output Airline 0 Date_of_Journey 0 Source 0 Destination 0 Route 0 Dep_Time 0 Arrival_Time 0 Duration 0 Total_Stops 0 Additional_Info 0 dtype: int64
绘制价格(Price)与航空公司(Airline)图 在猫图的帮助下,我们试图绘制航班价格和航空公司价格之间的箱线图,我们可以得出结论,Jet Airways 在价格方面的异常值最多。
绘制价格与来源的小提琴图
sns.catplot(y = "Price", x = "Source", data = train_df.sort_values("Price", ascending = False), kind="violin", height = 4, aspect = 3) plt.show()
现在仅借助猫图,我们在航班价格和源地之间绘制箱线图,即乘客将从哪里前往目的地,我们可以看到作为源地的班格罗尔(Banglore)拥有最多异常值,而金奈(Chennai)最少。
绘制价格与目的地的箱线图
sns.catplot(y = "Price", x = "Destination", data = train_df.sort_values("Price", ascending = False), kind="box", height = 4, aspect = 3) plt.show()
我们在航班价格和乘客旅行目的地之间的猫图的帮助下绘制箱线图,并发现新德里(New Delhi)的异常值最多,加尔各答(Kolkata)的异常值最少。
特征工程
先看看数据
train_df.head()
在这里,我们首先划分特征和标签,然后将小时转换为分钟。
train_df['Duration'] = train_df['Duration'].str.replace("h", '*60').str.replace(' ','+').str.replace('m','*1').apply(eval) test_df['Duration'] = test_df['Duration'].str.replace("h", '*60').str.replace(' ','+').str.replace('m','*1').apply(eval)
Date_of_Journey:标准化旅程日期的格式,以便在模型阶段进行更好的预处理。
train_df["Journey_day"] = train_df['Date_of_Journey'].str.split('/').str[0].astype(int) train_df["Journey_month"] = train_df['Date_of_Journey'].str.split('/').str[1].astype(int) train_df.drop(["Date_of_Journey"], axis = 1, inplace = True)
Dep_Time:将出发时间转换为小时和分钟
train_df["Dep_hour"] = pd.to_datetime(train_df["Dep_Time"]).dt.hour train_df["Dep_min"] = pd.to_datetime(train_df["Dep_Time"]).dt.minute train_df.drop(["Dep_Time"], axis = 1, inplace = True)
Arrival_Time:将到达时间转换为小时和分钟。
train_df["Arrival_hour"] = pd.to_datetime(train_df.Arrival_Time).dt.hour train_df["Arrival_min"] = pd.to_datetime(train_df.Arrival_Time).dt.minute train_df.drop(["Arrival_Time"], axis = 1, inplace = True)
在最后的预处理之后,让我们看看数据集 绘制月份(持续时间)与航班数量的条形图
plt.figure(figsize = (10, 5)) plt.title('Count of flights month wise') ax=sns.countplot(x = 'Journey_month', data = train_df) plt.xlabel('Month') plt.ylabel('Count of flights') for p in ax.patches: ax.annotate(int(p.get_height()), (p.get_x()+0.25, p.get_height()+1), va='bottom', color= 'black')
在上图中,我们绘制了一个月旅程与几个航班的计数图,并看到五月的航班数量最多。
绘制航空公司类型与航班数量的条形图
plt.figure(figsize = (20,5)) plt.title('Count of flights with different Airlines') ax=sns.countplot(x = 'Airline', data =train_df) plt.xlabel('Airline') plt.ylabel('Count of flights') plt.xticks(rotation = 45) for p in ax.patches: ax.annotate(int(p.get_height()), (p.get_x()+0.25, p.get_height()+1), va='bottom', color= 'black')
从上图中我们可以看到,在航空公司类型和航班数量之间,我们可以看到 Jet Airways 登机的航班最多。
绘制机票价格 VS 航空公司
plt.figure(figsize = (15,4)) plt.title('Price VS Airlines') plt.scatter(train_df['Airline'], train_df['Price']) plt.xticks plt.xlabel('Airline') plt.ylabel('Price of ticket') plt.xticks(rotation = 90)
所有特征之间的相关性
绘制相关性
plt.figure(figsize = (15,15)) sns.heatmap(train_df.corr(), annot = True, cmap = "RdYlGn") plt.show()
删除价格列,因为它没有用
data = train_df.drop(["Price"], axis=1)
处理分类数据和数值数据
train_categorical_data = data.select_dtypes(exclude=['int64', 'float','int32']) train_numerical_data = data.select_dtypes(include=['int64', 'float','int32']) test_categorical_data = test_df.select_dtypes(exclude=['int64', 'float','int32','int32']) test_numerical_data = test_df.select_dtypes(include=['int64', 'float','int32']) train_categorical_data.head()
分类列的标签编码和热编码
le = LabelEncoder() train_categorical_data = train_categorical_data.apply(LabelEncoder().fit_transform) test_categorical_data = test_categorical_data.apply(LabelEncoder().fit_transform) train_categorical_data.head()
连接分类数据和数值数据
X = pd.concat([train_categorical_data, train_numerical_data], axis=1) y = train_df['Price'] test_set = pd.concat([test_categorical_data, test_numerical_data], axis=1) X.head()
构建模型
1、构建评估模型的平均绝对百分比误差
# Calculating Mean Absolute Percentage Error def mean_absolute_percentage_error(y_true, y_pred): y_true, y_pred = np.array(y_true), np.array(y_pred) return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
2、切分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)
数据统计如下
3、模型训练整个流程
Ridge Regression Lasso Regression 算法整个流程 决策树算法整体流程
比较所有模型
# Comparing all the models models = pd.DataFrame({ 'Model': [ 'Ridge Regression', 'Lasso Regression','Decision Tree Regressor'], 'Score': [ ridge_score, lasso_score, decision_score], 'Test Score': [ ridge_score_test, lasso_score_test, decision_score_test]}) models.sort_values(by='Test Score', ascending=False)
通过比较所有模型,我们可以得出结论,决策树回归和随机森林回归表现最好。
结论
正如我们所看到的,我们已经完成了一个整个模型开发流程,包括数据洞察、特征工程和数据可视化、用机器学习模型制作步骤进行预测等。当然你也可以用更复杂的模型来做,文章涉及的数据,我也会提供给大家。
代码、数据获取
整个项目包含数据和代码
Github:https://github.com/Aman-Preet-Singh-Gulati/flight-fare-prediction
Be First to Comment