Как организовать набор данных для классификации с несколькими переменными? - PullRequest
0 голосов
/ 10 мая 2018

Я сомневаюсь, как я должен подготовить свои данные обучения и метки для многомерной регрессии логистики, я пытался найти в Интернете, но большинство учебных пособий используют любую библиотеку, которая выполняет эту работу,

Так что, если мой набор данных выглядит так:

input_data                                                     labels 


[ 'aa' , 'bb' ,'cc' ,'dd' , 'ee' ]                         ['n1' ,'n5']
['rr' , 'ff' , 'gg' , 'hh' , 'ii' ,'jj']                   ['g1', 'g5']
['kk' , 'll' , 'mm' , 'nn' , 'oo' , 'pp]                   ['y1','y2','y3']
['qq','rr','ss','tt','uu'vv','ww']                         ['y1','y2','z1','z2']

Я строю словарный запас:

#building vocabulary

vocabulary = {'bb': 1, 'ff': 6, 'll': 12, 'hh': 8, 'rr': 18, 'tt': 20, 'gg': 7, 'vv': 22, 'jj': 10, 'nn': 14, 'qq': 17, 'kk': 11, 'cc': 2, 'mm': 13, 'ee': 4, 'ww': 23, 'ii': 9, 'oo': 15, 'ss': 19, 'uu': 21, 'pp': 16, 'aa': 0, 'dd': 3}

#building all labels list

labels =['y3', 'n1', 'g1', 'g5', 'y1', 'y2', 'n5', 'z1', 'z2']

Теперь следующим шагом я делаю заполнение данных:

# doing padding 


[0, 1, 2, 3, 4,0 ,0 ]                             

[18, 6, 7, 8, 9, 10,0]                              

[11, 12, 13, 14, 15, 16,0]                    

[17, 18, 19, 20, 21, 22, 23,0] 

Пока все в порядке, теперь путаница в том, как передать свои метки в нейронную сеть. С каждым входом связано несколько классов,

Должен ли я пойти с методом горячего кодирования:

padded  input_data                                              one_hot labels 

[0, 1, 2, 3, 4,  0, 0]               [0, 1, 0, 0, 0, 0, 1, 0, 0]    # ['n1' ,'n5']



[18, 6, 7, 8, 9, 10,0]                [0, 0, 1, 1, 0, 0, 0, 0, 0]    # ['g1', 'g5']


[11, 12, 13, 14, 15, 16,0]        [1, 0, 0, 0, 1, 1, 0, 0, 0]    # ['y1','y2','y3']


[17, 18, 19, 20, 21, 22, 23,0]   [0, 0, 0, 0, 1, 1, 0, 1, 1]  #['y1','y2','z1','z2']

или второй метод

[[0, 1, 0, 0, 0, 0, 0, 0, 0] ,  [0, 0, 0, 0, 0, 0, 1, 0, 0]]     # [ ['n1'] , ['n5'] ]




[ [0, 0, 1, 0, 0, 0, 0, 0, 0] ,   [0, 0, 0, 1, 0, 0, 0, 0, 0] ]    # [ ['g1'] , ['g5'] ]



[ [1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0] ]  # [ ['y1'] , ['y2'] ,['y3]]




[ [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1]]      #  [ ['y1'],['y2'],['z1'],['z2']]

или индексный метод

[0, 1, 2, 3, 4,  0, 0]                                        [1, 6]

[18, 6, 7, 8, 9, 10,0]                                      [2, 3]



[11, 12, 13, 14, 15, 16,0]                              [4, 5, 0]

[17, 18, 19, 20, 21, 22, 23,0]                        [4, 5, 7, 8]

Для одиночной классификации я использовал argmax из распределений вероятностей, таких как:

probs  = tf.nn.softmax(logits)
preds  = tf.argmax(probs, axis=-1)   #which gives the max probality 

распределение, которое является результатом

Но в мультиклассификации, как мы возьмем результат из распределения?

1 Ответ

0 голосов
/ 11 мая 2018

Для прогнозирования выходных данных, вместо того, чтобы просто брать максимум, как в задаче с одной меткой, вам нужно определить порог, выше которого все отмечены как 1.

Вот пример, иллюстрирующий проблему с несколькими метками:

# Sample inputs
y_a = tf.constant([[0, 1, 0, 0, 1, 0, 0, 1, 0]], tf.float32)
y_b = tf.constant([[0, 1, 0, 0, 0, 0, 0, 0, 0]], tf.float32)
logits = tf.constant([[0.2, 0.8, 0.4, 0.5, 0.8, 0.4, 0.2, 0.8, 0.4]], tf.float32) 
# Threshold for classification
thres = 0.7

loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=y_a))
loss_1 = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=y_b))
#Probs
probs  = tf.nn.sigmoid(logits)
# a threshold of 0.5, tf.round() should help
acc_thresh_0_5 = tf.reduce_mean( tf.cast(tf.equal(tf.round(probs), y_a), tf.float32))

# Variable threshold
binary_logits = tf.where(tf.less(probs, thres), tf.zeros(tf.shape(probs)), tf.ones(tf.shape(probs)))
acc_var_thresh = tf.reduce_mean( tf.cast(tf.equal(tf.round(binary_logits), y_a), tf.float32))


with tf.Session() as sess:
   print(loss.eval())              #0.7136336
   print(loss_1.eval())            #0.89141136
   print(acc_thresh_0_5.eval())    #1.0
   print(acc_var_thresh.eval())    #1.0
...