В прошлый раз мы говорили о методах NLP в PySpark. Сегодня рассмотрим методы нормализации и стандартизации данных модуля ML библиотеки PySpark. Читайте в нашей статье: применение Normalizer, StandardScaler, MinMaxScaler и MaxAbsScaler для нормализация и стандартизации данных.
Нормализация и стандартизация — методы шкалирования данных
Нормализация (normalization) и стандартизация (standardization) являются методами изменения диапазонов значений — шкалирования. Шкалирование особенно полезно в машинном обучении (Machine Learning), поскольку разные атрибуты могут измеряться в разных диапазонах, или значения одного атрибута варьируются слишком сильно. Например, один атрибут имеет диапазон от 0 до 1, а второй — от 1 до 1000. Для задачи регрессии второй атрибут оказывал бы большое влияние на обучение, хотя не факт, что он является более важным, чем первый. Нормализация и стандартизация отличаются своими подходами:
-
Нормализация подразумевает изменение диапазонов в данных без изменения формы распределения,
-
Стандартизация изменяет форму распределения данных (приводится к нормальному распределению).
Обычно достаточно нормализовать данные. Например, в глубоком обучении (Deep Learning) требуется перевести цвета изображений RGB из диапазона 0-255 к диапазону 0-1. А вот стандартизацию стоит применять при использование алгоритмов, которые основываются на измерении расстояний, например, k ближайших соседей или метод опорных векторов (SVM).
Normalizer: применение нормализации к строкам
Normalizer в PySpark необходим для нормализации не атрибутов (столбцов), а записей (строк) путем деления на p-норму [1]. Общая формула выглядит так:
p_norm = sum(X**p) ** (1/p) X = X / p_norm
Единственным параметром в этом виде нормализации является p
, причём
-
если p=1, то p-норма равна сумме значений каждой строки;
-
если p=∞, то p-норма равна максимальному значению в каждой строке.
Следующий код на Python демонстрирует результат при p=1:
from pyspark.ml.feature import Normalizer from pyspark.ml.linalg import Vectors dataFrame = spark.createDataFrame([ (0, Vectors.dense([1.0, 0.5, -1.0]),), (1, Vectors.dense([2.0, 1.0, 1.0]),), (2, Vectors.dense([4.0, 10.0, 2.0]),) ], ["id", "features"]) normalizer = Normalizer(inputCol="features", outputCol="normFeatures", p=1.0) l1NormData = normalizer.transform(dataFrame) print("Normalized using L^1 norm") l1NormData.show() # Normalized using L^1 norm +---+--------------+------------------+ | id| features| normFeatures| +---+--------------+------------------+ | 0|[1.0,0.5,-1.0]| [0.4,0.2,-0.4]| | 1| [2.0,1.0,1.0]| [0.5,0.25,0.25]| | 2|[4.0,10.0,2.0]|[0.25,0.625,0.125]| +---+--------------+------------------+
В случае же p=∞ нормализация в PySpark приводит к другим результатам:
lInfNormData = normalizer.transform(dataFrame, {normalizer.p: float("inf")}) print("Normalized using L^inf norm") lInfNormData.show() # Normalized using L^inf norm +---+--------------+--------------+ | id| features| normFeatures| +---+--------------+--------------+ | 0|[1.0,0.5,-1.0]|[1.0,0.5,-1.0]| | 1| [2.0,1.0,1.0]| [1.0,0.5,0.5]| | 2|[4.0,10.0,2.0]| [0.4,1.0,0.2]| +---+--------------+--------------+
Normalizer можно применять после атрибутивного шкалирования, о которых пойдёт речь дальше.
StandardScaler: приведение к нормальному распределению
StandardScaler в PySpark подразумевает приравнивание среднего значения к нулю и/или приравнивание стандартного отклонения к единице. В отличие от Normalizer применяется к атрибутам, т.е. к столбцам, а не строкам. Данный вид шкалирования стремится привести данные к нормальному распределению.
StandardScaler рассчитывается для каждого атрибута следующим образом:
z = (X – u) / s
где u
— среднее значение или 0 при with_mean=False
, s
— стандартное отклонение или 0 при with_std=False
.
Следующий код на Python показывает применение StandardScaler в PySpark:
from pyspark.ml.feature import StandardScaler scaler = StandardScaler(inputCol="features", outputCol="scaledFeatures", withStd=True, withMean=True) scalerModel = scaler.fit(dataFrame) scaledData = scalerModel.transform(dataFrame) scaledData.show() # +---+--------------+-------------------------------------------------------------+ |id |features |scaledFeatures | +---+--------------+-------------------------------------------------------------+ |0 |[1.0,0.5,-1.0]|[-0.872,-0.623,-1.091]| |1 |[2.0,1.0,1.0] |[-0.218,-0.529,0.218] | |2 |[4.0,10.0,2.0]|[1.091,1.153,0.872] | +---+--------------+-------------------------------------------------------------+
MinMaxScaler: приведение к диапазону [0,1]
MinMaxScaler в PySpark применяется для шкалирования в диапазоне [min,max]. Рассчитывается как
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) X_scaled = X_std * (max - min) + min # при min=0, max=1 => X_std = X_scaled
где min и max задаются как минимальное и максимальное допустимое значение, по умолчанию min=0, max=1. Вот так выглядит Python-код для такого вида нормализации:
from pyspark.ml.feature import MinMaxScaler scaler = MinMaxScaler(inputCol="features", outputCol="scaledFeatures") scalerModel = scaler.fit(dataFrame) scaledData = scalerModel.transform(dataFrame) print("Features scaled to range: [%f, %f]" % (scaler.getMin(), scaler.getMax())) scaledData.select("features", "scaledFeatures").show(truncate=False)
Результат нормализации данных в PySpark:
Features scaled to range: [0.000000, 1.000000] +--------------+-----------------------------------------------------------+ |features |scaledFeatures | +--------------+-----------------------------------------------------------+ |[1.0,0.5,-1.0]|[0.0,0.0,0.0] | |[2.0,1.0,1.0] |[0.3333333333333333,0.05263157894736842,0.6666666666666666]| |[4.0,10.0,2.0]|[1.0,1.0,1.0] | +--------------+-----------------------------------------------------------+
MaxAbsScaler: приведение к диапазону [-1,1]
С помощью MaxAbsScaler в PySpark значения атрибутов приводятся к диапазону [-1,1] путем деления на максимальное абсолютное значение каждого атрибута.
from pyspark.ml.feature import MaxAbsScaler dataFrame = spark.createDataFrame([ (0, Vectors.dense([1.0, 0.1, -8.0]),), (1, Vectors.dense([2.0, 1.0, -4.0]),), (2, Vectors.dense([4.0, 10.0, 8.0]),) ], ["id", "features"]) scaler = MaxAbsScaler(inputCol="features", outputCol="scaledFeatures") scalerModel = scaler.fit(dataFrame) scaledData = scalerModel.transform(dataFrame) scaledData.show()
В результате нормализации получились следующие значения:
+--------------+----------------+ | features| scaledFeatures| +--------------+----------------+ |[1.0,0.1,-8.0]|[0.25,0.01,-1.0]| |[2.0,1.0,-4.0]| [0.5,0.1,-0.5]| |[4.0,10.0,8.0]| [1.0,1.0,1.0]| +--------------+----------------
О нормализации и стандартизации в PySpark в рамках подготовки и анализа данных перед обучением алгоритмов Machine Learning вы узнаете на специализированном курсе «Курс Анализ данных с Apache Spark» в нашем лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.
Источники