피쳐 추출과 변환
- 피쳐 값들을 모델 훈련에 적합한 형태로 바꾸는 것을 지칭
- 파이썬과 다르게 각각의 feature를 모델에 넣는 것이 아닌 feature를 하나의 vector로 묶어서 모델에 넣음
- 크게 두 가지가 존재: Feature Extractor와 Feature Transformer
- Feature Transformer
- https://spark.apache.org/docs/latest/ml-features.html#feature-transformers
- 피쳐 값들은 숫자 필드이어야함
- 텍스트 필드(카테고리 값들)를 숫자 필드로 변환해야함
- 숫자 필드 값의 범위 표준화
- 숫자 필드라고 해도 가능한 값의 범위를 특정 범위(0부터 1)로 변환해야 함
- 이를 피쳐 스케일링 (Feature Scaling) 혹은 정규화 (Normalization)라고 지칭
- 비어있는 필드들의 값은 Imputer 함수를 활용하여 채워넣어야함.
- Feature Extractor
- https://spark.apache.org/docs/latest/ml-features.html#feature-extractors
- 기존 피쳐에서 새로운 피쳐를 추출
- TF-IDF, Word2Vec, …
- 많은 경우 텍스트 데이터를 어떤 형태로 인코딩하는 것이 여기에 해당함
문자 카테고리형 데이터 처리
- StringIndexer, OneHotEncoder :텍스트 카테고리를 숫자로 변환
- 왼쪽과 같은 값을 갖는 Color라는 이름의 피쳐가 존재한다면 이를 오른쪽과 같은 숫자로 변환
- Scikit-Learn은 sklearn.preprocessing 모듈 아래 여러 인코더 존재
- OneHotEncoder, LabelEncoder, OrdinalEncoder, ...
- Spark MLlib의 경우 pyspark.ml.feature 모듈 밑에 두 개의 인코더 존재
- StringIndexer, OneHotEncoder
- 사용법은 Indexer 모델을 만들고(fit), Indexer 모델로 데이터프레임을 transform
StringIndexer
from pyspark.ml.feature import StringIndexer
gender_indexer = StringIndexer(inputCol='Gender', outputCol='GenderIndexed')
gender_indexer_model = gender_indexer.fit(final_data)
final_data_with_transformed = gender_indexer_model.transform(final_data)
- 아래 처럼 리스트를 사용하여 한번에 여러개의 컬럼을 인코딩할 수 있다.
- 차이점은 복수의 컬럼을 넣어줄 때는 인자이름이 inputCols, outputCols로 끝에 's'를 붙여주어야 한다.
from pyspark.ml.feature import StringIndexer
category_indexor = StringIndexer(inputCols=['Gender','Embarked'], outputCols=['GenderIndexed','EmbarkedIndexed'])
category_indexor_model = category_indexor.fit(final_data)
final_data_with_transformed = category_indexor_model.transform(final_data)
CF) Indextostring
- StringIndexer와 다르게 한번에 여러개의 컬럼을 변환할 수 없다. 즉 하나씩 일일이 바꾸어주어야 한다.
from pyspark.ml.feature import IndexToString
gender_indexer = IndexToString(inputCol='GenderIndexed', outputCol='Gender')
gender_indexer_model = gender_indexer.fit(final_data)
final_data_with_transformed = gender_indexer_model.transform(final_data)
OneHotEncoder
- Scikit-Learn에서는 문자열 형태의 컬럼을 그대로 넣어주면 알아서 내부적으로 레이블 인코딩을 호출하여 One Hot Vector로 변환
- 하지만 Spark OneHotEncoder는 문자열에서 숫자로 변환해주는 레이블 인코딩 작업을 필수로 수행해주어야 함.
- dropLast : True로 설정하면 one-hot-vector로 변환시 마지막 백터를 드랍한다.
- 모든 원소가 0일때도 하나의 값을 나타낼 수 있기 때문이기에, True로 설정하면 마지막 백터를 드랍한다.
변수의 인자 | dropLast = False | dropLast = True |
Red | [1,0,0] | [1,0] |
Orange | [0,1,0] | [0,1] |
Blue | [0,0,1] | [0,0] |
from pyspark.ml.feature import StringIndexer, OneHotEncoder
category_indexor = StringIndexer(inputCols=['Gender','Embarked'], outputCols=['GenderIndexed','EmbarkedIndexed'])
category_indexor_data = category_indexor.fit(final_data).transform(final_data)
one_hot_encoder = OneHotEncoder(inputCols=['GenderIndexed','EmbarkedIndexed'], outputCols=['Gender_onehot','Embarked_onehot'], dropLast=True)
encoding_df = one_hot_encoder.fit(category_indexor_data).transform(category_indexor_data)
encoding_df.show()
Scaling
- 숫자 필드 값의 범위를 특정 범위(예를 들면 0부터 1)로 변환하는 것
- 피쳐 스케일링 (Feature Scaling) 혹은 정규화 (Normalization)라 부름
- 사용법은 Scaler 모델을 만들고(fit), Scaler 모델로 데이터프레임을 transform
- StandardScaler
- 각 값에서 평균을 빼고 이를 표준편차로 나눔.
- 값의 분포가 정규분포를 따르는 경우 사용
- MinMaxScaler
- 모든 값을 0과 1사이로 스케일. 각 값에서 최소값을 빼고 (최대값-최소값)으로 나눔
StandardScaler
- WithMean, withStd인자를 True로 지정하면 평균이 0, 표준편차가 1인 표준정규분포형태로 값 Scaling
- False로 설정하면 수치형 값들의 실제 평균값으로 설정하여 정규화 수행
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.feature import StandardScaler, MinMaxScaler
assembler = VectorAssembler(inputCols=['Pclass', 'SibSp', 'Parch', 'Fare', 'AgeImputed', 'GenderIndexed'], outputCol='features')
data_vec = assembler.transform(final_data)
scaler = StandardScaler(inputCol = 'features', outputCol = 'feature_scaled', withMean=True, widStd=True)
df_scaled = scaler.fit(data_vec).transform(data_vec)
df_scaled.show()
MinMaxScaler
- 인자로 min값과 max값을 직접 지정할 수 있다.
- Default : min ->0, max -> 1
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.feature import StandardScaler, MinMaxScaler
assembler = VectorAssembler(inputCols=['Pclass', 'SibSp', 'Parch', 'Fare', 'AgeImputed', 'GenderIndexed'], outputCol='features')
data_vec = assembler.transform(final_data)
scaler = MinMaxScaler(inputCol = 'features', outputCol = 'feature_scaled', min=0, max=1)
df_scaled = scaler.fit(data_vec).transform(data_vec)
df_scaled.show()
Null값 채우기
- 값이 존재하지 않는 레코드들이 존재하는 필드들의 경우 기본값을 정해서 채우는 것. Impute한다고 부름
- Scikit-Learn은 sklearn.preprocessing 모듈 아래 존재
- Imputer
- Spark MLlib의 경우 pyspark.ml.feature 모듈 밑에 존재
- Imputer
- 사용법은 Imputer 모델을 만들고(fit), Imputer 모델로 데이터프레임을 transform
from pyspark.ml.feature import Imputer
imputer = Imputer(strategy='mean', inputCols=['Age'], outputCols=['AgeImputed'])
imputer_model = imputer.fit(final_data)
final_data_age_transformed = imputer_model.transform(final_data)
728x90
반응형
'Spark & Hadoop > SparkML' 카테고리의 다른 글
[SparkML] Spark ML Pipeline (DataFrame, Transformer, Estimator, Parameter) (1) | 2023.10.14 |
---|---|
[SparkML/Classification] 타이타닉 승객 생존 예측 분류 (Logistic Regression) (0) | 2023.10.14 |
[SparkML/Regression] 보스턴 주택가격 예측 예시 (Linear Regression) (0) | 2023.10.08 |
[SparkML] Spark ML이란 (1) | 2023.10.08 |