diff --git a/Test/energy-prediction.py b/Test/energy-prediction.py index 52dcaa0..247116c 100644 --- a/Test/energy-prediction.py +++ b/Test/energy-prediction.py @@ -2,15 +2,15 @@ import requests import zipfile import os import pandas as pd -from sklearn.model_selection import train_test_split, cross_val_score +from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error -from sklearn.preprocessing import StandardScaler, LabelEncoder +from sklearn.preprocessing import LabelEncoder import matplotlib.pyplot as plt import matplotlib +from sklearn.linear_model import LinearRegression import numpy as np - def main(): # 设置支持中文的字体(例如:SimHei 字体) matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 或使用 'Microsoft YaHei' @@ -53,85 +53,78 @@ def main(): generation_columns = ['generation_gwh_2013', 'generation_gwh_2014', 'generation_gwh_2015', 'generation_gwh_2016', 'generation_gwh_2017'] - # 确保所有发电量列都存在 - missing_cols = [col for col in generation_columns if col not in data.columns] - if missing_cols: - print(f"警告: 缺少以下列: {', '.join(missing_cols)}") - return - # 聚合不同年份的发电数据 data['total_generation'] = data[generation_columns].sum(axis=1) - # 清理数据,移除异常值 - data = data[(data['capacity_mw'] > 0) & (data['capacity_mw'] < 5000)] # 假设容量过大或过小的数据无效 - data = data[data['total_generation'] >= 0] # 确保发电量是正数 - - # 再次检查数据的统计信息 - print(data.describe()) - # 选择特征(X)和目标变量(y) - X = data[['capacity_mw', 'latitude', 'longitude', 'primary_fuel', 'total_generation']] + X = data[['capacity_mw', 'latitude', 'longitude', 'primary_fuel', 'total_generation']] # 示例特征 y = data['generation_gwh_2017'] # 预测目标:2017年的发电量 # 将数据分割为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - # 特征标准化 - scaler = StandardScaler() - X_train_scaled = scaler.fit_transform(X_train) - X_test_scaled = scaler.transform(X_test) - # 初始化并训练随机森林回归模型 model = RandomForestRegressor(n_estimators=100, random_state=42) - model.fit(X_train_scaled, y_train) + model.fit(X_train, y_train) # 在测试集上进行预测 - y_pred = model.predict(X_test_scaled) + y_pred = model.predict(X_test) # 评估模型 mse = mean_squared_error(y_test, y_pred) rmse = mse ** 0.5 print(f"均方根误差(RMSE):{rmse}") - # 可视化预测值与实际值,使用不同颜色标记 - plt.scatter(y_test, y_pred, color='blue', label='预测发电量', alpha=0.6) - plt.scatter(y_test, y_test, color='red', label='实际发电量', alpha=0.6) + # 绘制预测值与实际值的对比图(预测值为 y 轴,实际值为 x 轴) + plt.figure(figsize=(10, 6)) + plt.scatter(y_test, y_pred, color='blue', alpha=0.6) + plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--') plt.xlabel('实际发电量 (GWh)') plt.ylabel('预测发电量 (GWh)') - plt.title('实际 vs 预测发电量') - plt.legend() - plt.show() - - # 交叉验证(例如使用10折交叉验证) - cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=10, scoring='neg_mean_squared_error') - - # 检查是否存在 NaN 值 - if np.any(np.isnan(cv_scores)): - print("警告: 交叉验证中发现 NaN 值,可能由数据问题导致。") - - # 输出交叉验证的每折得分(RMSE) - print("交叉验证的每折结果(负均方误差):") - for i, score in enumerate(cv_scores, 1): - if np.isnan(score): - print(f"折 {i}: 无效得分") - else: - print(f"score: {score}") - print(f"折 {i}: {(-score) ** 0.5:.4f} RMSE") - - # 输出交叉验证的平均RMSE - mean_rmse = (-cv_scores.mean()) ** 0.5 - print(f"交叉验证的平均RMSE:{mean_rmse:.4f}") - - # 可视化交叉验证结果 - plt.figure(figsize=(8, 6)) - plt.plot(range(1, 11), -cv_scores, marker='o', label='每折负均方误差') - plt.xlabel('折数') - plt.ylabel('负均方误差') - plt.title('交叉验证结果(每折负均方误差)') - plt.xticks(range(1, 11)) - plt.legend() + plt.title('实际发电量与预测发电量对比') plt.grid(True) plt.show() + # 使用线性回归预测未来30年的增长趋势 + years = [2013, 2014, 2015, 2016, 2017] # 使用已有的年份 + generation_values = data[generation_columns].mean(axis=0) # 使用这些年份的平均发电量 + + # 创建一个线性回归模型来拟合这些数据 + linear_regressor = LinearRegression() + linear_regressor.fit(np.array(years).reshape(-1, 1), generation_values) + + # 预测未来30年的发电量 + future_years = list(range(2018, 2018 + 30)) + future_generation = linear_regressor.predict(np.array(future_years).reshape(-1, 1)) + + # 输出未来30年的预测发电量 + print("未来30年发电量预测(单位:GWh):") + for i, generation in enumerate(future_generation): + print(f"第 {i+1} 年 ({future_years[i]}): {generation:.2f} GWh") + + # 获取2013到2017年已知的发电量数据 + known_generation = data[generation_columns].mean(axis=0) + + # 合并已知发电量数据和未来30年预测的发电量 + all_years = years + future_years + all_generation = list(known_generation) + list(future_generation) + + # 可视化年份和发电量的增长趋势(已知数据和预测数据) + plt.figure(figsize=(10, 6)) + + # 绘制已知数据的发电量趋势(2013-2017年,用绿色标色) + plt.plot(years, known_generation, marker='o', color='green', label='已知发电量 (2013-2017)', linestyle='-', markersize=8) + + # 绘制未来预测数据的发电量趋势(2018-2047年,用蓝色标色) + plt.plot(future_years, future_generation, marker='o', color='blue', label='预测发电量 (2018-2047)', linestyle='-', markersize=8) + + plt.xlabel('年份') + plt.ylabel('发电量 (GWh)') + plt.title('2013-2047年发电量增长趋势(已知数据和预测数据)') + plt.grid(True) + plt.legend() + plt.show() + + if __name__ == "__main__": main()