随机森林算法
什么是中转航班?
1.中转旅客:在旅行过程中,需要在某个或多个中转站点暂时停留,换乘其他交通工具的旅客。
2.中转航班:指旅客需要换乘其他航班才能到达目的地的过程。
3.中转站:指在运输过程中,用于暂时停留和换乘的站点。
a. 比如张三,假期在吉祥航空买了从北京飞往上海的票,但是发现没有直达上海的票,需要先到武汉再到上海,在票面上来看虽然本次旅程到了武汉,但是票号只会出现一次,也就是票A,对应的航段为 北京-武汉-上海。我们成为中转旅客。
b. 再比如张三,假期在买了从北京到上海的往返票,但是票号却是一个,虽然往返票的起飞日期不一样,但这次旅程仍然属于中转航程。
c. 中转的站不限制次数,可以无限制的累积比如张三的票是A-B-C-D-E等等,可以无限中转换站。
如何赋能中转?
先看一篇文章,聚焦智慧民航 | 智慧赋能中转衔接:时间短一点,速度快一点|旅客|机场|值机|航季航班计划_网易订阅 (163.com)
好了,到底和算法和这玩意啥关系?💁
简单一点,就是利用算法的分析预测来辅助决策。
痛点
- 目前中转旅客的等待决策较为一刀切,主要以中转旅客人数作为一个判断依据,决策维度较为单一不够全面(扩充一些纬度)
- 总值班人数较多,每个人都有自己的价值取向,决策的价值标准比较难以统一,没有一个相对参考
数据导入
- 由业务部门提供尽可能全面的决策评估维度
- 建立多决策维度下的决策案例库,供模型搭建
- 通过模型计算和分析不同的决策结果,为决策者提供出中转旅客是否等待的决策建议
决策状态
- 已搁置:给出决策建议但忽略延后处理
- 已经忽略:给出决策建议但忽略
- 待处理:给出决策建议但等待处理
- 无需处理:给出决策建议
- 已处理:给出决策建议已处理
决策算法
# -*- coding: utf-8 -*-
# @Time : 2024/5/24 3:31 下午
# @Author : Hoey
import json
import os
import pickle
import sys
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from argparse import ArgumentParser
def parse_arguments():
parser = ArgumentParser()
parser.add_argument('json_str', help='json字符串')
return parser.parse_args()
def save_model(model_path, model):
with open(model_path, 'wb') as file:
pickle.dump(model, file)
def get_model(model_path):
loaded_model = None
if os.path.exists(model_path):
with open(model_path, 'rb') as file:
loaded_model = pickle.load(file)
return loaded_model
def read_excel_data_by_pd(file_path: str, sheet_name: str):
return pd.read_excel(file_path, sheet_name=sheet_name, header=0, engine='xlrd')
def model(model_path):
if os.path.exists(model_path):
print("模型已存在")
return get_model(model_path)
else:
print("模型不存在,开始初始化模型..")
return RandomForestClassifierWrapper(model_path = model_path, random_state=100)
class RandomForestClassifierWrapper:
def __init__(self, model_path:str, random_state: int = 100):
self.base_train_data = './assert/决策样本数据.xls'
# 定义参数网格
self.param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, 15, 20, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
self.rf_clf = RandomForestClassifier(random_state=random_state)
self.best_rf_clf = None
self.scaler = StandardScaler()
self.init(model_path)
def init(self, model_path):
x, y = self.load_training_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=300)
self.train(x_train, y_train, self.param_grid)
# 在测试集上评估模型性能
score = accuracy_score(y_test, self.predict(x_test))
print("模型在测试集上的评分:", score)
if score > 0.9:
save_model(model_path, self)
def load_training_data(self):
df = read_excel_data_by_pd(self.base_train_data, sheet_name='Sheet1')
x = df.iloc[:, 0:7]
y = df.iloc[:, -1]
return x, y
def train(self, x_train, y_train, param_grid):
X_train_scaled = self.scaler.fit_transform(x_train)
grid_search = GridSearchCV(estimator=self.rf_clf, param_grid=param_grid, cv=5)
grid_search.fit(X_train_scaled, y_train)
self.best_rf_clf = grid_search.best_estimator_
def predict(self, x):
x_scaled = self.scaler.transform(x)
return self.best_rf_clf.predict(x_scaled)
def predict_proba(self, x):
x_scaled = self.scaler.transform(x)
return self.best_rf_clf.predict_proba(x_scaled)
def __test():
rf_model = model()
x_np = np.array([[35, 294000, 7000, 65, 5, 3, 423]])
predict_realdata_dis = rf_model.predict_proba(x_np)
print("预测样本为某个标签的概率:\n", predict_realdata_dis)
predict_realdata = rf_model.predict(x_np)
print("预测样本为某个标签的概率:\n", predict_realdata)
if __name__ == '__main__':
try:
# pkl_file = sys.argv[1]
model_path = "./rf.pkl"
# json_str = sys.argv[2]
json_str = """
[{
"transferNumber": 35,
"transferIncome": 294000,
"transferCost": 7000,
"estimateDelayTime": 65,
"delayFlightNumber": 5,
"flightType": 3,
"waitAffectsNumber": 423
}]"""
print(json_str)
if not json_str:
raise Exception('无效的json_str')
except Exception as e:
print("请输入json_str")
exit(1)
json_data = json.loads(json_str)
data_list = [list(item.values()) for item in json_data]
x_np = np.array(data_list)
rf_model = model(model_path)
predict_realdata_dis = rf_model.predict_proba(x_np)
print("预测样本为某个标签的概率:\n", predict_realdata_dis)
predict_realdata = rf_model.predict(x_np)
print("预测样本为某个标签的概率:\n", predict_realdata)