鱼C论坛

 找回密码
 立即注册
查看: 25|回复: 5

stackingregression模型融合遇到问题

[复制链接]
发表于 昨天 21:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
from mlxtend.regressor import StackingRegressor
from sklearn.metrics import mean_squared_error

# 初始化基模型
models = [LR_model, dt_model, svm_model, rf_model,knn_model]

print('base model')
for model in models:
    model.fit(X_train, y_train)
    pred = model.predict(X_valid)
    print("loss is {}".format(mean_squared_error(y_valid, pred)))
sclf = StackingRegressor(regressors=models, meta_regressor=ridge)
# 训练回归器
sclf.fit(X_train, y_train)
pred = sclf.predict(X_valid)

print('stacking model')
print("loss is {}".format(mean_squared_error(y_valid, pred)))
plt.scatter(np.arange(len(pred)), pred)
plt.plot(np.arange(len(y_valid)), y_valid)
plt.show()
以上是模型融合的代码,以下是报错
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[35], line 12
     10     pred = model.predict(X_valid)
     11     print("loss is {}".format(mean_squared_error(y_valid, pred)))
---> 12 sclf = StackingRegressor(regressors=models, meta_regressor=ridge)
     13 # 训练回归器
     14 sclf.fit(X_train, y_train)

NameError: name 'ridge' is not defined
关于该模型的参数如何选择,翻遍外网也没找到meta_regressor是什么意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 昨天 21:32 | 显示全部楼层
您遇到的错误是因为变量 `ridge` 未定义。`meta_regressor` 是用于建立最后的评估模型的回归器,即融合不同基模型预测结果的回归器。可以使用常见的回归模型,比如 `Ridge`、`LinearRegression` 或其他你觉得合适的模型。

以下是如何定义 `ridge` 的示例代码:
from sklearn.linear_model import Ridge

# 定义meta_regressor
ridge = Ridge()

# 初始化基模型列表
models = [
    # 例如:
    # LinearRegression(), 
    # RandomForestRegressor(),
    # ...
]

# 之后的代码保持不变

选择 `meta_regressor` 时,可以尝试多种回归模型,看看哪个效果更好。一般来说,选择简单稳健的模型作为 `meta_regressor` 是一个不错的起点,如 `Ridge` 或 `LinearRegression`。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 22:04 | 显示全部楼层
FishC 发表于 2024-10-22 21:32
您遇到的错误是因为变量 `ridge` 未定义。`meta_regressor` 是用于建立最后的评估模型的回归器,即融合不同 ...
from mlxtend.regressor import StackingRegressor
from sklearn.metrics import mean_squared_error

# 初始化基模型
models = [LR_model, dt_model, svm_model, rf_model,knn_model,simple_dnn_model]

print('base model')
for model in models:
    model.fit(X_train, y_train)
    pred = model.predict(X_valid)
    print("loss is {}".format(mean_squared_error(y_valid, pred)))
sclf = StackingRegressor(regressors=models, meta_regressor=LinearRegression)
# 训练回归器
sclf.fit(X_train, y_train)
pred = sclf.predict(X_valid)

print('stacking model')
print("loss is {}".format(mean_squared_error(y_valid, pred)))
plt.scatter(np.arange(len(pred)), pred)
plt.plot(np.arange(len(y_valid)), y_valid)
plt.show()

上述代码提示报错未定义simplednnmodel,
--------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[43], line 5
      2 from sklearn.metrics import mean_squared_error
      4 # 初始化基模型
----> 5 models = [LR_model, dt_model, svm_model, rf_model,knn_model,simple_dnn_model]
      7 print('base model')
      8 for model in models:

NameError: name 'simple_dnn_model' is not defined
但是前面已经定义并执行了这个函数
#dnn模型(train_test_split)
import torch 
import torch.nn as nn
from torch.utils import data
from torch.utils.data import Dataset,DataLoader
from torch import optim

#定义神经网络模型
dropout1, dropout2 = 0.3, 0.6
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()  # 继承需要用 SimpleNN
        self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(12, 128),
            nn.ReLU(),  
            nn.Dropout(dropout1),
            nn.Linear(128, 256),
            nn.ReLU(),  
            nn.Dropout(dropout2),
            nn.Linear(256, 1),
        )
       
    def forward(self, X):
        x = self.dense(X)
        output = torch.sigmoid(x)
        return output

    
#初始化模型和优化器
simple_dnn_model = SimpleNN()
loss = nn.BCELoss() #定义损失函数
optimizer = optim.Adam(nn_model.parameters(),lr=0.0001) #定义优化器

#初始化列表
acc_list = []
loss_list = []



# 开始训练
batch_size = 99
num_epochs = 1000

    
#创建数据集
train_dataset = data.TensorDataset(X_train, y_train)
valid_dataset = data.TensorDataset(X_valid, y_valid)

# 获取一个数据迭代器
train_iter = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)#shuffle=True相当于sampler=RandomSampler(dataset)
valid_iter = DataLoader(dataset=valid_dataset,batch_size=batch_size,shuffle=True,num_workers=2)

#开始迭代
for epoch in range(num_epochs):
    train_loss = 0
    num_right = 0
    for tensor_x, tensor_y in train_iter:#训练集执行梯度更新
        tensor_x = tensor_x.float()
        tensor_y = tensor_y.float().reshape(-1, 1)
        optimizer.zero_grad() #梯度清零
        pre_train = simple_dnn_model(tensor_x)
        train_l = loss(pre_train, tensor_y) #损失应避免与全局变量loss重名
        train_l.backward()#前向传播
        optimizer.step()#梯度下降

        train_loss += train_l.item() * len(tensor_x)#批量损失
        result = [1 if out >= 0.5 else 0 for out in pre_train]
        num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

        train_loss = train_loss / len(train_iter.dataset)
        train_accuracy = num_right / len(train_iter.dataset)

    if epoch % 200 == 0:
        print('Loss: {} Accuracy: {} Epoch:{}'.format(train_loss, train_accuracy, epoch))

    with torch.no_grad():
        valid_loss = 0
        num_right = 0
        for tensor_x, tensor_y in valid_iter:
            tensor_x = tensor_x.float()
            tensor_y = tensor_y.float().reshape(-1, 1)
            pre_valid = simple_dnn_model(tensor_x)
            valid_l = loss(pre_valid, tensor_y)
            valid_loss += valid_l.item() * len(tensor_x)
            result = [1 if out >= 0.5 else 0 for out in pre_valid]
            num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

        valid_loss = valid_loss / len(valid_iter.dataset)
        valid_accuracy = num_right / len(valid_iter.dataset)

        if epoch % 200 == 0:
            print('Valid Loss: {} Accuracy: {} Epoch:{}'.format(valid_loss, valid_accuracy, epoch))

#将每次迭代的结果写入列表
loss_list.append(valid_loss)
acc_list.append(valid_accuracy)

print('Training Ended')
print('Average Loss: {} Average Accuracy: {}'.format(np.mean(loss_list), np.mean(acc_list)))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 22:04 | 显示全部楼层
Terence888 发表于 2024-10-22 22:04
from mlxtend.regressor import StackingRegressor
f ...


出现 `NameError`,可能是因为 `simple_dnn_model` 未包含在 `models` 列表中。确保 `models` 列表中包含初始化的模型。以下是一些改进建议:

1. **将模型加入列表:**
   在调用 `StackingRegressor` 之前,确保所有基模型都在 `models` 列表中。

from sklearn.linear_model import LinearRegression

   # 初始化基模型列表
   models = [simple_dnn_model, ...]  # 在列表中加入其他基模型

2. **导入和实例化 `meta_regressor`:**
   确保 `LinearRegression` 被正确导入和实例化:

from sklearn.linear_model import LinearRegression

   # 创建meta_regressor实例
   meta_regressor = LinearRegression()

3. **在 `StackingRegressor` 中使用 `meta_regressor` 实例:**

sclf = StackingRegressor(regressors=models, meta_regressor=meta_regressor)

4. **检查 `result` 变量的定义:**
   在验证和训练阶段,确保 `result` 有定义,以保存预测的结果。

result = (pre_train > 0.5).numpy()  # 对输出进行二值化处理

5. **确保数据的类型正确:**
   确保 `X_train` 和 `y_train` 是张量,并且类型正确。

如果你对这些步骤还有疑问,请提供更多上下文以便更好地帮助解决问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 22:42 | 显示全部楼层
FishC 发表于 2024-10-22 22:04
出现 `NameError`,可能是因为 `simple_dnn_model` 未包含在 `models` 列表中。确保 `models` 列表中包 ...
from mlxtend.regressor import StackingRegressor
from sklearn.metrics import mean_squared_error

# 初始化基模型
models = [LR_model, dt_model, svm_model, rf_model,knn_model,simple_dnn_model]

print('base model')
for model in models:
    model.fit(X_train, y_train)
    pred = model.predict(X_valid)
    print("loss is {}".format(mean_squared_error(y_valid, pred)))
sclf = StackingRegressor(regressors=models, meta_regressor=LR_model)
# 训练回归器
sclf.fit(X_train, y_train)
pred = sclf.predict(X_valid)

print('stacking model')
print("loss is {}".format(mean_squared_error(y_valid, pred)))
plt.scatter(np.arange(len(pred)), pred)
plt.plot(np.arange(len(y_valid)), y_valid)
plt.show()

提示错误
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[72], line 9
      7 print('base model')
      8 for model in models:
----> 9     model.fit(X_train, y_train)
     10     pred = model.predict(X_valid)
     11     print("loss is {}".format(mean_squared_error(y_valid, pred)))

File /opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py:1695, in Module.__getattr__(self, name)
   1693     if name in modules:
   1694         return modules[name]
-> 1695 raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")

AttributeError: 'SimpleNN' object has no attribute 'fit'

simple_nn_model是继承自module类自定义的类,
import torch 
import torch.nn as nn
from torch.utils import data
from torch.utils.data import Dataset,DataLoader
from torch import optim

#定义神经网络模型
dropout1, dropout2 = 0.3, 0.6
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()  # 继承需要用 SimpleNN
        self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(12, 128),
            nn.ReLU(),  
            nn.Dropout(dropout1),
            nn.Linear(128, 256),
            nn.ReLU(),  
            nn.Dropout(dropout2),
            nn.Linear(256, 1),
        )
       
    def forward(self, X):
        x = self.dense(X)
        output = torch.sigmoid(x)
        return output

    
#初始化模型和优化器
simple_dnn_model = SimpleNN()

这个报错在简单神经网络模型中找不到fit如何解决
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 22:53 | 显示全部楼层
Terence888 发表于 2024-10-22 22:42
from mlxtend.regressor import StackingRegressor
f ...


`SimpleNN` 是一个 PyTorch 模型,没有 `fit` 方法。你需要手动训练模型。若要将它与其他模型一起使用,可以尝试以下方法:

### 解决方案

1. **定义一个包装类:**

   创建一个包装类使其行为与 scikit-learn 模型一致:

from sklearn.base import BaseEstimator, RegressorMixin

   class SimpleNNWrapper(BaseEstimator, RegressorMixin):
       def __init__(self, model, epochs=10, lr=0.001):
           self.model = model
           self.epochs = epochs
           self.lr = lr
           self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr)
           self.criterion = nn.BCELoss()
       
       def fit(self, X, y):
           dataset = data.TensorDataset(torch.tensor(X, dtype=torch.float32), torch.tensor(y, dtype=torch.float32))
           loader = DataLoader(dataset, batch_size=32, shuffle=True)
           
           for _ in range(self.epochs):
               for batch_X, batch_y in loader:
                   self.optimizer.zero_grad()
                   outputs = self.model(batch_X)
                   loss = self.criterion(outputs, batch_y.view(-1, 1))
                   loss.backward()
                   self.optimizer.step()
           return self
       
       def predict(self, X):
           self.model.eval()
           with torch.no_grad():
               return self.model(torch.tensor(X, dtype=torch.float32)).numpy().flatten()

2. **使用包装类:**

   使用该包装类代替原始模型:

models = [SimpleNNWrapper(SimpleNN()), other_model1, other_model2]  # 在此添加其他基模型

3. **确保 `X_train` 和 `y_train` 是 numpy 数组:**

   确保输入数据是 numpy 数组,便于使用 PyTorch 数据集和 DataLoader。

这将允许你在 `StackingRegressor` 中使用自定义的 PyTorch 模型。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-23 02:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表