2024年认证杯国际赛小美赛D题详细思路+问题一二初步代码分享

资料为初步问题一二解题代码,仅供参考,如有不同意见或更好思路欢迎指正

分享资料链接

https://pan.baidu.com/s/1g5fBwXRy5nsgbjZwKyhimg

提取码:i3kc

问题 D(ICM)风能与太阳能电厂 详细解题思路

任务:提供的数据集包括一个月的来自12个风力发电机组和11个太阳能电站的发电数据。目标是开发一个有效的数学模型来解决以下任务:

任务1: 分析风电场和太阳能电场的发电波动模式

应在总发电量出现显著下降(至少提前5分钟)或显著上升(至少提前2分钟)时进行预测。设当前时刻的发电量为 p,过去30分钟的平均发电量为 q。波动幅度通过 k = |p − q|/q 来衡量。当 k 超过指定阈值 t 时,定义为显著下降或上升。你可以选择阈值 t,目标是使 t 尽可能小,同时提高预测的准确性。
步骤1.1: 数据预处理与波动计算

·首先对题目给出数据进行必要处理,并按时间戳对数据进行排序,确保数据是按正确的时间顺序排列。

例如,可以对给出的位置经纬度绘制可视化结果,也可以对给出数据进行必要描述性分析。

图片

图片

图片

步骤1.2: 确定显著波动阈值

·根据题意,当  超过某个阈值  时,认为发生了"显著的波动",可以是显著下降或显著上升。需要根据历史数据选择合适的阈值  。

·可以通过分析过去数据中  的分布情况(例如,通过直方图或统计分析)来选择阈值。一般来说,  的值不应过大,否则可能会错过一些实际的波动。

·选择合适的闻值  后,你可以识别出那些显萆的波动事件(即,波动幅度大于  的时刻)。


# 4. 计算过去30分钟的平均发电量并计算波动幅度
window_size = 30  # 过去30分钟的窗口

# 计算每个传感器的滚动平均值(过去30分钟的平均发电量)
for sensor in ['sensor_1', 'sensor_2', 'sensor_4', 'sensor_5', 'sensor_6']:  # 可以根据实际情况调整传感器列表
    data[f'{sensor}_rolling_avg'] = data[sensor].rolling(window=window_size).mean()

# 计算波动幅度
t = 0.5  # 设置波动幅度阈值t,默认设为0.2,表示波动幅度超过20%时认为是显著波动
for sensor in ['sensor_1', 'sensor_2', 'sensor_4', 'sensor_5', 'sensor_6']:
    # 计算当前时刻的波动幅度
    data[f'{sensor}_fluctuation'] = abs(data[sensor] - data[f'{sensor}_rolling_avg']) / data[f'{sensor}_rolling_avg']

    # 标记显著波动
    data[f'{sensor}_significant_change'] = np.where(data[f'{sensor}_fluctuation'] > t, 1, 0)  # 1代表显著波动,0代表没有显著波动

图片

步骤1.3:波动预测

·你需要对即将发生的显著波动进行预测。具体来说,在波动发生前(例如,显著下降至少5分钟,显著上升至少 2 分钟),你需要预测到这一变化。

·你可以选择不同的预测方法,例如:

·滑动平均法:基于历史数据(例如,过去几分钟的功率数据)来预测未来的功率变化。

·时间序列分析:使用ARIMA、LSTM等模型来预测功率变化。

·回归模型:例如多项式回归、支持向量回归等,根据历史数据拟合预测模型。

步骤1.4:精度与阈值选择

·对不同阈值  和预测方法进行实验,评估模型的精度。你可以计算准确率、召回率、F1-score等评价指标来评估预测性能。

·准确率:预测的波动事件与真实波动事件匹配的比例。

·召回率:真实发生波动事件中被正确预测的比例。

·F1-score: 综合考虑准确率和召回率的平衡。

任务2: 进行短期发电量预测
步骤2.1:确定预测目标

·你需要分别对未来1到120秒的发电量进行预测。

·因为数据的采样频率是 1 Hz ,意味着你有 1 秒钟间隔的数据。目标是基于当前时刻的功率数据,预测未来1秒到120秒的发电量变化。

步骤2.2: 选择预测模型

·传统时间序列方法:例如ARIMA、SARIMA等,适合于有季节性或趋势性的时间序列数据。

·机器学习模型:例如随机森林、XGBoost等,可以通过构造特征(如历史功率数据、时间等)来进行预测。

·深度学习模型:例如LSTM(长短时记忆网络),适用于具有时序性质的数据,能够捕捉到长期的时间依赖关系。

这里为了方便展示,我们仅仅以问题一线性回归为例进行预测展示,后续会进一步选择高精度模型。

图片

import geopandas as gpd
import matplotlib.pyplot as plt
from shapely.geometry import Point

# 经纬度数据
coordinates = {
    'sensor_1': (53.1532754254192, 8.16414535045624),
    'sensor_2': (53.1530566746515, 8.16568493843079),
    'sensor_4': (53.152976251295, 8.16516995429993),
    'sensor_5': (53.1527414142317, 8.16302955150604),
    'sensor_6': (53.152487274045, 8.1664627790451),
    'sensor_7': (53.1525001419387, 8.16336214542389),
    'sensor_8': (53.1524293684755, 8.16433310508728),
    'sensor_9': (53.1523843307564, 8.16504120826721),
    'sensor_10': (53.1523135571024, 8.16601753234863),
    'sensor_11': (53.1520787164146, 8.16337823867798),
    'sensor_13': (53.1520465463573, 8.16548109054565)
}

# 提取所有的经纬度
latitudes = [lat for lat, lon in coordinates.values()]
longitudes = [lon for lat, lon in coordinates.values()]

# 计算经纬度范围
min_lat = min(latitudes)
max_lat = max(latitudes)
min_lon = min(longitudes)
max_lon = max(longitudes)

# 创建一个GeoDataFrame
points = [Point(lon, lat) for lat, lon in coordinates.values()]
gdf = gpd.GeoDataFrame(geometry=points)

# 获取地图数据
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

# 创建绘图
fig, ax = plt.subplots(figsize=(10, 10))

# 绘制背景地图
world.plot(ax=ax, color='lightgray')

# 绘制传感器位置
gdf.plot(ax=ax, color='red', markersize=50, label='Sensors')

# 添加标签
for label, (lat, lon) in coordinates.items():
    ax.text(lon, lat, label, fontsize=9, ha='right', color='black')

# 设置地图显示的经纬度范围
ax.set_xlim(min_lon - 0.001, max_lon + 0.001)  # 适当扩展范围,避免点太靠边
ax.set_ylim(min_lat - 0.001, max_lat + 0.001)

# 设置标题
plt.title("Sensor Locations on the Map")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.legend()

# 显示地图
plt.show()
import folium

# 经纬度数据
coordinates = {
    'sensor_1': (53.1532754254192, 8.16414535045624),
    'sensor_2': (53.1530566746515, 8.16568493843079),
    'sensor_4': (53.152976251295, 8.16516995429993),
    'sensor_5': (53.1527414142317, 8.16302955150604),
    'sensor_6': (53.152487274045, 8.1664627790451),
    'sensor_7': (53.1525001419387, 8.16336214542389),
    'sensor_8': (53.1524293684755, 8.16433310508728),
    'sensor_9': (53.1523843307564, 8.16504120826721),
    'sensor_10': (53.1523135571024, 8.16601753234863),
    'sensor_11': (53.1520787164146, 8.16337823867798),
    'sensor_13': (53.1520465463573, 8.16548109054565)
}

# 创建地图对象,初始位置设为数据点的中心位置
m = folium.Map(location=[53.1525, 8.164], zoom_start=15, control_scale=True)

# 向地图中添加背景(OpenStreetMap或其他底图)
folium.TileLayer('openstreetmap').add_to(m)  # OpenStreetMap 背景
# 或者使用其他底图,比如:
# folium.TileLayer('Stamen Terrain').add_to(m)  # Stamen Terrain 背景
# folium.TileLayer('Stamen Toner').add_to(m)    # Stamen Toner 背景
# folium.TileLayer('CartoDB positron').add_to(m)  # CartoDB positron 背景

# 在地图上添加传感器点
for sensor, (lat, lon) in coordinates.items():
    folium.Marker([lat, lon], popup=sensor).add_to(m)

# 保存地图到HTML文件
m.save("sensors_map_with_background.html")

# 显示提示信息
print("地图已保存为 'sensors_map_with_background.html',打开该文件查看交互式地图。")
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# 读取数据
file_path = 'S1.txt'
data = pd.read_csv(file_path, sep='\s+', header=0,  # header=0 确保第一行被当作列名
                   dtype={'timestamp': 'float64'}, low_memory=False)

plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用SimHei字体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号

# 2. 确保时间戳列是数字并转换为 datetime 类型
data['timestamp'] = pd.to_datetime(data['timestamp'], unit='s', errors='coerce')

# 3. 描述性统计分析
desc_stats = data.describe()
print("描述性统计数据:")
print(desc_stats)

# 4. 时间序列图
plt.figure(figsize=(12, 6))
for sensor in data.columns[1:]:
    plt.plot(data['timestamp'], data[sensor], label=sensor)

plt.title('各传感器太阳辐照度时间序列图')
plt.xlabel('时间')
plt.ylabel('辐照度')
plt.legend(loc='upper right')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 5. 绘制辐照度分布直方图
plt.figure(figsize=(12, 6))
for sensor in data.columns[1:]:
    plt.hist(data[sensor], bins=30, alpha=0.5, label=sensor)

plt.title('各传感器辐照度分布直方图')
plt.xlabel('辐照度')
plt.ylabel('频率')
plt.legend(loc='upper right')
plt.tight_layout()
plt.show()

# 6. 绘制箱型图
plt.figure(figsize=(12, 6))
sns.boxplot(data=data.iloc[:, 1:], orient='vertical')
plt.title('各传感器辐照度分布箱型图')
plt.ylabel('辐照度')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 7. 波动性分析
# 计算每个传感器的平均值并计算波动性
for sensor in ['sensor_1', 'sensor_2', 'sensor_4', 'sensor_5', 'sensor_6']:  # 你可以根据实际情况调整传感器列表
    data[f'{sensor}_avg'] = data[sensor].mean()  # 计算每个传感器的平均值
    data[f'{sensor}_fluctuation'] = abs(data[sensor] - data[f'{sensor}_avg']) / data[f'{sensor}_avg']  # 计算波动性

# 8. 滚动窗口分析
window_size = 24  # 设置为24小时窗口大小,或者根据实际情况调整
for sensor in ['sensor_1', 'sensor_2', 'sensor_4', 'sensor_5', 'sensor_6']:  # 只分析部分传感器
    # 在这里计算滚动平均并命名为 `{sensor}_avg`
    data[f'{sensor}_rolling_avg'] = data[sensor].rolling(window=window_size).mean()
    # 计算滚动波动性
    data[f'{sensor}_rolling_fluctuation'] = abs(data[sensor] - data[f'{sensor}_rolling_avg']) / data[f'{sensor}_rolling_avg']

# 9. 绘制sensor_1波动幅度时间序列图
plt.figure(figsize=(12, 6))
plt.plot(data['timestamp'], data['sensor_1_fluctuation'], label='sensor_1 波动幅度', color='r')
plt.title('sensor_1 辐照度波动幅度')
plt.xlabel('时间')
plt.ylabel('波动幅度')
plt.xticks(rotation=45)
plt.tight_layout()
plt.legend()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值