scikit-learn - 具有高斯过程的多输出空间统计

我最近一直在研究高斯过程。概率多输出的观点在我的领域中很有前途。特别是空间统计。但是我遇到了三个问题:

  • 多输出
  • 过度拟合和
  • 各向异性。

  • 让我使用meuse数据集(来自R包sp)运行一个简单的案例研究。

    更新:用于此问题并根据Grr's answer更新的Jupyter笔记本为here。
    import pandas as pd
    import numpy as np
    import matplotlib.pylab as plt
    %matplotlib inline
    
    meuse = pd.read_csv(filepath_or_buffer='https://gist.githubusercontent.com/essicolo/91a2666f7c5972a91bca763daecdc5ff/raw/056bda04114d55b793469b2ab0097ec01a6d66c6/meuse.csv', sep=',')
    

    例如,我们将重点放在铜和铅上。
    fig = plt.figure(figsize=(12,8))
    ax1 = fig.add_subplot(121, aspect=1)
    ax1.set_title('Lead')
    ax1.scatter(x=meuse.x, y=meuse.y, s=meuse.lead, alpha=0.5, color='grey')
    
    ax2 = fig.add_subplot(122, aspect=1)
    ax2.set_title('Copper')
    ax2.scatter(x=meuse.x, y=meuse.y, s=meuse.copper, alpha=0.5, color='orange')
    



    实际上,铜和铅的浓度是相关的。
    plt.plot(meuse['lead'], meuse['copper'], '.')
    plt.xlabel('Lead')
    plt.ylabel('Copper')
    



    因此,这是一个多输出问题。
    from sklearn.gaussian_process.kernels import RBF
    from sklearn.gaussian_process import GaussianProcessRegressor as GPR
    reg = GPR(kernel=RBF())
    reg.fit(X=meuse[['x', 'y']], y=meuse[['lead', 'copper']])
    predicted = reg.predict(meuse[['x', 'y']])
    

    第一个问题:当y具有一个以上的维时,是否为相关的多输出构建内核? 如果不是,我如何指定内核?

    我继续进行分析以显示第二个问题 overfitting :
    fig = plt.figure(figsize=(12,4))
    ax1 = fig.add_subplot(121)
    ax1.set_title('Lead')
    ax1.set_xlabel('Measured')
    ax1.set_ylabel('Predicted')
    ax1.plot(meuse.lead, predicted[:,0], '.')
    
    ax2 = fig.add_subplot(122)
    ax2.set_title('Copper')
    ax2.set_xlabel('Measured')
    ax2.set_ylabel('Predicted')
    ax2.plot(meuse.copper, predicted[:,1], '.')
    



    我创建了一个x和y坐标的网格,并且该网格上的所有浓度都被预测为零。

    最后,最后一个需要特别注意的问题是在3D土壤中:如何在此类模型中指定各向异性

    最佳答案

    首先,您需要拆分数据。训练模型,然后根据相同的训练数据进行预测,就像您观察到的那样看起来过拟合,但是您没有在任何保留的数据上测试模型,因此您不知道它在野外的性能如何。尝试使用 sklearn.model_selection.train_test_split 分割数据,如下所示:

    X_train, X_test, y_train, y_test = train_test_split(meuse[['x', 'y']], meuse[['lead', 'copper']])
    

    然后,您可以训练自己的模型。但是,您在那里也有问题。以这种方式训练模型时,最终会得到带有length_scale=1e-05的内核。基本上,您的模型中没有噪音。使用此设置所做的预测将非常紧密地围绕您的输入点(X_train)集中,您将无法对它们周围的站点进行任何预测。您需要更改alphaGaussianProcessRegressor参数来解决此问题。您可能需要对网格进行搜索,因为默认值为1e-10。例如,我使用了alpha=0.1
    reg = GPR(RBF(), alpha=0.1)
    reg.fit(X_train, y_train)
    predicted = reg.predict(X_test)
    
    fig = plt.figure(figsize=(12,4))
    ax1 = fig.add_subplot(121)
    ax1.set_title('Lead')
    ax1.set_xlabel('Measured')
    ax1.set_ylabel('Predicted')
    ax1.plot(y_test.lead, predicted[:,0], '.')
    
    ax2 = fig.add_subplot(122)
    ax2.set_title('Copper')
    ax2.set_xlabel('Measured')
    ax2.set_ylabel('Predicted')
    ax2.plot(y_test.copper, predicted[:,1], '.')
    

    结果如下图所示:



    如您所见,这里没有过度拟合的问题,实际上这可能是不合适的。就像我说的那样,您将需要在此模型上执行一些GridSearchCV来根据您的数据提出最佳设置。

    因此,回答您的问题:
  • 该模型可以很好地处理多路输出。
  • 过度拟合可以通过适本地分割数据或在不同的保留集上进行测试来解决。
  • 查看高斯过程指南的Radial Basis Function RBF Kernel部分,以获取有关应用各向异性内核而不是上面应用的各向同性内核的一些见解。

  • 更新评论中的问题

    当您编写“模型按原样可以很好地处理多个输出”时,您是在说模型“按原样”是为相关目标构建的,还是模型可以很好地处理独立输出的集合呢?

    好问题。根据我对GaussianProcessRegressor的了解,我认为它不能在内部存储多个模型。因此,这是一个单一模型。话虽这么说,您的问题有趣的是“为相关目标构建”的声明。在这种情况下,我们的两个目标似乎确实存在相当的相关性(皮尔逊相关系数= 0.818,p = 1.25e-38),因此我在这里确实看到了两个问题:
  • 对于相关数据,如果我们为两个目标以及单个目标建立模型,结果将如何比较?
  • 对于不相关的数据,以上内容是否成立?

  • 不幸的是,如果不创建新的“伪”数据集,我们将无法测试第二个问题,这在某种程度上超出了我们在此所做的工作。但是,我们可以很容易地回答第一个问题。使用我们相同的训练/测试组,我们可以训练两个具有相同超参数的新模型,以分别预测铅和铜。然后,我们可以同时使用这两个类来训练 MultiOutputRegressor 。最后将它们与原始模型进行比较。像这样:
    reg = GPR(RBF(), alpha=1)
    reg.fit(X_train, y_train)
    preds = reg.predict(X_test)
    reg_lead = GPR(RBF(), alpha=1)
    reg_lead.fit(X_train, y_train.lead)
    lead_preds = reg_lead.predict(X_test)
    reg_cop = GPR(RBF(), alpha=1)
    reg_cop.fit(X_train, y_train.copper)
    cop_preds = reg_cop.predict(X_test)
    multi_reg = MultiOutputRegressor(GPR(RBF(), alpha=1))
    multi_reg.fit(X_train, y_train)
    multi_preds = multi_reg.predict(X_test)
    

    现在,我们可以比较几种模型。让我们绘制预测并看看我们得到了什么。



    有趣的是,铅的预测中没有明显的差异,但铜的预测中有一些差异。而且这些仅存在于原始GPR模型和我们的其他模型之间。继续使用更多定量的误差度量,我们可以看到,对于已解释的方差,原始模型的性能要比MultiOutputRegressor稍好。有趣的是,铜模型的解释方差显着低于铅模型(实际上,这也对应于其他两个模型的各个组件的行为)。这都是非常有趣的,并会引导我们沿着多种不同的开发路线进入最终模型。

    我认为这里重要的一点是,所有模型迭代似乎都在同一个球场上,并且在这种情况下没有明显的赢家。在这种情况下,您将需要进行一些重要的网格搜索,并且可能需要实现各向异性内核,并且任何其他领域特定的知识都将有所帮助,但是由于它是我们的示例,与有用的模型相去甚远。

    https://stackoverflow.com/questions/43618633/

    相关文章:

    sql - 将前导零添加到 varchar 列

    java - 如果单例不好!为什么spring bean默认是单调的

    r - 每种可能组合的 Wilcoxon 秩和检验

    r - 交叉比较相同数据框的列

    java - 使用 Java 8 Streams 将 Map 的 Map 转换为 Lists

    r - R中的双重居中

    r - 为列名传递变量?

    junit4 - Wiremock 模拟返回 HTTP 500

    persistence - 在 Quartz 调度程序中看到异常导致作业无法运行

    r - 从 R 中的公式中提取模型框架时排除变量