python的按列归一化_python

 在很多机器学习数据挖掘的项目中,都免不了要去构建特征工程,在面临特征选择的时候经常会出现我们所提取到的不同的特征维度的数据本身的量纲或者是取值范围是不同的,比如我们在对人的属性建模的时候,人的体温取值都是在36-45之间,但是人的薪资确实可以差异很大,不同量纲对于模型的收敛速度和精度都会带来一定的影响,具体的分析可以网上差一些资料仔细看下就会懂了,这个不是本文的主要内容,在我之前的很多做时间序列的项目中都会用到数据的归一化处理,比如:股票预测、气象预测、海洋水文预测、风光发电预测等等,在时间序列预测任务中又主要分为:单变量数据预测和多变量序列数据预测,一般都是需要对其进行尺度归一化处理后再送入模型中的,最近私信有几位同学在咨询时间序列预测建模里面的相关问题,其中问到一个共性问题就是尺度归一化这个,今天正好有时间就吧这一块专门整理抽取了出来将我实现好的方法拿出来,可以直接使用。

本文主要是基于原生实现方式以及基于numpy库的实现方式两种方法来分别实现了数据归一化操作,我在写这篇文章的试试也有查询过一些资料,我自己的习惯是对于多变量维度的数据集做的都是按列进行的归一化,之后再转置回去即可,但是有些场景里面可能因为数据本身的量纲差异没有那么大或者说是特定场景的需要就是按照整体归一化实现的,而并没有像我一样区分得那么详细,这里为了对比分析,我都实现了。

首先来看第一种方式:

def matrixNormalization(matrix):
    """
    矩阵数据归一化--特征数据按列归一化处理
    """
    temp = []
    for i in range(len(matrix[0])):
        one_col_list = [one_row[i] for one_row in matrix]
        oneMinV, oneMaxV = min(one_col_list), max(one_col_list)
        one_tmp_col = []
        for j in range(len(one_col_list)):
            one_value = one_col_list[j]
            one_new = singleNormalize(one_value, oneMinV, oneMaxV)
            one_tmp_col.append(one_new)
        temp.append(one_tmp_col)
    result = []
    for k in range(len(temp[0])):
        one_col_list = [one_row[k] for one_row in temp]
        result.append(one_col_list)
    return result



def numpyNormalization(matrix):
    """
    基于Numpy实现矩阵数据归一化--特征数据按列归一化处理
    """
    temp = []
    for i in range(len(matrix[0])):
        one_col_list = np.array([one_row[i] for one_row in matrix])
        oneMinV, oneMaxV = one_col_list.min(), one_col_list.max()
        one_tmp_col = (one_col_list - oneMinV) / (oneMaxV - oneMinV)
        temp.append(one_tmp_col)
    result = []
    for k in range(len(temp[0])):
        one_col_list = [one_row[k] for one_row in temp]
        result.append(one_col_list)
    return result

测试数据如下:

matrix = [[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 0]]

测试执行:

result1 = matrixNormalization(matrix)
result2 = numpyNormalization(matrix)
print("result1: ", result1)
print("result2: ", result2)
print("Judge: ", result1 == result2)

结果如下:

result1:  [[0.0, 0.0, 0.0, 0.5714285714285714], [0.5, 0.5, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]]
result2:  [[0.0, 0.0, 0.0, 0.5714285714285714], [0.5, 0.5, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]]
Judge:  True

接下来看第二种方法:

def matrixNormalization2(matrix):
    """
    矩阵数据归一化--特征数据整体归一化处理
    """
    allData = []
    for one_row in matrix:
        allData += one_row
    minV, maxV = min(allData), max(allData)
    result = []
    for i in range(len(matrix)):
        one_new_row = []
        for j in range(len(matrix[i])):
            one_value = matrix[i][j]
            one_new = singleNormalize(one_value, minV, maxV)
            one_new_row.append(one_new)
        result.append(one_new_row)
    return result



def numpyNormalization2(matrix):
    """
    基于Numpy实现矩阵数据归一化--特征数据整体归一化处理
    """
    matrix = np.array(matrix)
    minV = matrix.min()
    maxV = matrix.max()
    result = (matrix - minV) / (maxV - minV)
    return result

测试数据同上,测试执行如下:

result3 = matrixNormalization2(matrix)
result4 = numpyNormalization2(matrix)
print("result3: ", result3)
print("result4: ", result4)
print("Judge: ", result3 == result4)

结果如下所示:

result3:  [[0.1111111111111111, 0.2222222222222222, 0.3333333333333333, 0.4444444444444444], [0.4444444444444444, 0.5555555555555556, 0.6666666666666666, 0.7777777777777778], [0.7777777777777778, 0.8888888888888888, 1.0, 0.0]]
result4:  [[0.11111111 0.22222222 0.33333333 0.44444444]
 [0.44444444 0.55555556 0.66666667 0.77777778]
 [0.77777778 0.88888889 1.         0.        ]]
Judge:  [[ True  True  True  True]
         [ True  True  True  True]
         [ True  True  True  True]]

可以看到:代码判断的基于原生实现的方式和基于numpy库实现的两种归一化方式得到的结果是完全相同的,其实就我本身而言,更习惯自己实现,这样可以非常细致地了解到具体是怎么工作的,对于后续的建模也有一定的帮助。