원-핫인코딩(One-Hot encoding)
대상이 되는 값에 1 그외의 값에 0을 지정하는 방식으로 인코딩합니다. 이러한 할당방식을 one-hot 인코딩이라 합니다. 예를 들어 변수에 할당된 목록 값이 female, male인 경우 다음과 같이 인코딩 됩니다.
female | male | |
female | 1 | 0 |
male | 0 | 1 |
그러므로 x=['female']인 경우 Onehotcoding에 의해 [1, 0]으로 변환됩니다. 이 변환은 pandas.get_dummies()
함수나 sklearn.preprocessing.OneHotEncoder()
클래스 또는 torch.funtional.one_hot()에 의해 실행할 수 있습니다.
위 함수들은 원-핫 인코딩을 위한 함수들들을 참조합니다.
다음 자료 x는 5개의 데이터와 고유값 3개(Na를 코딩에서 제외)를 포함합니다. 그러므로 다음과 같이 5행 3열의 결과가 되며 각각에 대응하는 위치에 1이 할당됩니다.
x=['a', 'c', 'z', 'a', np.nan] pd.get_dummies(x, dtype="int")
a | c | z | |
---|---|---|---|
0 | 1 | 0 | 0 |
1 | 0 | 1 | 0 |
2 | 0 | 0 | 1 |
3 | 1 | 0 | 0 |
4 | 0 | 0 | 0 |
pd.get_dummies(x, dummy_na=True)
a | c | z | NaN | |
---|---|---|---|---|
0 | True | False | False | False |
1 | False | True | False | False |
2 | False | False | True | False |
3 | True | False | False | False |
4 | False | False | False | True |
y=pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['b', 'a', 'c'], 'C': [1, 2, 3]}); y
A | B | C | |
---|---|---|---|
0 | a | b | 1 |
1 | b | a | 2 |
2 | a | c | 3 |
pd.get_dummies(y, dtype="int")
C | A_a | A_b | B_a | B_b | B_c | |
---|---|---|---|---|---|---|
0 | 1 | 1 | 0 | 0 | 1 | 0 |
1 | 2 | 0 | 1 | 1 | 0 | 0 |
2 | 3 | 1 | 0 | 0 | 0 | 1 |
pd.get_dummies(y, prefix=['c1', 'c2'], dtype="int")
C | c1_a | c1_b | c2_a | c2_b | c2_c | |
0 | 1 | 1 | 0 | 0 | 1 | 0 |
1 | 2 | 0 | 1 | 1 | 0 | 0 |
2 | 3 | 1 | 0 | 0 | 0 | 1 |
sklearn.preprocessing.OneHotEncoder()
클래스를 사용할 수 있습니다. 실행기전은 get_dummies()
와 같습니다.
X = [['male', 'asia', 'uses Safari'], ['female', 'Europe', 'uses Firefox']] xDf=pd.DataFrame(X, columns=["sex", "From","use"]); xDf
sex | From | use | |
0 | male | asia | uses Safari |
1 | female | Europe | uses Firefox |
ohc_dum=pd.get_dummies(xDf, dtype="int"); ohc_dum
sex_female | sex_male | From_Europe | From_asia | use_uses Firefox | use_uses Safari | |
0 | 0 | 1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 1 | 0 | 1 | 0 |
ohc_sk=preprocessing.OneHotEncoder().fit(X) print(ohc_sk.categories_)
[array(['female', 'male'], dtype=object), array(['Europe', 'asia'], dtype=object), array(['uses Firefox', 'uses Safari'], dtype=object)]
다음 코드 ohc_sk.transform()
은 다음과 같이 1로 변환된 결과만을 나타냅니다.
print(ohc_sk.transform(X))
(0, 1) 1.0 (0, 3) 1.0 (0, 5) 1.0 (1, 0) 1.0 (1, 2) 1.0 (1, 4) 1.0
위 결과는 .toarray()
메소드를 사용하여 array 형으로 변환하는 것으로 다음과 같이 모든 결과를 반환합니다.
print(ohc_sk.transform(X).toarray())
[[0. 1. 0. 1. 0. 1.] [1. 0. 1. 0. 1. 0.]]
다음 코드들은 python의 패키지인 torch의 funtional.one_hot() 함수에 의해 원-핫 인코딩을 실행한 것입니다.
import torch import torch.nn.functional as F x=torch.arange(0, 5) x
tensor([0, 1, 2, 3, 4])
F.one_hot(x)
tensor([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]])
x1=torch.randint(0, 12, size=(5,)) x1
tensor([ 0, 9, 4, 10, 1])
위 객체 x1의 각 요소는 하나의 행으로 변환되어 나타냅니다. 그러므로 변환된 객체의 모양은 (5, 11)이 됩니다.
F.one_hot(x1)
tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
one_hot()
함수에서 매개변수인 num_classes를 수동으로 지정한 경우입니다. 이 경우 x1의 최대값보다 커야 합니다. 변환된 객체의 모양은 (5, 12)이 됩니다.
F.one_hot(x1, num_classes=12)
tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
위의 X와 같이 문자열(string) 객체를 one-hot 인코딩을 위해 torch.one_hot()
함수를 적용하기 위해서는 문자 변수를 숫자로 전환할 필요가 있습니다. 이 전환은 sklearn.preprocessing의 LabelEncoder()
클래스를 적용합니다. 이 클래스에 전달하는 객체는 대상 자료의 모든 변수를 포함하는 1차원 벡터이어야 합니다. 예를 들어 위의 객체 X는 다음과 같이 (2, 3)형태의 2차원 객체입니다.
x=np.array(X) x
array([['male', 'asia', 'uses Safari'], ['female', 'Europe', 'uses Firefox']], dtype='< U12')
데이터내의 각 요소의 원-핫 인코딩을 위해서는 모든 값들에 대한 label encoding이 필요합니다. 그러므로 위 객체 x를 1차원 벡터로 전환하여 label을 전환합니다.
xVec=np.array(X).ravel() xVec
array(['male', 'asia', 'uses Safari', 'female', 'Europe', 'uses Firefox'], dtype='< U12')
LabelEcoder()
에 의해 전환된 labelencoder 객체를 각 대상에 적용합니다.
le=sklpre.LabelEncoder().fit(xVec) t0=torch.from_numpy(le.transform(x[0,:])) t0
tensor([3, 1, 5])
torch.one_hot()
에 전달하기 위해 tensor객체로 전환합니다.
t1=torch.from_numpy(le.transform(x[1,:])) t1
tensor([2, 0, 4])
t0oh=F.one_hot(t0) t0oh
tensor([[0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1]])
t1oh=F.one_hot(t1) t1oh
tensor([[0, 0, 1, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 1]])
댓글
댓글 쓰기