机器学习·学习笔记---电力需求预测挑战赛

比赛详细地址见:2024 iFLYTEK A.I.开发者大赛-讯飞开放平台 (xfyun.cn)


在参加本次比赛之前,我首先看到训练营提供的代码。思路很简单,就是选取dt<=20的所有数据求和取均值作为test数据集的target值,但是自我感觉效果并非很好,所以有了改进的想法。


训练营代码如下:

import pandas as pd
import numpy as np

# 读取训练集和测试集
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

# 计算11-20的dt内每个id的target均值
target_mean = train[train['dt']<=20].groupby(['id'])['target'].mean().reset_index()

# 合并结果
test = test.merge(target_mean, on=['id'], how='left')

# 保存结果
test[['id','dt','target']].to_csv('submit.csv', index=None)

然后到比赛页面提交

自我感觉还是有一定提升空间的,于是开始对数据进行分析,看看可以咋搞

对数据的id和type进行分组,画图,发现有这样的关系(这里以type0为例):

咱就是说,如果只是简单的取均值的话,效果确实不太好,然后就打算用用自己最近学到的知识来解决,也就是线性回归,话不多说,直接上代码

# 导入必要的库,其中IPython库用来大致且方便地显示模型训练的过程
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from IPython.display import clear_output  

# 读取训练集和测试集
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
# 针对不同的type和id单独进行训练
cnt = 0
test['target'] = np.nan
for name, data in train.groupby('type'):
    for group_name, group_data in train[train['type'] == name].groupby('id'):
        
        # 对每个type下不同的id分别训练线性回归模型
        model = LinearRegression()
        model.fit(group_data['dt'].values.reshape(-1, 1), group_data['target'])
        

        # 将预测结果合并到测试集
        test.loc[(test['id'] == group_name) & (test['type'] == name), 'target'] = model.predict(test[(test['id'] == group_name) & (test['type'] == name)]['dt'].values.reshape(-1, 1))

        # 打印训练日志
        cnt += 1
        clear_output()
        print(f'第{cnt}次')
print('Done')

# 存储结果
test[['id', 'dt', 'target']].to_csv('submit.csv', index=None)

# 查看预测结果
test

 其实主要就是导入相关的库然后直接放入参数即可,没啥好说的,但是考虑的很少,忽略了数据预处理的步骤,所以最后的结果也不是很可观。

但是主要目的在于学习,在提出想法到实现自己的想法的过程中,自己能熟悉很多以往陌生的操作,并且能根据这些操作派生出很多自己独特的想法。

这里附上提交结果

发现或许分数不会特别大,但是或多或少也接近一开始的结果了,然后将预测好的数据和训练集数据进行比对,发现还是有一定出入的(以type0为例):

这里其实看不出啥来,而且id为007d45c89d的这个图像拟合地也还不错,但是考虑到图像高低不平的特性,打算试试梯度下降法的多项式回归

直接上代码

# 还是一样,先导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from scipy import stats
from IPython.display import clear_output  

# 读取训练集和测试集
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

# 针对不同的type和id单独进行训练
cnt = 0
test['target'] = np.nan
for name, data in train.groupby('type'):
    for group_name, group_data in train[train['type'] == name].groupby('id'):

        # 提取数据,方便后续进行操作
        train_x = group_data['dt'].values
        train_y = group_data['target'].values
        mu = train_x.mean()
        sigma = train_x.std()
        train_z = (train_x - mu) / sigma
        theta = np.random.rand(3)
        
        # 将标准化的数据转化为矩阵
        def to_matrix(x):
            return np.vstack([np.ones(x.shape[0]), x, x ** 2]).T
        X  = to_matrix(train_z)
        
        # 定义函数和误差函数
        def f(x):
            return np.dot(x, theta)
        def E(x, y):
            return 0.5 * np.sum((y - f(x)) ** 2)

        # 开始训练模型
        diff = 1
        error = E(X, train_y)
        ETA = 1e-3
        while diff > 1e-2:
            theta = theta - ETA * np.dot(f(X) - train_y, X)
            current_error = E(X, train_y)
            diff = error - current_error
            error = current_error
        # 使用训练好的 theta 进行预测  
        test_x = test[(test['id'] == group_name) & (test['type'] == name)]['dt'].values  
        test_x_scaled = (test_x - mu) / sigma
        test_X = to_matrix(test_x_scaled)  
        predicted_y = np.dot(test_X, theta)  
          
        # 更新 test DataFrame  
        test.loc[(test['id'] == group_name) & (test['type'] == name), 'target'] = predicted_y
        
        cnt += 1
        clear_output()
        print(f'第{cnt}次')
print('Done')

# 预测test数据,得出结论
test[['id', 'dt', 'target']].to_csv('submit.csv', index=None)

# 查看预测结果
test

代码看上去有些乱,不过最后还是整出来了,可能图像上差别不大,但是提交结果还是有进步的,最重要的是能够将自己学到的知识活用到这里来了,自我感觉不错了,后续如果有其它的思路,也会去尝试。

下面展示提交结果~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值