【模型融合】集成学习(boosting, bagging, stacking)原理介绍、python代码实现(sklearn)、分类回归任务实战

12 篇文章 11 订阅
订阅专栏
9 篇文章 14 订阅
订阅专栏

概览

简单来说,集成学习是一种分类器结合的方法(不是一种分类器)。

宏观上讲集成学习分为3类

  • 序列集成方法boosting

    思路:每个学习器按照串行的方法生成。把几个基本学习器层层叠加,但是每一层的学习器的重要程度不同,越前面的学习的重要程度越高。它聚焦样本的权重。每一层在学习的时候,对前面几层分错的样本“特别关注”,建立了每个机器学习器之间的依赖关系,因此提升了整体模型的准确率。

    boost家族还是非常有名的,在sklearn上已经集成了非常多的boost分类器,例子特别多。值得一提的是很多树类的boost还可以作为特征筛选器,有特征重要程度评分的功能。

  • 并行集成方法bagging

    跟楼上不一样,这个方法是并行的,每个学习器是独立的存在,所以在训练的时候也将训练集分成互相有交集(训练集庞大的时候也可以没交集)的几组分别给每个学习器学习。因此bagging方法是一个集体决策,这就导致了每个学习器的学习结果存在差异。对于相同部分,直接采取;对于不同部分,采用投票的方式做出集体决策。

  • 模型融合Stacking

    这个思路跟上面两种方法又有所区别。之前的方法是对几个基本学习器的结果操作的,而Stacking是针对整个模型操作的,可以将多个已经存在的模型进行组合。跟上面两种方法不一样的是,Stacking强调模型融合,所以里面的模型不一样(异质),而上面两种方法中的模型基本类似(同质)。个人感觉关键点在于组合的模型的选择和组合策略的确定。

南京大学的周志华教授对集成学习有很深入的研究,其在09年发表的一篇概述性论文 《 Ensemble Learning》对这三种集成学习的框架的介绍非常详细。

模型的特点

  • 序列集成方法boosting

    重点聚焦几个基本学习器分类错的样本,主要目的是减少整体模型的偏差

  • 并行集成方法bagging

    重点聚焦数据集是分布,多次采样分别训练模型,减少分类器的方差

  • 模型融合Stacking

    重点是聚焦模型的顺序和种类,根据模型来构建融合Stack。模型“好而不同”,提升泛化能力。

优点

  1. 通常一个集成分类器的分类性能会好于单个分类器。
  2. 因为采取了不同的模型,集成学习的泛化能力也有所提升。

boosting

基本过程如下图所示

在这里插入图片描述

注意点:

  • 权重初始化:样本权重1初始化的时候直接平分权重。如果有n个样本,那就直接每个样本 1 n \frac{1}{n} n1的权重。
  • 权重更新方法:不同的模型就不一样 AdaBoost 是对错误样本赋更大的权重;GBDT(Gradient Boost Decision Tree) 每一次的计算是为了减少上一次的残差,还有很多其他的模型用了不同的方法。
  • 迭代:一直计算每个基本分类器的误差率,并更新,直至误差率达到规定范围。
  • 相对来说,boosting模型更关注在上一轮的结果上进行调整,是个串行的策略。所以,作为一个序列化的方法,其基本学习器之间存在强依赖关系,基本学习器可以稍微简单一点(弱分类器)。

bagging

基本过程如下图所示,还是能看出跟 boosting 不一样的。

在这里插入图片描述

注意点:

  • 随机采样:又放回地随机采样,所以有的样本被重复抽到有的不会被抽到。好处是能降低数据分布对学习器的影响。
  • 结合策略:随机森林就是在样本随机采样时对决策树也随机采样。
  • 迭代:一直训练基本学习器,直至基本学习器的数量达到规定数量。
  • 相对来说,bagging模型更关注每个模型的表现,因为是个并行的策略,每个模型都很重要。所以,基本学习器可以稍微复杂一点(随机森林的决策树深度深一点)。

Stacking

这个其实跟楼上不太一样,这个不是一个集成学习模型,是一个结合策略。

比较简单的结合策略有:

  • 投票法
  • 平均法
  • stack

投票

投票的的基本思路就是少数服从多数。感觉多数用于分类问题中。

最简单的投票就是直接让基本学习器对某一个样本分类,每个分类器根据自己的结果对类别投票。对于最终的分类结果,我们取得票最多的选项,如果出现平票就随机选一个。

稍微有点想法的投票是绝对多数投票:有点像决策树的增益率选取,对于最终的分类结果,它不仅要满足取得票最多这一条件,还要满足被投票过半的条件。如果不满足,那就直接拒绝预测。

在这里插入图片描述

另一种投票方法是加权投票法:对于每个学习器赋予权重,再加权求和得到每个类别的票数,这里的权重制定方法就要看你自己了。

平均

很多时候,针对回归问题,投票显然不能解决问题。这个时候就需要平均

普通的平均就是直接取多个学习器的预测结果直接取平均。

加权平均跟其他的也差不多,主要是怎么个赋权法。

Stack

从初始数据集中训练出初级学习器,然后“生成”一个新数据集用于训练次级学习器。在新数据集中,初级学习器的输出被当做样例输入特征,初始样本的标记仍被当做样例标记。

上面的两种学习器我们称为:

  • 基学习器:即上述所说的一级学习器
  • 元学习器:即上述所说的二级学习器。这里的”元“跟元学习、元宇宙等的”元“是一个意思,表示的是更高一层的抽象。元学习器即“学习器的学习器”,有点像基学习器的加权平均和打分器。

还有几个注意点:

  • 强模型

    一般来说跟bagging一样,第一层放的都是强模型,毕竟这几个模型是并行的,只有这几个强了最后的结果才会好,不然一堆垃圾放到一起再怎么组合都没用。

  • 多样性

    此外第一层的基学习器最好还得多样一点(结构),因为stacking希望从多个模型中学到不同的特点取其精华,不同的模型针对不同的分布效果也有好有坏。典型的错误就是第一层放好几个随机森林模型。

  • 多基学习器

    理由很简单,元学习器是学习基学习器的结果的,如果你基学习器太少就导致元学习器的输入特征过少,就导致元学习器不能很好地学习基学习器之间的关系,就导致元学习器效果下降。

  • 大数据

    这里的大数据不是指那种要用Hadoop的那种大数据,这里是指数据不能太少。毕竟要划分测试集训练集,还要交叉验证划分k折和验证集,要是数据太少确实没什么用。

  • 简单元学习器

    这个学习器不要太强,因为很强大的学习器在这种简单问题上往往会过拟合,毕竟第一层的基学习器已经很强了,元学习器只是为了学习基学习器的结果而已。

我的理解是这样的:

在这里插入图片描述

在训练的时候

  1. 将训练样本划分为k折的交叉验证样本(不解释交叉验证,网上的解释一抓一大把)

  2. 用基学习器学习将交叉验证样本,并得出每个基学习器的预测结果,并保存

  3. 将基学习器的预测结果拼接到一起,输入至元学习器中。元学习器以拼接的结果为训练样本,训练集label为标记得出预测结果

  4. 对比元学习器的预测结果于基学习器的预测结果,测试stacking之后模型的表现是否优于单一模型的表现

在预测的时候

  1. 将测试样本呢输入至以训练好的基学习器中,得到每个基学习器的预测结果,并保存
  2. 将基学习器的预测结果拼接到一起(也有说法是去平均),输入至元学习器中。元学习器以拼接的结果为训练样本,测试集label为标记得出预测结果
  3. 对比元学习器的预测结果于基学习器的预测结果,测试stacking之后模型的表现是否优于单一模型的表现

对于stacking的架构,这篇写的也非常好: Stacking:集成学习策略图解_stacking策略_SaoYear的博客-CSDN博客

代码实现

1. 分类

1.0 数据集介绍

好像是好久好久好久之前的小说新闻分类任务了,直接拿特征工程归一化之后的结果来用,感觉大小对机器学习来说不大不小吧(可能还是有点偏小,但是太大了这么多模型跑的好慢……)

训练集(1421 x 43)

在这里插入图片描述

label(1421 x 1)分布为44.5%的1,55.5%的0。

在这里插入图片描述

1.1 boosting

在这里插入图片描述

关于boosting,查了一下sklearn里的模型,好像没有啥框架,都是人家实现好的东西,暂时就直接用吧。应该就 AdaBoost, GTBoost,HBGBoost 这三个。

再补几个比较有名的boost(xgboost: https://xgboost.apachecn.org;CatBoost: CatBoost - open-source gradient boosting library;LightGBM: Welcome to LightGBM’s documentation! — LightGBM 3.3.5.99 documentation),这里我只管实现哈,之后可能会出原理的博客,一键三连不迷路~~

(写的时候没注意 ModelResultResult 用的不是很合理)

  • step 1 20%的测试集,10%的验证集,70%的训练集。

  • step 2 5 折训练集

  • step 3 训练

    • step 3.1 取一折当prediction,剩下训练
    • step 3.2 验证集网格调参(简化的时候就不需要了)
  • step 4 评估训练结果(时间,准确率,5次交叉验证得分,F1)

  • step 5 评估测试结果(时间,准确率,5次交叉验证得分,F1)

import pandas as pd
import numpy as np
np.set_printoptions(precision=3)
from datetime import time, timedelta
import time
from sklearn.model_selection import train_test_split, cross_val_predict, cross_val_score, KFold, RandomizedSearchCV
from sklearn.metrics import accuracy_score, f1_score
from sklearn.ensemble import GradientBoostingClassifier, AdaBoostClassifier, HistGradientBoostingClassifier
from xgboost.sklearn import XGBClassifier
from catboost import CatBoostClassifier
from lightgbm import LGBMClassifier
import warnings
warnings.filterwarnings("ignore")


class ModelResult:
    def __init__(self, model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc, test_score,
                 test_F1):
        self.model_name = model_name
        self.train_time = train_time
        self.train_acc = train_acc
        self.train_score = train_score
        self.train_F1 = train_F1
        self.test_time = test_time
        self.test_acc = test_acc
        self.test_score = test_score
        self.test_F1 = test_F1
        self.columns = ["model_name", "train_time", "train_acc", "train_score", "train_F1", "test_time", "test_acc",
                        "test_score", "test_F1"]

    def to_list(self):
        return [self.model_name, self.train_time, self.train_acc, self.train_score, self.train_F1, self.test_time,
                self.test_acc, self.test_score, self.test_F1]


class Result:
    def __init__(self):
        self.model_list = []

    def save(self, file_name):
        model_list = [line.to_list() for line in self.model_list]
        output = pd.DataFrame(model_list, columns=self.model_list[0].columns)
        output.to_csv(file_name, encoding="utf-8-sig", index=0)


class BoostMethod:
    def __init__(self, datapath, labelpath, k=5, cv=4, search=False):
        """
        :param datapath: 数据路径
        :param labelpath: 标签路径
        :param k: k折训练
        :param cv: 交叉验证次数
        :param search: 是否需要网格调参
        """
        self.data_path = datapath
        self.labelpath = labelpath
        self.dataset = self.loading_data()  # [train_x, test_x, train_y, test_y]
        self.cv = cv
        self.k = k
        self.search = search
        self.model = {
            "AdaBoost": AdaBoostClassifier(n_estimators=100),
            "GTBoost": GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1, random_state=0),
            "HBGBoost": HistGradientBoostingClassifier(max_iter=100),
            "xgboost": XGBClassifier(eval_metric=['logloss', 'auc', 'error']),
            "CatBoost": CatBoostClassifier(learning_rate=0.1, depth=6, iterations=100, verbose=False),
            "LightGBM": LGBMClassifier(learning_rate=0.1, max_depth=3, num_leaves=16),
        }

    def loading_data(self):
        data = pd.read_csv(self.data_path, encoding="utf-8-sig", header=0)
        label = pd.read_csv(self.labelpath, encoding="utf-8-sig", header=0)
        train_x, test_x, train_y, test_y = train_test_split(data, label, test_size=0.3, random_state=1129)
        return {"train_x": train_x, "test_x": test_x, "train_y": train_y, "test_y": test_y}

    def fitting(self):
        result = Result()
        for item in self.model.items():
            model_name = item[0]
            model = item[1]
            print(model_name)
            model, train_time, (train_acc, train_score, train_F1) = self.train(model, self.dataset["train_x"],
                                                                               self.dataset["train_y"])
            (test_time, test_acc, test_score, test_F1) = self.test(model, self.dataset["test_x"],
                                                                   self.dataset["test_y"])
            model_result = ModelResult(model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc,
                                       test_score, test_F1)
            result.model_list.append(model_result)
        return result

    def evaluate(self, model, data, label, test=False):
        start_time = time.time()
        predict = cross_val_predict(model, data, label, cv=self.cv)
        time_ret = self.get_time_dif(start_time)
        acc = accuracy_score(predict, label)
        score = cross_val_score(model, data, label, cv=self.cv).mean()
        F1 = f1_score(label, predict)
        if test:
            return str(time_ret), acc, score, F1
        else:
            return acc, score, F1

    def train(self, model, data, label):
        start_time = time.time()
        kf = KFold(n_splits=self.k, random_state=1129, shuffle=True)
        for train, evaluate in kf.split(data):
            model.fit(data.iloc[train], label.iloc[train])
        time_ret = self.get_time_dif(start_time)
        return model, str(time_ret), self.evaluate(model, data, label)

    def test(self, model, data, label):
        return self.evaluate(model, data, label, test=True)

    def get_time_dif(self, start_time):
        end_time = time.time()
        time_dif = end_time - start_time
        # print("Time usage:", timedelta(seconds=int(round(time_dif))))
        return timedelta(seconds=int(round(time_dif)))


if __name__ == '__main__':
    method = BoostMethod("dataset.csv", "label.csv")
    result = method.fitting()
    result.save("boosting{}.csv".format(time.strftime('_%Y%m%d_%H%M', time.localtime())))

几个模型结果如下

在这里插入图片描述

1.2 bagging

直接用sklearn试一下:

import pandas as pd
import numpy as np
from sklearn.ensemble import BaggingClassifier
from sklearn.svm import SVC
np.set_printoptions(precision=3)
from datetime import time, timedelta
import time
from sklearn.model_selection import train_test_split, cross_val_predict, cross_val_score, KFold, RandomizedSearchCV, \
    GridSearchCV
from sklearn.metrics import accuracy_score, f1_score
import warnings
warnings.filterwarnings("ignore")


class ModelResult:
    def __init__(self, model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc, test_score,
                 test_F1):
        self.model_name = model_name
        self.train_time = train_time
        self.train_acc = train_acc
        self.train_score = train_score
        self.train_F1 = train_F1
        self.test_time = test_time
        self.test_acc = test_acc
        self.test_score = test_score
        self.test_F1 = test_F1
        self.columns = ["model_name", "train_time", "train_acc", "train_score", "train_F1", "test_time", "test_acc",
                        "test_score", "test_F1"]

    def to_list(self):
        return [self.model_name, self.train_time, self.train_acc, self.train_score, self.train_F1, self.test_time,
                self.test_acc, self.test_score, self.test_F1]


class Result:
    def __init__(self):
        self.model_list = []

    def save(self, file_name):
        model_list = [line.to_list() for line in self.model_list]
        output = pd.DataFrame(model_list, columns=self.model_list[0].columns)
        output.to_csv(file_name, encoding="utf-8-sig", index=0)


class BaggingMethod:
    def __init__(self, datapath, labelpath, k=5, cv=4, search=False):
        """
        :param datapath: 数据路径
        :param labelpath: 标签路径
        :param k: k折训练
        :param cv: 交叉验证次数
        :param search: 是否需要网格调参
        """
        self.data_path = datapath
        self.labelpath = labelpath
        self.dataset = self.loading_data()  # [train_x, test_x, train_y, test_y]
        self.cv = cv
        self.k = k
        self.search = search
        self.model = {
            "SVM": SVC(kernel='rbf', class_weight='balanced')
        }

    def loading_data(self):
        data = pd.read_csv(self.data_path, encoding="utf-8-sig", header=0)
        label = pd.read_csv(self.labelpath, encoding="utf-8-sig", header=0)
        train_x, test_x, train_y, test_y = train_test_split(data, label, test_size=0.3, random_state=1129)
        return {"train_x": train_x, "test_x": test_x, "train_y": train_y, "test_y": test_y}

    def fitting(self):
        result = Result()
        for item in self.model.items():
            model_name = item[0]
            model = item[1]
            print(model_name)
            model, train_time, (train_acc, train_score, train_F1) = self.train(model, self.dataset["train_x"],
                                                                               self.dataset["train_y"])
            (test_time, test_acc, test_score, test_F1) = self.test(model, self.dataset["test_x"],
                                                                   self.dataset["test_y"])
            model_result = ModelResult(model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc,
                                       test_score, test_F1)
            result.model_list.append(model_result)
        return result

    def evaluate(self, model, data, label, test=False):
        start_time = time.time()
        predict = cross_val_predict(model, data, label, cv=self.cv)
        time_ret = self.get_time_dif(start_time)
        acc = accuracy_score(predict, label)
        score = cross_val_score(model, data, label, cv=self.cv).mean()
        F1 = f1_score(label, predict)
        if test:
            return str(time_ret), acc, score, F1
        else:
            return acc, score, F1

    def train(self, model, data, label):
        start_time = time.time()
        clf = BaggingClassifier(estimator=model, n_estimators=20, max_samples=1.0, max_features=1.0,
                                bootstrap=True, bootstrap_features=False, n_jobs=1, random_state=1)
        param_grid = [{'estimator': [SVC(kernel='rbf', class_weight='balanced', C=4.5)],
                       'n_estimators': [20], 'max_samples': [0.95],
                       'max_features': [0.8]}]
        grid = GridSearchCV(clf, param_grid, cv=6, n_jobs=-1)
        grid.fit(data, label.values.ravel())
        best_estimator = grid.best_estimator_
        time_ret = self.get_time_dif(start_time)
        return best_estimator, str(time_ret), self.evaluate(best_estimator, data, label)

    def test(self, model, data, label):
        return self.evaluate(model, data, label, test=True)

    def get_time_dif(self, start_time):
        end_time = time.time()
        time_dif = end_time - start_time
        # print("Time usage:", timedelta(seconds=int(round(time_dif))))
        return timedelta(seconds=int(round(time_dif)))


if __name__ == '__main__':
    method = BaggingMethod("dataset.csv", "label.csv")
    result = method.fitting()
    result.save("bagging{}.csv".format(time.strftime('_%Y%m%d_%H%M', time.localtime())))

结果长这样

在这里插入图片描述

1.3 stacking

stacking 如果手写实现,那还是有难度的。幸运的是 sklearn给我们提供了相关的函数,所以秒出。

还是要说明下,stacking 的元学习器真的不建议放太好的。也尝试过随机森林等等,效果真没有线性的逻辑回归好。就是说强学习器模型可能会造成过拟合,反而降低了我们这块的准确率。

import pandas as pd
import numpy as np
np.set_printoptions(precision=3)
from datetime import time, timedelta
import time
from sklearn.model_selection import train_test_split, cross_val_predict, cross_val_score, KFold, RandomizedSearchCV
from sklearn.metrics import accuracy_score, f1_score
from sklearn.ensemble import GradientBoostingClassifier, AdaBoostClassifier, HistGradientBoostingClassifier, RandomForestClassifier, StackingClassifier
from xgboost.sklearn import XGBClassifier
from catboost import CatBoostClassifier
from lightgbm import LGBMClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn import tree
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
import warnings
warnings.filterwarnings("ignore")


class ModelResult:
    def __init__(self, model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc, test_score,
                 test_F1):
        self.model_name = model_name
        self.train_time = train_time
        self.train_acc = train_acc
        self.train_score = train_score
        self.train_F1 = train_F1
        self.test_time = test_time
        self.test_acc = test_acc
        self.test_score = test_score
        self.test_F1 = test_F1
        self.columns = ["model_name", "train_time", "train_acc", "train_score", "train_F1", "test_time", "test_acc",
                        "test_score", "test_F1"]

    def to_list(self):
        return [self.model_name, self.train_time, self.train_acc, self.train_score, self.train_F1, self.test_time,
                self.test_acc, self.test_score, self.test_F1]


class Result:
    def __init__(self):
        self.model_list = []

    def save(self, file_name):
        model_list = [line.to_list() for line in self.model_list]
        output = pd.DataFrame(model_list, columns=self.model_list[0].columns)
        output.to_csv(file_name, encoding="utf-8-sig", index=0)


class StackMethod:
    def __init__(self, datapath, labelpath, k=5, cv=4, search=False):
        """
        :param datapath: 数据路径
        :param labelpath: 标签路径
        :param k: k折训练
        :param cv: 交叉验证次数
        :param search: 是否需要网格调参
        """
        self.data_path = datapath
        self.labelpath = labelpath
        self.dataset = self.loading_data()  # [train_x, test_x, train_y, test_y]
        self.cv = cv
        self.k = k
        self.search = search
        self.model = {
            "AdaBoost": AdaBoostClassifier(n_estimators=100),
            "GTBoost": GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1, random_state=0),
            "HBGBoost": HistGradientBoostingClassifier(max_iter=100),
            "xgboost": XGBClassifier(eval_metric=['logloss', 'auc', 'error']),
            "CatBoost": CatBoostClassifier(learning_rate=0.1, depth=6, iterations=100, verbose=False),
            "LightGBM": LGBMClassifier(learning_rate=0.1, max_depth=3, num_leaves=16),
            "SVC": SVC(kernel='rbf', class_weight='balanced'),
            "KNN": KNeighborsClassifier(),
            "LR": LogisticRegression(penalty='l2'),
            "RF": RandomForestClassifier(n_estimators=8),
            "DT": tree.DecisionTreeClassifier(),
            "GNB": GaussianNB(),
            "LDA": LinearDiscriminantAnalysis(),
            "QDA": QuadraticDiscriminantAnalysis(),
            "MNB": MultinomialNB(alpha=0.01),
        }

    def loading_data(self):
        data = pd.read_csv(self.data_path, encoding="utf-8-sig", header=0)
        label = pd.read_csv(self.labelpath, encoding="utf-8-sig", header=0)
        train_x, test_x, train_y, test_y = train_test_split(data, label, test_size=0.3, random_state=1129)
        return {"train_x": train_x, "test_x": test_x, "train_y": train_y, "test_y": test_y}

    def fitting(self):
        result = Result()
        estimators = [(item[0], item[1]) for item in self.model.items()]
        clf = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())
        clf, train_time, (train_acc, train_score, train_F1) = self.train(clf, self.dataset["train_x"], self.dataset["train_y"])
        (test_time, test_acc, test_score, test_F1) = self.test(clf, self.dataset["test_x"], self.dataset["test_y"])
        model_result = ModelResult("Stacking", train_time, train_acc, train_score, train_F1, test_time, test_acc, test_score, test_F1)
        result.model_list.append(model_result)
        for item in self.model.items():
            model_name = item[0]
            model = item[1]
            print(model_name)
            model, train_time, (train_acc, train_score, train_F1) = self.train(model, self.dataset["train_x"], self.dataset["train_y"])
            (test_time, test_acc, test_score, test_F1) = self.test(model, self.dataset["test_x"], self.dataset["test_y"])
            model_result = ModelResult(model_name, train_time, train_acc, train_score, train_F1, test_time, test_acc, test_score, test_F1)
            result.model_list.append(model_result)
        return result

    def evaluate(self, model, data, label, test=False):
        start_time = time.time()
        predict = cross_val_predict(model, data, label, cv=self.cv)
        time_ret = self.get_time_dif(start_time)
        acc = accuracy_score(predict, label)
        score = cross_val_score(model, data, label, cv=self.cv).mean()
        F1 = f1_score(label, predict)
        if test:
            return str(time_ret), acc, score, F1
        else:
            return acc, score, F1

    def train(self, model, data, label):
        start_time = time.time()
        kf = KFold(n_splits=self.k, random_state=1129, shuffle=True)
        for train, evaluate in kf.split(data):
            model.fit(data.iloc[train], label.iloc[train])
        time_ret = self.get_time_dif(start_time)
        print("Time Usage:{}".format(time_ret))
        return model, str(time_ret), self.evaluate(model, data, label)

    def test(self, model, data, label):
        return self.evaluate(model, data, label, test=True)

    def get_time_dif(self, start_time):
        end_time = time.time()
        time_dif = end_time - start_time
        # print("Time usage:", timedelta(seconds=int(round(time_dif))))
        return timedelta(seconds=int(round(time_dif)))


if __name__ == '__main__':
    method = StackMethod("dataset.csv", "label.csv")
    result = method.fitting()
    result.save("stacking{}.csv".format(time.strftime('_%Y%m%d_%H%M', time.localtime())))

看结果,stacking 还是很强的,可能是任务太简单了(有的人考100分是因为满分只有100分)。

在这里插入图片描述

2. 回归

2.0 数据集介绍

拿2023年美赛春季赛Y题的数据做一下哈~~

一共16个特征,1898条数据,任务是预测帆船的价格,给的是制造商、船型、船长、地区、国家、年份的数据,我自己又找了引擎马力、吃水量、装油量、设计师、最大价格、平均价格、最小价格、LWL、梁长、航范围、定价法的数据,有些数据是特征工程的结果。

在这里插入图片描述

去重啊填空啊归一化啊异常值处理啊之类的咱就不提,直接上手模型就完事了。

label 长这样(标准化了)

在这里插入图片描述

stacking

把sklearn上的回归模型往上面乱扔。

顺便利用这几个boost算法评估一下特征的重要性。

import pandas as pd
import numpy as np
from catboost import CatBoostRegressor
from datetime import time, timedelta
import time
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split, cross_val_predict, cross_val_score, KFold, RandomizedSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.ensemble import AdaBoostRegressor, StackingRegressor, RandomForestRegressor, GradientBoostingRegressor
import lightgbm as lgb
import warnings
from sklearn.neighbors import KNeighborsRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.svm import SVR
from sklearn.tree import DecisionTreeRegressor, ExtraTreeRegressor
from xgboost import XGBRegressor
warnings.filterwarnings("ignore")
np.set_printoptions(precision=3)

class ModelResult:
    def __init__(self, model_name, train_time, train_MSE, train_score, train_MAE, train_R2, test_time, test_MSE, test_score, test_MAE,
                 test_R2):
        self.model_name = model_name
        self.train_time = train_time
        self.train_MSE = train_MSE
        self.train_score = train_score
        self.train_MAE = train_MAE
        self.train_R2 = train_R2
        self.test_time = test_time
        self.test_MSE = test_MSE
        self.test_score = test_score
        self.test_MAE = test_MAE
        self.test_R2 = test_R2
        self.columns = ["model_name", "train_time", "train_MSE", "train_score", "train_MAE", "train_R2", "test_time",
                        "test_MSE", "test_score", "test_MAE", "test_R2"]

    def to_list(self):
        return [
            self.model_name,
            self.train_time,
            self.train_MSE,
            self.train_score,
            self.train_MAE,
            self.train_R2,
            self.test_time,
            self.test_MSE,
            self.test_score,
            self.test_MAE,
            self.test_R2
        ]


class Result:
    def __init__(self):
        self.model_list = []

    def save(self, file_name):
        model_list = [line.to_list() for line in self.model_list]
        output = pd.DataFrame(model_list, columns=self.model_list[0].columns)
        output.to_csv(file_name, encoding="utf-8-sig", index=0)


class StackMethod:
    def __init__(self, datapath, labelpath, predpath, k=5, cv=4, search=False):
        """
        :param datapath: 数据路径
        :param labelpath: 标签路径
        :param k: k折训练
        :param cv: 交叉验证次数
        :param search: 是否需要网格调参
        """
        self.data_path = datapath
        self.labelpath = labelpath
        self.predpath = predpath
        self.dataset = self.loading_data()  # [train_x, test_x, train_y, test_y]
        self.cv = cv
        self.k = k
        self.search = search
        self.importance = []
        self.model = {
            "LinearRegression": LinearRegression(),
            "SVR": SVR(),
            "KNN": KNeighborsRegressor(),
            "Ridge": Ridge(random_state=1129,),
            "Lasso": Lasso(random_state=1129,),
            "DecisionTree": DecisionTreeRegressor(random_state=1129,),
            "ExtraTree": ExtraTreeRegressor(random_state=1129,),
            "RandomForest": RandomForestRegressor(random_state=1129,),
            "MLP": MLPRegressor(random_state=1129),
            "GBoost": GradientBoostingRegressor(random_state=1129,),
            "AdaBoost": AdaBoostRegressor(random_state=1129, n_estimators=100),     # GA search
            "LightGBM": lgb.LGBMRegressor(random_state=1129),                       # 可以优化
            "Catboost": CatBoostRegressor(random_state=1129),
            "XGBboost": XGBRegressor(random_state=1129),
        }

    def loading_data(self):
        data = pd.read_csv(self.data_path, encoding="utf-8-sig", header=0)
        label = pd.read_csv(self.labelpath, encoding="utf-8-sig", header=0)
        train_x, test_x, train_y, test_y = train_test_split(data, label, test_size=0.3, random_state=1129)
        return {"train_x": train_x, "test_x": test_x, "train_y": train_y, "test_y": test_y}

    def fitting(self):
        result = Result()
        estimators = [(item[0], item[1]) for item in self.model.items()]
        clf = StackingRegressor(estimators=estimators, final_estimator=LinearRegression())
        clf, train_time, (train_mse, train_score, train_mae, train_r2) = self.train(clf, self.dataset["train_x"], self.dataset["train_y"])
        (test_time, test_mse, test_score, test_mae, test_r2) = self.test(clf, self.dataset["test_x"], self.dataset["test_y"])
        self.pred_ret(clf, self.dataset["test_x"], self.dataset["test_y"])
        model_result = ModelResult("Stacking", train_time, train_mse, train_score, train_mae, train_r2, test_time, test_mse, test_score, test_mae, test_r2)
        result.model_list.append(model_result)
        for item in self.model.items():
            model_name = item[0]
            model = item[1]
            print(model_name)
            model, train_time, (train_mse, train_score, train_mae, train_r2) = self.train(model, self.dataset["train_x"], self.dataset["train_y"])
            (test_time, test_mse, test_score, test_mae, test_r2) = self.test(model, self.dataset["test_x"], self.dataset["test_y"])
            model_result = ModelResult(model_name, train_time, train_mse, train_score, train_mae, train_r2, test_time, test_mse, test_score, test_mae, test_r2)
            result.model_list.append(model_result)
        return result

    def evaluate(self, model, data, label, test=False):
        start_time = time.time()
        predict = cross_val_predict(model, data, label, cv=self.cv)
        time_ret = self.get_time_dif(start_time)
        MSE = mean_squared_error(label, predict)
        score = cross_val_score(model, data, label, cv=self.cv).mean()
        MAE = mean_absolute_error(label, predict)
        R2 = r2_score(label, predict)
        if test:
            return str(time_ret), MSE, score, MAE, R2
        else:
            return MSE, score, MAE, R2

    def train(self, model, data, label):
        start_time = time.time()
        kf = KFold(n_splits=self.k, random_state=1129, shuffle=True)
        for train, evaluate in kf.split(data):
            model.fit(data.iloc[train], label.iloc[train])
        time_ret = self.get_time_dif(start_time)
        try:
            n = model.feature_importances_
            self.importance.append(n)
        except:
            1
        print("Time Usage:{}".format(time_ret))
        return model, str(time_ret), self.evaluate(model, data, label)

    def test(self, model, data, label):
        return self.evaluate(model, data, label, test=True)

    def get_time_dif(self, start_time):
        end_time = time.time()
        time_dif = end_time - start_time
        # print("Time usage:", timedelta(seconds=int(round(time_dif))))
        return timedelta(seconds=int(round(time_dif)))

    def save_importance(self, file_path):
        file = pd.DataFrame(self.importance)
        file.columns = self.dataset["train_x"].columns
        file = file.div(file.sum(axis=1), axis='rows')
        file = file.T
        file["sum"] = file.sum(axis=1)
        file.sort_values(by=file.columns[-1], inplace=True, ascending=True)
        file.to_csv(file_path)


    def pred_ret(self, model, data, label):
        predict = model.predict(data)
        result = pd.DataFrame([label[label.columns[-1]].values.tolist(), predict]).T
        result.columns = ["label", "predict"]
        result.to_csv(self.predpath, index=None)



if __name__ == '__main__':
    method = StackMethod("dataset_M.csv", "label_M.csv", "ret_M.csv")
    result = method.fitting()
    method.save_importance("importance/M.csv")
    result.save("CSDN_stacking_M{}.csv".format(time.strftime('_%Y%m%d_%H%M', time.localtime())))

结果如下:

在这里插入图片描述

在这个任务上,Stacking倒也没有达到乱杀的程度,有的时候效果还不如单一的集成模型,个人认为是因为中间混入了很多像线性回归啊、岭回归啊、Lasso回归啊、MLP啊之类的弱学习器或者是在该任务上表现不出众的学习器,这些学习器对最后的结果有比较强的干扰作用。改善有3种方案:

  1. 删除这些弱学习器。
  2. 适当加强元学习器,让它学明白弱学习器的权重应该小一点。
  3. 调整参数。这里我各个学习器都是直接扔上去的,表现不好可能跟调参有关,所以可以尝试微调参数,可能会有比较好的效果。

去除掉了几个不相关特征之后,特征重要性在这里:

在这里插入图片描述

stacking模型融合
芒果冰麦
04-04 9208
模型融合 模型融合的方法 简单加权融合: 回归分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean); 分类:投票(Voting) 综合:排序融合(Rank averaging),log融合 stacking/blending: 构建多层模型,并利用预测结果再拟合预测。 boosting/bagging(在xgboost,Ad...
三种集成学习范式详解:Boosting、BaggingStacking
最新发布
weixin_41174300的博客
06-16 694
集成学习是机器学习中一个非常强大的范式,通过结合多个模型的预测来提升整体的预测效果。主要的集成学习方法包括Boosting、BaggingStacking,每种方法都有其独特的策略和优点。本文将详细介绍这三种集成学习方法,包括它们的数学原理、具体的算法实现,以及应用场景。
【机器学习】集成学习——Stacking模型融合(理论+图解)
热门推荐
CSDN 精品推荐
08-29 3万+
如果需要完整代码可以关注下方公众号,后台回复“代码”即可获取,阿光期待着您的光临~ 文章目录一、引言二、Stacking集成模型1.Stacking原理2.实现代码 2021人工智能领域新星创作者,带你从入门到精通,该博客每天更新,逐渐完善机器学习各个知识体系的文章,帮助大家更高效学习。 一、引言 对于单个模型来说很难拟合复杂的数据,而且对于单模型来说,模型的抗干扰能力较低,所以我们希望可以集成多个模型,结合多个模型的优缺点提高模型的泛化能力。 针对于集成学习一般有两种方式,第一种为Boosti.
最强全面总结,十大集成学习模型!!!
Python数据挖掘
04-25 1710
Bagging 通过在原始数据集的随机子集上训练多个基本模型,并对它们的预测结果进行平均或投票来减少方差。
集成学习Stacking
u012867518的专栏
05-13 1万+
1. 基本概念 ​ 模型堆叠是一种数据科学基础方法,它依赖于多个模型的结果,即将多个弱学习器的结果进行组织,往往胜过单一的强模型。过去几年中大多数主要 kaggle 比赛的获胜者在最终获奖模型中都使用了模型堆叠。 ​ 堆叠模型类比于现实世界的例子,就比如商业团队,科学实验,或者体育团队。如果团队中的所有成员都非常擅长完成同样的任务,那么团队就会摧毁任何需要这个任务的挑战。 ​ Stacking有“堆叠”的意思。从字面意思理解,Stacking方法就是将多个模型(同一层),进
模型融合Stacking
Unravel_36的博客
03-29 5081
前言 最近研究模型融合,看到很多关于介绍Stacking的文章,大多数文章都有这张图。如果你能一眼看懂,OK,那你就不用继续读下去了。如果一下子看不懂,我会结合代码具体介绍Stacking是如何工作的。 一、Stacking是什么? Stacking集成学习的一种方法。集成学习可以融合不同模型学习到的特征以提升最终的预测效果。一般来说,集成学习的要求基学习器好而不同。即每个基学习器性能不能太差,同时不同的基学习器学习的特征不同。 二、代码实现 本示例使用Sklearn的威斯康辛州乳腺癌数据集 1.引入
集成学习】:Stacking原理以及Python代码实现
极歌科技
10-17 1万+
  Stacking集成学习在各类机器学习竞赛当中得到了广泛的应用,尤其是在结构化的机器学习竞赛当中表现非常好。今天我们就来介绍stacking这个在机器学习模型融合当中的大杀器的原理。并在博文的后面附有相关代码实现。 总体来说,stacking集成算法主要是一种基于“标签”的学习,有以下的特点:   用法:模型利用交叉验证,对训练集进行预测,从而实现二次学习   优点:可以结合不同的模型  ...
一、集成学习概况、Boosting、Baggingstacking介绍
qq_34120015的博客
05-18 1127
11
一行 Python 代码搞定训练分类回归模型
Warmer_Sweeter
10-15 194
引言自动机器学习(Auto-ML)是指自动化数据科学模型开发流水线的组件。AutoML 减少了数据科学家的工作量,并加快了工作流程。AutoML 可用于自动化各种流水线组件,包括数据理解,EDA,数据处理,模型训练,超参数调整等。在本文中,我们将讨论如何使用开放源码的 Python 库 LazyPredict 来自动化模型训练过程。什么是LazyPredict ?LazyPredict 是一个开...
python机器学习库sklearn-集成方法
11-16
sklearn提供了多种集成方法,如BaggingBoostingStacking。 **BaggingBootstrap Aggregating)** 是一种典型的集成方法,其核心是通过对原始数据进行有放回抽样(bootstrap sampling)来构建多个基估计器。在...
基于sklearn实现Bagging算法(python
01-01
本文使用的数据类型是数值型,每一个样本6个特征表示,所用的数据如图所示: 图中A,B,C,D,E,F列表示六个特征,G表示样本标签。每一行数据即为一个样本的六个特征和标签。 实现Bagging算法的代码如下: from sklearn.ensemble import BaggingClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.preprocessing import StandardScaler import csv from sklearn.cross_validation import t
python集成-从基础到实现集成学习综合教程(附Python代码).pdf
06-13
Python中,有许多库支持集成学习,如scikit-learn提供了baggingboosting实现,以及用于堆叠和混合的工具。通过实际案例和Python代码,你可以深入理解和实践这些概念,进一步提升机器学习项目的效果。
机器学习之集成学习理论与代码实践
06-14
集成学习主要有四种常见的策略:Voting、BaggingBoostingStacking。 1. **Voting**:投票法是最简单的集成策略,它将多个学习器的预测结果进行统计,然后选择出现频率最高的类别作为最终预测。分为硬投票(直接...
striking融合_python_模型融合_预测_
09-29
在这个案例中,"striking融合_python_模型融合_预测_"的标题表明我们正在探讨使用Python编程语言实现的一种特定的模型融合策略,用于二手车价格的预测。描述中提到,通过模型融合,已经实现了较高的预测准确率,这...
Python金融大数据风控建模实战:基于机器学习源代码.zip
02-15
4. **模型优化**:如果模型性能不佳,可以通过集成学习(如BaggingBoostingStacking)或者深度学习进一步提升。 5. **模型部署**:将训练好的模型部署到生产环境,实时进行风险评估。 在...
机器学习之集成学习Boosting算法、Bagging算法、Stacking算法)总结
~华仔的博客
06-16 1935
20190616 1集成学习 集成学习就是组合多个学习器,最后可以得到一个更好的学习器 #集成学习算法 #装袋(bagging):个体学习器之间不存在强依赖关系 #随机森林(Random Forest) #提升(boosting):个体学习器之间存在强依赖关系 #Stacking 2bagging 是一种有放回抽样 ...
机器学习之Stacking原理实战
weixin_41580067的博客
02-23 4002
学习过机器学习相关基础的童鞋应该知道,从基学习器的类型可将集成学习分为两大类: 同质集成(homogeneous) Boosting:Adaboost、GBDT、XGboost、lightGBM等 Bagging:RandomForest 异质集成(heterogenous) Stacked Generalization(SG),也叫堆栈泛化 1、堆栈泛化(Stacked G...
集成学习——BaggingBoostingStacking
Gu_NN的博客
07-23 829
目录投票法集成学习BaggingBootstraps(题5.1)Bagging(题5.2-题5.6)BoostingStacking 投票法 投票法即通过对多个模型结果进行少数服从多数的融合。有助于提高模型的泛化能力,减少模型的错误率。 回归模型 投票法最终的预测结果是多个其他回归模型预测结果的平均值。 分类模型 硬投票:预测结果是多个模型预测结果中出现次数最多的类别 软投票:对各类预测结果的概率进行求和,最终选取概率之和最大的类标签。 投票法结果好需要满足的两个条件: 基模型之间的效果不能差别
集成学习方法归纳与代码实现
AIHUBEI的博客
05-02 1757
组合不同的模型进行集成学习 群体决策: 一般可以从数据层面、单模型层面(比如模型调参等)、集成学习等方式提升模型性能。 Bagging:随机构造训练所使用的数据样本,随机选择特征,通过引入数据上的随机性降低模型方差,减小过拟合。 Boosting:从错误中学习,当前模型更加聚焦于上一个模型错分的样本,着力减小偏差。 from IPython.display import Image %matplotlib inline 1.集成学习 集成学习的目标是将不同的分类器组合形成一个元分类器,该组合生成的分类器具
stacking集成学习python代码
05-24
以下是一个简单的 stacking 集成学习Python 代码示例: ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.ensemble import RandomForestClassifier from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.naive_bayes import GaussianNB # 加载数据 X, y = load_iris(return_X_y=True) # 划分训练集和验证集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 初始化基模型 rf = RandomForestClassifier(n_estimators=50, random_state=42) lr = LogisticRegression(random_state=42) knn = KNeighborsClassifier(n_neighbors=3) nb = GaussianNB() # 训练基模型 rf.fit(X_train, y_train) lr.fit(X_train, y_train) knn.fit(X_train, y_train) nb.fit(X_train, y_train) # 使用基模型对验证集进行预测 rf_pred = rf.predict(X_test) lr_pred = lr.predict(X_test) knn_pred = knn.predict(X_test) nb_pred = nb.predict(X_test) # 计算基模型的准确率 rf_acc = accuracy_score(y_test, rf_pred) lr_acc = accuracy_score(y_test, lr_pred) knn_acc = accuracy_score(y_test, knn_pred) nb_acc = accuracy_score(y_test, nb_pred) print('Random Forest accuracy:', rf_acc) print('Logistic Regression accuracy:', lr_acc) print('KNN accuracy:', knn_acc) print('Naive Bayes accuracy:', nb_acc) # 构建元模型的训练集和验证集 train_meta = [rf_pred, lr_pred, knn_pred, nb_pred] train_meta = np.array(train_meta).T test_meta = np.column_stack((rf.predict(X_test), lr.predict(X_test), knn.predict(X_test), nb.predict(X_test))) # 初始化元模型 meta_model = RandomForestClassifier(n_estimators=50, random_state=42) # 训练元模型 meta_model.fit(train_meta, y_test) # 使用元模型对验证集进行预测 meta_pred = meta_model.predict(test_meta) # 计算元模型的准确率 meta_acc = accuracy_score(y_test, meta_pred) print('Stacking accuracy:', meta_acc) ``` 该代码使用 scikit-learn 库中的 iris 数据集演示了如何使用 stacking 集成学习。首先,将数据集划分为训练集和验证集;然后,使用随机森林、逻辑回归、KNN 和朴素贝叶斯等基模型对训练集进行训练,并在验证集上进行预测和评估;接着,将基模型的预测结果作为元特征,构建元模型的训练集和验证集;最后,使用随机森林作为元模型对验证集进行预测和评估。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 从零开始的Origin新手入门教程(速成) 52621
  • 从零开始的Django框架入门到实战教程(内含实战实例) - 01 创建项目与app、加入静态文件、模板语法介绍(学习笔记) 24898
  • FTP服务器保存账号密码自动登录后如何退出并切换用户名登录其他账号(windows 10) 19581
  • 机器学习之朴素贝叶斯分类器原理详解、公式推导(手推)、面试问题、简单实例(python实现,sklearn调包) 19115
  • 机器学习之支持向量机(SVM)原理详解、公式推导(手推)、面试问题、简单实例(sklearn调包) 14566

分类专栏

  • 深度学习 1篇
  • python 2篇
  • 机器学习 9篇
  • 移动应用开发 21篇
  • Android Studio 5篇
  • Flutter 16篇
  • 前端 14篇
  • Django 11篇
  • 网页制作 3篇
  • 爬虫
  • 数学建模 12篇
  • 算法小题 13篇
  • 异常值识别 6篇
  • 电脑使用 2篇
  • 数据结构 2篇
  • origin 1篇
  • Latex 4篇

最新评论

  • 从零开始的Django框架入门到实战教程(内含实战实例) - 01 创建项目与app、加入静态文件、模板语法介绍(学习笔记)

    放。756: 深入浅出,非常适合初学者

  • 从零开始的Django框架入门到实战教程(内含实战实例) - 01 创建项目与app、加入静态文件、模板语法介绍(学习笔记)

    放。756: 深入浅出,非常适合初学者

  • 从零开始的Django框架入门到实战教程(内含实战实例) - 11 利用echart和Ajax请求完成数据可视化(学习笔记)

    猪儿虫啦: 大佬可以看看源码吗?谢谢1875032109@qq.com

  • 从零开始的Django框架入门到实战教程(内含实战实例) - 01 创建项目与app、加入静态文件、模板语法介绍(学习笔记)

    夏日冰甜汽水*^O^*: 对,下个破解版吧

  • 基于overleaf 的美国大学生数学建模竞赛(美赛)latex 格式模板(含信件和附件)

    qq_49016034: 博主您好,可以分享一下模版吗

大家在看

  • OSPF特殊区域及其他特性
  • 引领职场潮流,从这个霍兰德测试掌握先机! 871
  • Java 二进制文件操作汇总 278
  • Docker搭建本地私有仓库 563
  • java中多态的用法 273

最新文章

  • 简单毛概刷题网页制作 3.0(拖欠近一年版)
  • 简单毛概刷题网页制作 2.0(拖欠近一年版)
  • 超简单有趣的模拟算法:元胞自动机(CA)原理简介与 matlab 代码实现
2023年37篇
2022年41篇

目录

目录

评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铖铖的花嫁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

PHP网站源码福田网站优化按天收费石岩网站优化按天计费盐田网站优化软件龙华网站优化推广西乡营销型网站建设丹竹头高端网站设计盐田网络营销木棉湾网络广告推广永湖网站推广系统罗湖百搜词包惠州百搜标王同乐关键词排名大浪网站优化按天扣费坪地英文网站建设广州百姓网标王推广光明seo南山关键词排名包年推广布吉seo福永模板网站建设沙井百姓网标王大鹏建站南山品牌网站设计观澜网络推广大运百度标王爱联设计网站同乐网站排名优化观澜网站优化排名深圳网站优化推广光明网站制作设计观澜网站排名优化歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化