第十周周四
在搞数学建模竞赛,用python完成了数据分析。
1 import os 2 import pandas as pd 3 from sklearn.model_selection import train_test_split 4 from sklearn.linear_model import LinearRegression 5 from sklearn.metrics import mean_squared_error, r2_score 6 import numpy as np 7 import plotly.graph_objs as go 8 from concurrent.futures import ProcessPoolExecutor 9 from multiprocessing import freeze_support 10 from statsmodels.tsa.statespace.sarimax import SARIMAX 11 from datetime import datetime, timedelta 12 13 # 定义函数读取单个文件的数据 14 def read_file(file_path): 15 return pd.read_csv(file_path, encoding='utf-8', delimiter=",") 16 17 def main(): 18 # 定义第一个文件夹路径 19 folder_path_1 = r"C:\Users\86155\Desktop\建模竞赛\2024校赛题目\2024校赛题目--C\附件2:2014年01月-2024年03月全国主要城市空气质量数据\all\all1" 20 21 # 初始化一个空 DataFrame 22 all_data_1 = pd.DataFrame() 23 24 # 定义并行处理的进程数 25 num_processes = os.cpu_count() # 使用CPU核心数作为进程数 26 i = 0 27 # 使用进程池并行读取所有文件的数据 28 with ProcessPoolExecutor(max_workers=num_processes) as executor: 29 # 提交所有文件读取任务 30 futures = [executor.submit(read_file, os.path.join(folder_path_1, file_name)) for file_name in 31 os.listdir(folder_path_1) if file_name.endswith(".csv")] 32 33 # 获取所有任务的结果 34 for future in futures: 35 i += 1 36 print(i) 37 data = future.result() 38 all_data_1 = pd.concat([all_data_1, data], ignore_index=True) 39 40 # 对第一个文件数据进行清洗和预处理(这里假设无需清洗和预处理) 41 42 # 将日期列和小时列合并为日期时间类型 43 all_data_1['datetime'] = pd.to_datetime( 44 all_data_1['date'].astype(str) + ' ' + all_data_1['hour'].astype(str).str.zfill(2), format='%Y%m%d %H') 45 # 删除原始的日期和小时列 46 all_data_1.drop(columns=['date', 'hour'], inplace=True) 47 48 # 用副本解决 'SettingWithCopyWarning' 问题 49 shijiazhuang_data = all_data_1[['datetime', '石家庄', 'type']].copy() 50 51 # 将日期设置为索引 52 shijiazhuang_data.set_index('datetime', inplace=True) 53 54 # 提取AQI指数的数据 55 aqi_data = shijiazhuang_data[shijiazhuang_data['type'] == 'AQI'] 56 57 # 定义第二个文件路径 58 file_path_2 = r"C:\Users\86155\Desktop\建模竞赛\2024校赛题目\2024校赛题目--C\附件1:2014年01月-2024年02月石家庄天气数据.xlsx" 59 60 # 读取第二个文件的数据 61 weather_factors = pd.read_excel(file_path_2) 62 if weather_factors.empty: 63 print("文件未打开") 64 65 # 将日期列和小时列合并为日期时间类型 66 weather_factors['datetime'] = pd.to_datetime(weather_factors['年'].astype(str) + '-' + 67 weather_factors['月'].astype(str).str.zfill(2) + '-' + 68 weather_factors['日'].astype(str).str.zfill(2) + ' ' + 69 weather_factors['时'].astype(str).str.zfill(2) + ':00') 70 # 将缺失数据(9999)替换为 NaN 71 weather_factors.replace(9999, pd.NA, inplace=True) 72 73 # 合并两个数据集 74 merged_data = pd.merge(aqi_data, weather_factors, on='datetime') 75 76 # 划分特征和目标变量 77 X = merged_data[['气温(因子10)℃', '露点温度(因子10)℃', '海平面气压(因子10)Pa', '风向(由北顺时针)°', 78 '风速(因子10)m/s', '天空状况总覆盖代码', '液体沉积深度(因子10,周期6小时)mm']] 79 y = merged_data['石家庄'] 80 81 # 确保在划分训练集和测试集之前用平均值填充NaN 82 X.fillna(X.mean(), inplace=True) 83 y.fillna(y.mean(), inplace=True) 84 85 # 划分训练集和测试集 86 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) 87 88 # 建立线性回归模型 89 model = LinearRegression() 90 91 # 在划分和训练模型之前解决 'Input contains NaN, infinity or a value too large for dtype' 问题 92 X_train.fillna(X_train.mean(), inplace=True) 93 y_train.fillna(y_train.mean(), inplace=True) 94 X_train = X_train.astype(float).fillna(5) 95 y_train = y_train.astype(float).fillna(5) 96 # 在处理过的训练集上训练模型 97 model.fit(X_train, y_train) 98 99 # 获取特征的系数 100 feature_coef = pd.Series(model.coef_, index=X.columns).abs().sort_values(ascending=False) 101 102 # 打印出对 AQI 影响最大的因素 103 print("对 AQI 影响最大的因素:", feature_coef.index[0]) 104 105 X_test = X_test.astype(float).fillna(5) 106 # 在测试集上进行预测 107 y_pred = model.predict(X_test) 108 109 # 计算均方误差 110 mse = mean_squared_error(y_test, y_pred) 111 print("均方误差:", mse) 112 113 # 计算均方根误差(RMSE) 114 rmse = np.sqrt(mse) 115 print("均方根误差(RMSE):", rmse) 116 117 # 计算决定系数(R^2) 118 r2 = r2_score(y_test, y_pred) 119 print("决定系数(R^2):", r2) 120 121 # 创建交互式图表 122 fig = go.Figure() 123 124 # 添加原始数据曲线 125 fig.add_trace(go.Scatter(x=merged_data['datetime'], y=merged_data['石家庄'], mode='lines', name='石家庄原始AQI数据')) 126 127 # 处理预测特征集前的缺失值 128 weather_factors.fillna(method='ffill', inplace=True) # 以前向填充方式处理缺失值 129 130 # 确保特征匹配(假设这些是训练模型时使用的特征) 131 selected_features = ['气温(因子10)℃', '露点温度(因子10)℃', '海平面气压(因子10)Pa', 132 '风向(由北顺时针)°', '风速(因子10)m/s', '天空状况总覆盖代码', 133 '液体沉积深度(因子10,周期6小时)mm'] 134 weather_factors_for_prediction = weather_factors[selected_features] 135 136 # 再次确认无 NaN 或 NA 137 weather_factors_for_prediction.fillna(weather_factors_for_prediction.mean(), inplace=True) 138 139 # 添加预测AQI指数曲线 140 # SARIMA模型预测 141 train = merged_data[['datetime', '石家庄']].copy() # 使用历史AQI数据作为时间序列 142 train.set_index('datetime', inplace=True) 143 order = (1, 1, 1) # ARIMA模型的阶数 144 seasonal_order = (1, 1, 1, 12) # 季节性阶数 145 model_sarima = SARIMAX(train, order=order, seasonal_order=seasonal_order, enforce_stationarity=False, enforce_invertibility=False) 146 results_sarima = model_sarima.fit() 147 148 149 # 定义当前日期为2024年3月1日 150 current_date = pd.to_datetime('2024-03-01') 151 152 # 计算未来两三个月后的日期 153 future_date = current_date + pd.DateOffset(months=3) # 或者 pd.DateOffset(months=3) 如果是未来三个月 154 155 # 将日期转换为字符串形式 156 end_date_str = future_date.strftime('%Y-%m-%d') 157 158 # 将字符串日期转换为 pandas 的 datetime 格式 159 end_date = pd.to_datetime(end_date_str) 160 161 print(len(train)) 162 163 forecast = results_sarima.predict(start='2024-03-01', end='2024-06-30', dynamic=False) # 预测未来60天,每天24个小时 164 fig.add_trace(go.Scatter(x=forecast.index, y=forecast, mode='lines', name='石家庄预测AQI数据')) 165 166 # 为每个特征创建曲线并添加到图表中 167 for feature in selected_features: 168 # 获取特征的预测值 169 feature_pred = model.predict(weather_factors_for_prediction) 170 fig.add_trace(go.Scatter(x=merged_data['datetime'], y=merged_data[feature], mode='lines', name=feature + '_原始值', xaxis='x1')) 171 fig.add_trace(go.Scatter(x=merged_data['datetime'], y=feature_pred, mode='lines', name=feature + '_预测值', xaxis='x1')) 172 173 # 设置图表布局 174 fig.update_layout( 175 title='石家庄AQI指数预测', 176 xaxis_title='日期', 177 yaxis_title='AQI指数' 178 ) 179 180 # 显示图表 181 fig.show() 182 183 184 if __name__ == '__main__': 185 freeze_support() 186 main()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)