开始日期: 2024.07.26
学习目标: 深入理解Agent-Based Modeling(ABM)的基本原理、构建方法、应用领域以及其在复杂系统研究中的价值。
Agent-Based Modeling是一种通过模拟系统中具有自主性和交互能力的个体代理(Agent)来研究和预测复杂系统整体行为的方法。
代理(Agent)
自主性:代理能够根据自己的内部状态和外部环境做出决策。
感知能力:代理能够感知周围环境中的信息,如其他代理的位置、状态等。
决策能力:基于感知到的信息和预设的规则或策略,代理能够做出决策并执行相应的动作。
交互性:代理之间可以通过直接或间接的方式相互通信和互动。
项目实施
背景:
电力现货市场是一个短时间内的电能量交易市场,通过市场机制实现电力资源的优化配置。市场中的发电机组(供给者)在指定平台上进行集中竞价,确定电能的交易量和价格。本项目的目标是通过Agent-Based Modeling (ABM) 方法,模拟549个发电机组在报价上的博弈行为,以预测2023年7月1日至2024年4月18日的市场出清价格。
目标:
构建一个基于ABM的电力现货市场模拟系统。
准确模拟发电机组之间的报价博弈行为。
预测指定时间段内的市场出清价格,并最小化MSE和RMSE。
数据准备
数据集:
electricity_price.csv:包含市场出清价格、市场需求等信息,用于训练和测试模型。
unit.csv:包含发电机组的参数信息,如额定容量、运行小时数、煤炭消耗等。
首先,进行数据预处理
base_path = Path("data") # 确保数据都放在同级的data目录下
# 读取市场数据
electricity_price = pd.read_csv(base_path / "electricity price.csv")
# 读取市场主体(各发电机组)数据
unit = pd.read_csv(base_path / "unit.csv")
"""
准备示例提交数据sample_submit
1. electricity_price["clearing price (CNY/MWh)"].isna()找到出清价格为缺失值的行,即要预测的目标
2. 去除demand列,符合最后的提交格式
"""
sample_submit = electricity_price[electricity_price["clearing price (CNY/MWh)"].isna()].drop(columns="demand")
sample_submit.to_csv(base_path / "sample_submit.csv", index=False)
# 将day和time列合并成timestamp列,便于提取时间戳特征
electricity_price["timestamp"] = pd.to_datetime(
electricity_price["day"] + " " + electricity_price["time"].str.replace("24:00:00", "00:00"))
# 处理24:00:00的情况,即表示第二天的00:00:00
mask = electricity_price['timestamp'].dt.time == pd.Timestamp('00:00:00').time()
# 需要将这些行的日期部分加一天
electricity_price.loc[mask, 'timestamp'] += pd.Timedelta(days=1)
# 设置列的顺序,同时去除day和time列
electricity_price = electricity_price[["timestamp", "demand", "clearing price (CNY/MWh)"]]
接着,使用ABM估计市场出清价格
Agent-Based Modeling (ABM) 是一种模拟系统的复杂行为和动态的计算方法。它通过定义系统中的个体(称为“代理(Agent)”)及其相互作用规则来进行建模。每个代理具有独特的属性和行为。ABM 模型通过模拟代理之间的互动,观察宏观层面的模式和现象,帮助理解复杂系统的行为和演化。
sorted_unit = unit.sort_values("coal consumption (g coal/KWh)") # 按照一度电的耗煤量(近似为边际成本)降序排序
sorted_unit.head()
# 预先计算 sorted_unit 的累积和
sorted_unit['cumulative_capacity'] = sorted_unit['Capacity(MW)'].cumsum()
prices = []
# 找到最后一个满足总需求的机组报价
for demand in electricity_price["demand"]:
price = sorted_unit[sorted_unit['cumulative_capacity'] >= demand]["coal consumption (g coal/KWh)"].iloc[0]
prices.append(price)
print(len(prices))
prices[:5]
转换耗煤量为机组报价
model = LinearRegression()
# 55392为训练集的长度
train_length = 55392
prices = np.array(prices).reshape(-1, 1)
X = prices[:train_length]
y = electricity_price["clearing price (CNY/MWh)"].iloc[:train_length].values.reshape(-1, 1)
model.fit(X, y)
使用边际成本定价的机组报价为出清价格估计
y_pred = model.predict(prices[train_length:])
y_pred = y_pred.flatten() # 2维矩阵转为1维
y_pred[:5]
最后保存结果
sample_submit["clearing price (CNY/MWh)"] = y_pred
sample_submit.head()
sample_submit.to_csv("submit.csv", index=False)