【问题标题】:Scaling wide range datas in scikit learn在 scikit learn 中缩放广泛的数据
【发布时间】:2018-12-14 18:21:57
【问题描述】:

我正在尝试使用来自 scikit learn 的 MLPregressor,以便对一组 260 个示例(X,Y)进行非线性回归。一个示例由 X 的 200 个特征和 Y 的 1 个特征组成。

File containing X

File containing Y

如果直接绘制在一起,X 和 Y 之间的联系并不明显,但如果我们绘制 x=log10(sum(X)) 和 y=log10(Y),两者之间的联系几乎是线性的。 作为第一种方法,我尝试将我的神经网络直接应用于 X 和 Y,但没有成功。

我已经读到缩放会改善回归。在我的例子中,Y 包含的数据范围很广(从 10e-12 到 10e-5)。在计算误差时,当然 10e-5 比 10e-12 重得多。但我希望我的神经网络能够正确地近似两者。使用线性缩放时,假设来自 scikit learn 的 preprocessing.MinMaxScaler,10e-8 ~ -0.99 和 10e-12 ~ -1。所以我失去了目标的所有信息。

我的问题是:我可以使用什么样的缩放来获得一致的结果? 我找到的唯一解决方案是应用 log10(Y) 但当然,错误会成倍增加。

我能得到的最好的就是下面的代码:

    from sklearn.neural_network import MLPRegressor
    from sklearn.svm import SVR
    import numpy as np
    import matplotlib.pyplot as plt

    plt.rcParams["figure.figsize"]=(20,10)

    freqIter=[]
    for i in np.arange(0,0.2,0.001):
        freqIter.append([i,i+0.001])
#############################################################################

    X = np.zeros((len(learningFiles),len(freqIter)))
    Y = np.zeros(len(learningFiles))

    # Import X: loadtxt()
    # Import Y: loadtxt

    maxy = np.amax(Y)
    Y *= 1/maxy
    Y = Y.reshape(-1, 1)

    maxx = np.amax(X)
    X *= 1/maxx

    #############################################################################

    reg = MLPRegressor(hidden_layer_sizes=(8,2),  activation='tanh', solver='adam', alpha=0.0001, learning_rate='adaptive', max_iter=10000, verbose=False, tol = 1e-7)

    reg.fit(X, Y)

    #############################################################################

    plt.scatter([np.log10(np.sum(kou*maxx)) for kou in X],Y*maxy,label = 'INPUTS',color='blue')
    plt.scatter([np.log10(np.sum(kou*maxx)) for kou in X],reg.predict(X)*maxy,label='Predicted',color='red')
    plt.grid()
    plt.legend()
    plt.show()

结果:

感谢您的帮助。

【问题讨论】:

  • 日志似乎适合所有数据,有什么问题?
  • 首先,您可以看到我的近似值不好,尤其是在 0 和 1 之间。然后,在对数刻度中出现错误会极大地增加正常刻度中的误差。我期待 scikit learn 有一些工具,但我找不到。

标签: python scikit-learn


【解决方案1】:

您可能想查看FunctionTransformer。给出的示例应用对数变换作为预处理的一部分。您也可以对任意数学函数执行此操作。

如果您以对数方式缩放,我还建议您尝试使用 ReLU 激活函数。转换后,您的数据看起来相当线性,因此收敛速度可能会快一些——但这只是一种预感。

【讨论】:

  • 谢谢,我想我不会再进一步​​讨论缩放了。但正如您在我的结果中看到的那样,当 log10(sum(X)) 介于 0 和 1 之间(因此 Y 约为 10e-12)时,我不适合。但是,如果我还缩放我的输入 X,我会失去我的关系 log(sum(X)) 并且 sum(log(X)) 不起作用。还有其他提示吗?
  • 这是在黑暗中拍摄的,但您可能想在对数缩放后尝试polynomial features。这可能允许您尝试围绕对数拟合对噪声进行建模。
  • 有 200 个特征,这将代表重新缩放后的 1.6e60 个特征。即使这个想法听起来不错,我也认为这太过分了。或者也许我不明白这种重新调整是如何工作的。
  • 如果你有很多特性,你可能想看看 sklearn 的一些dimensionality reduction 方法。生成多项式特征在某种意义上是相反的——它增强了特征,因此您可以尝试对隐藏的交互进行建模。
  • 好的,但是降维意味着丢失信息。在我的 X 中显示了每个频率范围的频谱值。降低维度意味着丢失某些频率范围的信息。实际上我的主要问题是在我的输入 X 上找到一个智能缩放,以便我可以正确匹配我的 Y。在某些情况下,X 特征非常小,导致 Y 非常小。当我应用 log10(Y) 时,Y 被正确缩放。但是如果我应用 log10(X),我就会失去线性度。我不知道该怎么办...
【解决方案2】:

我终于找到了一些有趣的东西,对我的情况很有效。 首先,我对 Y 使用了对数缩放。我认为当值的范围非常宽时,例如我的(从 10e-12 到 10e-5),它是最适合的缩放。目标在 -5 和 -12 之间。 其次,我关于缩放 X 的错误是将相同的缩放应用于所有特征。假设我的 X 包含 200 个特征,然后我除以所有示例的所有特征的最大值。我的解决方案是通过所有示例将 feature1 缩放到所有 feature1 的最大值,然后对所有功能重复它。对于所有示例,这使我的 feature1 介于 0 和 1 之间,而不是以前的更少(在我之前的缩放中,feature1 可能介于 0 和 0.0001 之间)。 我得到了更好的结果,我现在的主要问题是选择正确的参数(层数,公差,...),但这是另一个问题。

【讨论】:

    猜你喜欢
    • 2012-10-30
    • 2015-06-22
    • 1970-01-01
    • 2018-11-05
    • 2015-04-14
    • 2018-09-07
    • 2019-01-10
    • 2013-07-01
    • 2021-06-30
    相关资源
    最近更新 更多