[Python] 실습 Categorical 변수를 Embedding 해보기

2019. 5. 20. 23:46분석 Python/Tensorflow

728x90

https://data-newbie.tistory.com/90?category=749566

 

NN에서 Categorical Variables에 대해서는 어떻게 해야할까?

현재 Neural Network는 주로 이미지나 비디어 같이 Unconstructed Data에 대해서 Convolution을 사용해서 feature의 Parameter 개수를 축약하면서 Wide한 구조로 만들 수 데이터에 대한 Representation을 layer에..

data-newbie.tistory.com

 

이번에는 실습을 해보려고 합니다.

이것의 배경에 대해서는 위에 있으니, 참고해주시면 감사하겠습니다.

 

일단 직관적인 설명은 Categorical를 Embedding을 통해 더 낮은 차원으로 Embedding을 해줍니다.

곧 word2vec 같은 느낌으로 생각해주시면 됩니다.

 

실제 할 것은 Location을 RainTomorrow에 따라서 embedding을 시켜서 변수로 써보는 것이 목적입니다.

X = df["Location"]
label = df["RainTomorrow"]
encoder = LabelEncoder()
X = encoder.fit_transform(X.values)
print(X)

## [17 41  8 ... 41 21 36]

일단 labelencoder를 통해서 숫자로 변환합니다. 

마찬가지로 target도 해주고 onehot을 해줍니다.

label = df["RainTomorrow"]
LABEL = encoder.fit_transform(label.values)
Y = np.zeros((len(df), 2))
Y[np.arange(len(df)), LABEL] = 1
training_epochs = 10000
learning_rate = 1e-3
cardinality = len(np.unique(X)) 
embedding_size = int( math.ceil(len(np.unique(X))/2) )
n_labels = len(np.unique(Y))
n_hidden = 15
n_hidden2 = 10
print(cardinality , embedding_size , n_labels)
## 49 25 2

보시면 실제 Location은 49개인데 이것을 embedding을 25로 하겠다는 것입니다.

model을 이제 define 하는데 , Layer를 쌓아줍니다.

from IPython.display import clear_output
tf.reset_default_graph()
x = tf.placeholder(tf.int32, [None], name="input_x")
y = tf.placeholder(tf.float32, [None, 2], name="input_y")

# Neural network weights
embeddings = tf.Variable(tf.random_uniform([cardinality, embedding_size], -1.0, 1.0))
h = tf.get_variable(name='h2', shape=[embedding_size, n_hidden],
                    initializer=tf.contrib.layers.xavier_initializer())
bias = tf.get_variable(name='b2', shape=[n_hidden],
                    initializer=tf.constant_initializer(0.01))
h2 = tf.get_variable(name='h3', shape=[n_hidden, n_hidden2],
                    initializer=tf.contrib.layers.xavier_initializer())
W_out = tf.get_variable(name='out_w', shape=[n_hidden2, n_labels],
                        initializer=tf.contrib.layers.xavier_initializer())
b_out = tf.get_variable(name='out_b', shape=[n_labels],
                        initializer=tf.constant_initializer(0.01) )
###
W_out_v2 = tf.get_variable(name='out_w_v2', shape=[embedding_size, n_labels],
                        initializer=tf.contrib.layers.xavier_initializer())

# Neural network operations
embedded_chars = tf.nn.embedding_lookup(embeddings, x)
print(embedded_chars)
############### version1
layer_1 = tf.matmul(embedded_chars , h  ) + bias
layer_1 = tf.nn.leaky_relu(layer_1)
layer_2 = tf.matmul(layer_1, h2)
layer_2 = tf.nn.leaky_relu(layer_2)
out_layer = tf.matmul(layer_2, W_out) + b_out

Loss Define Run!

cost      = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out_layer, labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# Initializing the variables
batch_size = 256
init = tf.global_variables_initializer()
# Launch the graph
with tf.Session() as sess:
    sess.run(init)

    for epoch in range(training_epochs):
        # Run optimization op (backprop) and cost op (to get loss value)
        avgcost = 0
        for n in range(0,  (len(X) // batch_size) * batch_size,  batch_size):
            _, c  = sess.run([optimizer, cost],
                             feed_dict={x: X[n: n + batch_size ],y: Y[n: n + batch_size,:]})
            avgcost += c
        
        avgcost /= (len(X) // batch_size)
        
        if epoch % 100 == 0 :
            twodim = sess.run(embeddings,feed_dict={x: X, y: Y})
            plt.scatter(twodim[:,0] , twodim[:,1])
            plt.title( "cost : " + str(avgcost) , fontsize= 10 )
            plt.show()
            #print(c)
        if epoch % 500 == 0 :
            clear_output()
print("Optimization Finished!")

 일단 현재 49 -> 25차원으로 줄였지만,

앞에 2개의 컬럼만 빼서 시각화 중이다.

Loss는 멀 해도 0.5에서 유지된다...

 

으흠 잘된건지... 한 개 Layer로 해도 0.5 근처에 나온다.

한계가 있는건지 모르겠다.

 

암튼 이런식으로 한 개 기준으로 해봤다.

 

실제 목표는 저렇게 Embedding 한 다음 Dense 하게 만들어서 

모델의 쓸데없는 변수의 개수를 줄이고 싶은 것이 목적이다.

 

https://stackoverflow.com/questions/34870614/what-does-tf-nn-embedding-lookup-function-do

 

What does tf.nn.embedding_lookup function do?

tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None) I cannot understand the duty of this function. Is it like a lookup table? Which means to return the parameters correspondin...

stackoverflow.com

https://github.com/phamdinhthang/neural_embedder/blob/master/NeuralEmbedder.py

 

phamdinhthang/neural_embedder

Tensorflow implementation of Categorical Variable encoder, using Shallow Neural Network entity embedding - phamdinhthang/neural_embedder

github.com

https://stackoverflow.com/questions/43574889/tensorflow-embedding-for-categorical-feature

 

Tensorflow embedding for categorical feature

In machine learning, it is common to represent a categorical (specifically: nominal) feature with one-hot-encoding. I am trying to learn how to use tensorflow's embedding layer to represent a categ...

stackoverflow.com

https://yashuseth.blog/2018/07/22/pytorch-neural-network-for-tabular-data-with-categorical-embeddings/

불러오는 중입니다...
728x90