如何在 Julia 中执行特征归一化?

问题描述

我为 Andrew Ng 在 Julia 的机器学习课程编写了一个“featurenormalize”函数

它适用于输入特征,但用于预测输出值,如果我输入为

predict = featurenormalize([1650 3])

输出

1×2 Matrix{Float64}:
 NaN  NaN


function featurenormalize(X)
    mu = mean(X,dims=1)
    sigma = std(X,dims=1)
    
    X_norm = (X .- mu) ./ sigma
    
    return X_norm
end

解决方法

您需要一个包含至少两个示例的数据集才能计算 std,否则将返回 NaN。如果你真的需要考虑这种极端情况,你可以在函数体中引入一个 if-else 分支。

,

您可能需要考虑有时您需要从归一化中跳过某些特征,或者您可能需要恢复归一化(当您对 y 进行归一化时)。

以下是说明这两种情况的示例(来自 BetaML.jl):


"""julia
    getScaleFactors(x;skip)
Return the scale factors (for each dimensions) in order to scale a matrix X (n,d)
such that each dimension has mean 0 and variance 1.
# Parameters
- `x`: the (n × d) dimension matrix to scale on each dimension d
- `skip`: an array of dimension index to skip the scaling [def: `[]`]
# Return
- A touple whose first elmement is the shift and the second the multiplicative
term to make the scale.
"""
function getScaleFactors(x;skip=[])
    μ  = mean(x,dims=1)
    σ² = var(x,corrected=false,dims=1)
    sfμ = - μ
    sfσ² = 1 ./ sqrt.(σ²)
    for i in skip
        sfμ[i] = 0
        sfσ²[i] = 1
    end
    return (sfμ,sfσ²)
end

"""
    scale(x,scaleFactors;rev)
Perform a linear scaling of x using scaling factors `scaleFactors`.
# Parameters
- `x`: The (n × d) dimension matrix to scale on each dimension d
- `scalingFactors`: A tuple of the constant and multiplicative scaling factor
respectively [def: the scaling factors needed to scale x to mean 0 and variance 1]
- `rev`: Whether to invert the scaling [def: `false`]
# Return
- The scaled matrix
# Notes:
- Also available `scale!(x,scaleFactors)` for in-place scaling.
- Retrieve the scale factors with the `getScaleFactors()` function
"""
function scale(x,scaleFactors=(-mean(x,dims=1),1 ./ sqrt.(var(x,dims=1))); rev=false )
    if (!rev)
      y = (x .+ scaleFactors[1]) .* scaleFactors[2]
    else
      y = (x ./ scaleFactors[2]) .- scaleFactors[1]
    end
    return y
end
function scale!(x,dims=1))); rev=false)
    if (!rev)
        x .= (x .+ scaleFactors[1]) .* scaleFactors[2]
    else
        x .= (x ./ scaleFactors[2]) .- scaleFactors[1]
    end
    return nothing
end