【机器学习与实战】回归分析与预测 之 AI通识:数据归一化处理

92 阅读7分钟

AI通识:数据归一化处理

配套视频课程:www.bilibili.com/video/BV1Rx…

领取全套教材、资料包与源码请+ AIxiaoyun0000

一、Softmax归一化

Softmax是一种数学函数,通常用于将一组任意实数转换为表示概率分布的实数。其本质上是一种归一化函数,可以将一组任意的实数值转化为在[0, 1]之间的概率值,因为softmax将它们转换为0到1之间的值,所以它们可以被解释为概率。如果其中一个输入很小或为负,softmax将其变为小概率,如果输入很大,则将其变为大概率,但它将始终保持在0到1之间。

Softmax是逻辑回归的一种推广,可以用于多分类任务,其公式与逻辑回归的sigmoid函数非常相似。只有当分类是互斥的,才可以在分类器中使用softmax函数,也就是说只能是多元分类(即数据只有一个标签),而不能是多标签分类(即一条数据可能有多个标签)。

许多多层神经网络输出层的最后一层是一个全连接层,输出是一个实数向量,这个向量通常代表了每个类别的得分或置信度。为了将这些得分转换为概率分布,通常会使用softmax函数。因为它将分数转换为规范化的概率分布,可以显示给用户或用作其他系统的输入。所以通常附加一个softmax函数在神经网络的最后一层之后。

softmax函数的输入是一个包含K个元素的向量,其中不带箭头的z表示向量的一个元素:

1.png

Softmax的分子将指数函数应用于向量的每个元素,对于最高的输入值返回最高的输出值。因为它的范围是(0,∞),所以任何负数也变成正数。就是说,e的任意次方,必然是0或者一个正数。这样就可以很好的解决归一化后取值为0-1之间。

自然对数e的值为2.71828,也可以引用python中的math.e,输出为更精确的值:2.718281828459045

Softmax分母中的求和是通过确保函数的和为1来标准化每个元素,创建一个概率分布。所有的指数元素加在一起,所以当每个指数元素除以这个和时,它将是它的一个百分比。[5,7,10]的指数元素之和如下:

2.png

比如要计算第2个向量7的归一化结果,则运算过程如下:

σ([5,7,10])2=e7e5+e7+e10=0.047\huge \sigma([5,7,10])_2 = \frac{e^7}{e^5+e^7+e^{10}} = 0.047

当然,公式也可以由以下方式来表达,本质是一样的:

给定一个n维向量,softmax函数将其映射为一个概率分布。标准的softmax函数由下面的公式定义[1]:

3.png

直观上看,标准softmax函数用一个自然底数 e 先拉大了输入值之间的差异,然后使用一个配分将其归一化为一个概率分布。在分类问题中,我们希望模型分配给正确的类别的概率接近1,其他的概率接近0,如果使用线性的归一化方法,很难达到这种效果,而softmax有一个先拉开差异再归一化的“两步走”战略,因此在分类问题中优势显著。

事实上,在势能函数和配分函数中,可以采用的底数不仅仅是自然底数 e ,也可以采用一些其他的底数。原则上,任意 >0 的数都可以作为这里的底数,越大的底数越能起到“拉开差异”的作用。

二、使用Python原生实现

任意假定一个向量(在Python中可以使用列表或元组来表示),比如 list = [5, 7, 10, 9, 8, 2, 12, 15, 6],现通过Softmax函数分别计算每一个向量的概率分布,代码如下:

import math
def softmax(list):
    # 先求分母的总和,输出为:3466538.535767658
    sum = 0
    for m in list:
        sum += math.pow(math.e, m)
        # sum += math.exp(m)   # 或直接调用math.exp完成运算
    # 再遍历每一个元素,求出其概率,并添加到新的列表中
    result = []
    for n in list:
        z = math.pow(math.e, n) / sum
        # result.append("{:.8f}".format(z))    # 保留8位小数,该操作会将其转换为字符串
        # result.append(format(z, ".8f"))
        result.append(round(z, 8))             # 会出现科学计数法表示,不影响使用
    return result
if __name__ == '__main__':
    list = [5, 7, 10, 9, 8, 2, 12, 15, 6]
    list = softmax(list)
    print(list)

以上代码的输出结果为:

[4.281e-05, 0.00031635, 0.00635402, 0.00233751, 0.00085992, 2.13e-06, 0.04695023, 0.94302064, 0.00011638]

以上代码涉及两次针对list列表的遍历和运算,所以可以使用列表推导式进行代码简化。

三、使用numpy库来实现

1、最简化版本
def softmax_3(list):
    numpy.set_printoptions(suppress=True)
    matrix = numpy.array(list, dtype=float)
    sum = 0
    for n in matrix:
        sum += math.exp(n)
    print(sum)
    for i in range(matrix.size):
        # 直接修改matrix元素的值为概率值,覆盖了matrix原本的值,节省内存空间
        matrix[i] = math.exp(matrix[i]) / sum
    return matrix
2、只为利用一下numpy的特征
import numpy
def softmax_2(list):
    # 禁止使用科学计数法来表示数字,看起来比较不方便
    numpy.set_printoptions(suppress=True)
    matrix = numpy.array([list]) # 构建为二维数组 [[5, 7, 10, 9, 8, 2, 12, 15, 6]]
    m, n = numpy.shape(matrix)      # m表示第一维的个数, n为9,表示第二维的个数
    # numpy.zeros,生成一个均为0的二维矩阵,里面有第一维是m个,第二维是n个, [[0. 0. 0. 0. 0. 0. 0. 0. 0.]]
    zeros = numpy.zeros((m,n), dtype=float)
    print(zeros)
    # numpy.mat 将期转换为matrix矩阵类型,便于后续运算
    out_matrix = numpy.mat(zeros)
    sum = 0
    for i in range(0, n):
        out_matrix[0, i] = math.exp(matrix[0, i])
        sum += out_matrix[0, i]
    for j in range(0, n):
        out_matrix[0, j] = out_matrix[0, j] / sum
    return out_matrix

输出结果为:

[[0.00004281 0.00031635 0.00635402 0.00233751 0.00085992 0.00000213
  0.04695023 0.94302064 0.00011638]]

四、其他数据标准化

1、Min-Max标准化

这种方法将数据线性地映射到[0,1]的范围内。

x=xminAmaxAminA\huge x’ = \frac{x-minA}{maxA-minA}

2、平均值标准化

这种方法将数据线性地映射到[-1,1]的范围内。

x=xmeanAmaxAminA\huge x’ = \frac{x-meanA}{maxA - minA}

3、Z-Score标准化

这种方法将数据转化为标准正态分布,均值为0,标准差为1。

z=xmeanstd\huge z = \frac{x-mean}{std}

其中x是原始数据,mean是原始数据的均值,std是原始数据的标准差。

4、均值方差标准化

这种方法将数据转化为均值为0,方差为1的分布

z=xmeansqrt(var)\huge z = \frac{x - mean}{sqrt(var)}

其中x是原始数据,mean是原始数据的均值,var是原始数据的方差。

5、Sigmoid标准化

这种方法将数据通过Sigmoid函数映射到[0,1]范围内

g(z)=11+ez\huge g(z) = \frac{1}{1+e^{-z}}

请使用Python或Numpy将以上公式用代码实现,并观察其规律。

五、在SKLearn中实现标准化

4.webp

  • MinMaxScaler:归一化去量纲处理,适用于数据有明显的上下限,不会存在严重的异常值,例如考试得分0-100之间的数据可首选归一化处理
  • StandardScaler:标准化去量纲处理,适用于可能存在极大或极小的异常值,此时用MinMaxScaler时,可能因单个异常点而将其他数值变换的过于集中,而用标准正态分布去量纲则可有效避免这一问题
  • Binarizer:二值化处理,适用于将连续变量离散化
  • OneHotEncoder:独热编码,一种经典的编码方式,适用于离散标签间不存在明确的大小相对关系时。例如对于民族特征进行编码时,若将其编码为0-55的数值,则对于以距离作为度量的模型则意味着民族之间存在”大小”和”远近”关系,而用独热编码则将每个民族转换为一个由1个”1”和55个”0”组成的向量。弊端就是当分类标签过多时,容易带来维度灾难,而特征又过于稀疏
  • Ordinary:数值编码,适用于某些标签编码为数值后不影响模型理解和训练时。例如,当民族为待分类标签时,则可将其简单编码为0-55之间的数字
from sklearn.preprocessing import MinMaxScaler
nd1 = numpy.array([1,2,3,4,5,6])
nd2 = nd1.reshape(-1, 1)
mm = MinMaxScaler()
list3 = mm.fit_transform(nd2)
print(list3)

配套视频课程:www.bilibili.com/video/BV1Rx…

领取全套教材、资料包与源码请+ AIxiaoyun0000