희소 행렬과 다중 레이블 출력을 모두 지원하는 로지스틱 회귀?

금연 건강 증진 협회

저는 sklearn의 SGDClassifier 및 LogisticRegression을 많이 사용했습니다. 이제 문제가 있습니다. 1- 희소 행렬로 작업 (sklearn 지원) 2- 다중 레이블 인스턴스 (각 인스턴스의 레이블이 0/1 지표가 아닌 모든 레이블에 대한 확률 분포).

예를 들어 샘플 1의 레이블은 다음과 같을 수 있습니다.

0.1 0.0 0.4 0.5

즉, 4 개의 레이블에 대해 확률 분포가 있으며이를 0/1로 만들기 위해 임계 값을 사용해서는 안됩니다.

누구든지 그것을 달성하기 위해 sklearn의 선형 모델을 수정하는 방법을 알고 있습니까? 아니면 다중 출력 인스턴스를 지원하는 다른 라이브러리가 있습니까?

참고 : lasagne / theano에서 다중 출력 로지스틱 회귀를 구현했지만 희소 행렬을 허용하지 않으며 sklearn에 비해 매우 느립니다.

금연 건강 증진 협회

업데이트 2 : 미니 배치의 크기를 20에서 1000으로 늘리면 최적화가 훨씬 빨라집니다. 그래서 저는이 솔루션을 고수 할 것이라고 생각합니다.

Update1 : 다음 솔루션은 너무 느립니다.

해결책 :

마지막으로 Lasagne를 사용하여 희소 행렬을 입력으로 받아들이고 다중 출력 인스턴스 (예 : 레이블에 대한 확률 분포)를 대상 값으로 지원하는 로지스틱 회귀 모델을 구현했습니다. 코드는 다음과 같습니다. lasagne.layers.sparse의 두 클래스 를 내 코드에 직접 복사 했습니다.이 코드는 lasagne가 업데이트 된 버전 인 경우 필요하지 않습니다.

주요 아이디어는 모든 DenseLayer 및 DropoutLayer 대신 해당 클래스 SparseInputDenseLayer 및 SparseInputDropoutLayer를 사용해야한다는 것입니다. 입력 레이어는 변경되지 않은 상태로 유지되므로 혼란 스러웠습니다. 입력 레이어의 변경을 예상했지만 입력 레이어와 관련된 모든 계산이 다음 레이어 (숨겨진 레이어 또는 출력 레이어)에서 발생하므로 두 번째 수준의 레이어가 언급 된대로 변경됩니다.

로지스틱 회귀는 하나 이상의 조밀 한 계층을 추가하여 MLP로 쉽게 변환 할 수 있습니다.

변경되는 유일한 레이어는 입력 레이어 바로 뒤의 레이어이며 다른 레이어는 변경되지 않습니다.

나는 또한 sklearn의 gmlnet (python wrapper) 및 MLPClassifier로 실험했지만 내 지식으로는 1d 대상 레이블 또는 1/0 다중 출력 레이블 만 지원하고 레이블 확률 분포를 대상으로 허용하지 않습니다.

'''
Created on 22 Apr 2016

@author: af
'''

import pdb
import numpy as np
import sys
from os import path
import scipy as sp
import theano
import theano.tensor as T
import lasagne
from lasagne.regularization import regularize_layer_params_weighted, l2, l1
from lasagne.regularization import regularize_layer_params
import theano.sparse as S
from lasagne.layers import DenseLayer, DropoutLayer
sys.path.append(path.abspath('../geolocation'))
import params
import geolocate
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO)

class SparseInputDenseLayer(DenseLayer):
    def get_output_for(self, input, **kwargs):
        if not isinstance(input, (S.SparseVariable, S.SparseConstant,
                                  S.sharedvar.SparseTensorSharedVariable)):
            raise ValueError("Input for this layer must be sparse")

        activation = S.dot(input, self.W)
        if self.b is not None:
            activation = activation + self.b.dimshuffle('x', 0)
        return self.nonlinearity(activation)
class SparseInputDropoutLayer(DropoutLayer):
    def get_output_for(self, input, deterministic=False, **kwargs):
        if not isinstance(input, (S.SparseVariable, S.SparseConstant,
                                  S.sharedvar.SparseTensorSharedVariable)):
            raise ValueError("Input for this layer must be sparse")

        if deterministic or self.p == 0:
            return input
        else:
            # Using Theano constant to prevent upcasting
            one = T.constant(1, name='one')
            retain_prob = one - self.p

            if self.rescale:
                input = S.mul(input, one/retain_prob)

            input_shape = self.input_shape
            if any(s is None for s in input_shape):
                input_shape = input.shape

            return input * self._srng.binomial(input_shape, p=retain_prob,
                                               dtype=input.dtype)


def load_data():
    from sklearn.datasets import fetch_20newsgroups
    from sklearn.feature_extraction.text import TfidfVectorizer
    #categories = ['alt.atheism', 'talk.religion.misc', 'comp.graphics', 'sci.space']
    categories = None 
    #remove = ('headers', 'footers', 'quotes')
    remove = ()
    train_set = fetch_20newsgroups(subset='train', 
                                   remove=remove,
                                   categories=categories)
    test_set = fetch_20newsgroups(subset='test', 
                                  remove=remove,
                                  categories=categories)
    Y_train, Y_test = train_set.target, test_set.target
    vectorizer = TfidfVectorizer(min_df=2, stop_words='english')
    X_train = vectorizer.fit_transform(train_set.data)
    X_test = vectorizer.transform(test_set.data)
    return X_train, Y_train, X_test, Y_test

def load_geolocation_data(mindf=10, complete_prob=True):

    geolocate.initialize(granularity=params.BUCKET_SIZE, write=False, readText=True, reload_init=False, regression=params.do_not_discretize)
    params.X_train, params.Y_train, params.U_train, params.X_dev, params.Y_dev, params.U_dev, params.X_test, params.Y_test, params.U_test, params.categories, params.feature_names = geolocate.feature_extractor(norm=params.norm, use_mention_dictionary=False, min_df=mindf, max_df=0.2, stop_words='english', binary=True, sublinear_tf=False, vocab=None, use_idf=True, save_vectorizer=False)

    if complete_prob:
        Y_train = np.zeros((params.X_train.shape[0], len(params.categories)), dtype='int32')
        Y_dev = np.zeros((params.X_dev.shape[0], len(params.categories)), dtype='int32')
        for i in range(params.Y_dev.shape[0]):
            Y_dev[i, params.Y_dev[i]] = 1
        for i in range(params.Y_train.shape[0]):
            Y_train[i, params.Y_train[i]] = 1

        return params.X_train, Y_train, params.X_dev, Y_dev
    else:
        return params.X_train, params.Y_train, params.X_dev, params.Y_dev
# ############################# Batch iterator ###############################
# This is just a simple helper function iterating over training data in
# mini-batches of a particular size, optionally in random order. It assumes
# data is available as numpy arrays. For big datasets, you could load numpy
# arrays as memory-mapped files (np.load(..., mmap_mode='r')), or write your
# own custom data iteration function. For small datasets, you can also copy
# them to GPU at once for slightly improved performance. This would involve
# several changes in the main program, though, and is not demonstrated here.

def iterate_minibatches(inputs, targets, batchsize, shuffle=False):
    assert inputs.shape[0] == targets.shape[0]
    if shuffle:
        indices = np.arange(inputs.shape[0])
        np.random.shuffle(indices)
    for start_idx in range(0, inputs.shape[0] - batchsize + 1, batchsize):
        if shuffle:
            excerpt = indices[start_idx:start_idx + batchsize]
        else:
            excerpt = slice(start_idx, start_idx + batchsize)
        yield inputs[excerpt], targets[excerpt]

def nn_model(X_train, Y_train, X_test, Y_test, n_epochs=20, batch_size=50, init_parameters=None, complete_prob=True, add_hidden=False, regul_coef=5e-5):

    logging.info('building the network...')
    in_size = X_train.shape[1]

    if complete_prob:
        out_size = Y_train.shape[1]
    else:
        out_size = len(set(Y_train.tolist()))
    # Prepare Theano variables for inputs and targets
    if not sp.sparse.issparse(X_train):
        X_sym = T.matrix()
    else:
        X_sym = S.csr_matrix(name='inputs', dtype='float32')

    if complete_prob:
        y_sym = T.matrix()
    else:
        y_sym = T.ivector()    
    l_in = lasagne.layers.InputLayer(shape=(None, in_size),
                                     input_var=X_sym)

    drop_input = False
    if drop_input:
        l_in = lasagne.layers.dropout(l_in, p=0.2)

    if add_hidden:
        if not sp.sparse.issparse(X_train):
            l_hid1 = lasagne.layers.DenseLayer(
                l_in, num_units=300,
                nonlinearity=lasagne.nonlinearities.rectify,
                W=lasagne.init.GlorotUniform())
        else:
            l_hid1 = SparseInputDenseLayer(
                l_in, num_units=300,
                nonlinearity=lasagne.nonlinearities.rectify,
                W=lasagne.init.GlorotUniform())


        l_out = lasagne.layers.DenseLayer(
        l_hid1, num_units=out_size,
        nonlinearity=lasagne.nonlinearities.softmax)
    else:
        if not sp.sparse.issparse(X_train):
            l_out = lasagne.layers.DenseLayer(
                l_in, num_units=out_size,
                nonlinearity=lasagne.nonlinearities.softmax)
        else:
            l_out = SparseInputDenseLayer(
                l_in, num_units=out_size,
                nonlinearity=lasagne.nonlinearities.softmax)




    if add_hidden:
        embedding = lasagne.layers.get_output(l_hid1, X_sym)
        f_get_embeddings = theano.function([X_sym], embedding)
    output = lasagne.layers.get_output(l_out, X_sym)
    pred = output.argmax(-1)
    loss = lasagne.objectives.categorical_crossentropy(output, y_sym)
    #loss = lasagne.objectives.multiclass_hinge_loss(output, y_sym)

    l1_share = 0.9
    l1_penalty = lasagne.regularization.regularize_layer_params(l_out, l1) * regul_coef * l1_share
    l2_penalty = lasagne.regularization.regularize_layer_params(l_out, l2) * regul_coef * (1-l1_share)
    loss = loss + l1_penalty + l2_penalty
    loss = loss.mean()
    if complete_prob:
        y_sym_one_hot = y_sym.argmax(-1)
        acc = T.mean(T.eq(pred, y_sym_one_hot))
    else:
        acc = T.mean(T.eq(pred, y_sym))
    if init_parameters:
        lasagne.layers.set_all_param_values(l_out, init_parameters)
    parameters = lasagne.layers.get_all_params(l_out, trainable=True)

    #print(params)
    #updates = lasagne.updates.nesterov_momentum(loss, parameters, learning_rate=0.01, momentum=0.9)
    #updates = lasagne.updates.sgd(loss, parameters, learning_rate=0.01)
    #updates = lasagne.updates.adagrad(loss, parameters, learning_rate=0.1, epsilon=1e-6)
    #updates = lasagne.updates.adadelta(loss, parameters, learning_rate=0.1, rho=0.95, epsilon=1e-6)
    updates = lasagne.updates.adam(loss, parameters, learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8)

    f_train = theano.function([X_sym, y_sym], [loss, acc], updates=updates)
    f_val = theano.function([X_sym, y_sym], [loss, acc])
    f_predict = theano.function([X_sym], pred)
    f_predict_proba = theano.function([X_sym], output)


    do_scale = False
    #X_train = X_train.todense()
    #X_text = X_text.todense()
    if do_scale:
        from sklearn import preprocessing
        scaler = preprocessing.StandardScaler().fit(X_train)
        X_train = scaler.transform(X_train)
        X_text = scaler.transform(X_text)        
    #X = X_train.todense().astype(theano.config.floatX)
    #Xt = X_test.todense().astype(theano.config.floatX)
    X = X_train.astype('float32')
    Xt = X_test.astype('float32')
    #X = X_train.astype(theano.config.floatX)
    #Xt = X_test.astype(theano.config.floatX)
    if complete_prob:
        Y = Y_train.astype('float32')
        Yt = Y_test.astype('float32')
    else:
        Y = Y_train.astype('int32')
        Yt = Y_test.astype('int32')

    logging.info('training (n_epochs, batch_size) = (' + str(n_epochs) + ', ' + str(batch_size) + ')' )
    for n in xrange(n_epochs):
        for batch in iterate_minibatches(X, Y, batch_size, shuffle=True):
            x_batch, y_batch = batch
            l_train, acc_train = f_train(x_batch, y_batch)

        l_val, acc_val = f_val(Xt, Yt)
        logging.info('epoch ' + str(n) + ' ,train_loss ' + str(l_train) + ' ,acc ' + str(acc_train) + ' ,val_loss ' + str(l_val) + ' ,acc ' + str(acc_val))
        geolocate.loss(f_predict(Xt), U_eval=params.U_dev )
    logging.info( str(regul_coef))
    if add_hidden:
        X_embs = f_get_embeddings(X)
        Xt_embs = f_get_embeddings(Xt)
    train_probs = f_predict_proba(X)
    return train_probs
    #pdb.set_trace()

if __name__ == '__main__':
    #X_train, Y_train, X_test, Y_test = load_data()
    X_train, Y_train, X_test, Y_test = load_geolocation_data(complete_prob=True)

    if params.DATASET_NUMBER == 1:
        if params.TEXT_ONLY:
            _coef = 1e-4
        else:
            _coef = 9e-5
    #for _coef in [1e-7, 2e-7, 4e-7, 8e-7, 1e-6, 8e-6]:
    #for _coef in [1e-5, 2e-5, 4e-5, 6e-5, 8e-5, 1e-4, 2e-4]:
    for _coef in [_coef]: 
        logging.info( str(_coef))
        nn_model(X_train, Y_train, X_test, Y_test, complete_prob=True, regul_coef=_coef)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

ValueError : 희소 행렬이있는 scikit 선형 회귀 CV 모델에서는 음의 차원이 허용되지 않습니다.

분류에서Dev

그룹이있는 다중 로지스틱 회귀 ggplot

분류에서Dev

다중 클래스 로지스틱 회귀 분석을 위해 Octave에서 벡터 (데이터 세트)의 레이블 감지 벡터화

분류에서Dev

다단계 로지스틱 회귀 추측 모수

분류에서Dev

Scipy로 로지스틱 회귀 구현 :이 Scipy 최적화가 모두 0을 반환하는 이유는 무엇입니까?

분류에서Dev

Python 통계 모델을 사용한 로지스틱 회귀

분류에서Dev

로지스틱 회귀는 오차 행렬에 더하기 대신 곱셈을 사용하지 않는 이유는 무엇입니까?

분류에서Dev

로지스틱 회귀 모델을 훈련하는 동안 오류 발생

분류에서Dev

Numexpr이 float 유형 (희소 행렬)을 인식하지 못합니다.

분류에서Dev

glm을 사용하여 로지스틱 회귀 모델을 구축 할 때 둘 이상의 열 제외

분류에서Dev

GLM과 로지스틱 회귀를 피팅 값을 시작하는 기본

분류에서Dev

다중 스레드에 의해 희소 행렬에 값을 할당 할 때 Segfault

분류에서Dev

R에서 로지스틱 회귀 (다항 사용)의 출력에서 발생하는 NA

분류에서Dev

RapidMiner 데이터 마이닝 로지스틱 회귀 하나 레이블

분류에서Dev

Pandas : OLS 회귀는 절편을 출력하지 않습니다.

분류에서Dev

TensorFlow 회귀에서 2 개 이상의 출력 레이블을 지정하는 방법

분류에서Dev

데이터 포인트마다 가중치가 다른가요? (처음부터 로지스틱 회귀)

분류에서Dev

auc가 sklearn 및 R의 로지스틱 회귀와 다른 이유

분류에서Dev

대규모 데이터 세트 (2 억 x 2 변수)에 대해 로지스틱 회귀를 실행하는 효율적인 방법은 무엇입니까?

분류에서Dev

Spark : DataFrame을 LibSVM으로 변경하고 로지스틱 회귀를 수행하는 방법

분류에서Dev

scikit에서 다른 특성 차원으로 로지스틱 회귀 모델 훈련

분류에서Dev

Tensorflow 다중 변수 로지스틱 회귀가 작동하지 않음

분류에서Dev

scikit-learn-확률을 목표 변수로하는 다항 로지스틱 회귀

분류에서Dev

윤곽선 모양을 유지하면서 희소 행렬 압축

분류에서Dev

TypeError : Scikit-learn에서 로지스틱 회귀 모델을 피팅하는 동안 잘못된 유형 승격

분류에서Dev

계산 된 로지스틱 회귀 모델을 사용하여 R의 적절한 컷오프 값을 기반으로 분류기를 만듭니다.

분류에서Dev

pyspark mlib에서 로지스틱 회귀를 실행하는 동안 오류가 발생했습니다.

분류에서Dev

파이썬에서 모양이 다른 두 개의 'csc'희소 행렬 추가

분류에서Dev

R의인지 로지스틱 회귀 모델링

Related 관련 기사

  1. 1

    ValueError : 희소 행렬이있는 scikit 선형 회귀 CV 모델에서는 음의 차원이 허용되지 않습니다.

  2. 2

    그룹이있는 다중 로지스틱 회귀 ggplot

  3. 3

    다중 클래스 로지스틱 회귀 분석을 위해 Octave에서 벡터 (데이터 세트)의 레이블 감지 벡터화

  4. 4

    다단계 로지스틱 회귀 추측 모수

  5. 5

    Scipy로 로지스틱 회귀 구현 :이 Scipy 최적화가 모두 0을 반환하는 이유는 무엇입니까?

  6. 6

    Python 통계 모델을 사용한 로지스틱 회귀

  7. 7

    로지스틱 회귀는 오차 행렬에 더하기 대신 곱셈을 사용하지 않는 이유는 무엇입니까?

  8. 8

    로지스틱 회귀 모델을 훈련하는 동안 오류 발생

  9. 9

    Numexpr이 float 유형 (희소 행렬)을 인식하지 못합니다.

  10. 10

    glm을 사용하여 로지스틱 회귀 모델을 구축 할 때 둘 이상의 열 제외

  11. 11

    GLM과 로지스틱 회귀를 피팅 값을 시작하는 기본

  12. 12

    다중 스레드에 의해 희소 행렬에 값을 할당 할 때 Segfault

  13. 13

    R에서 로지스틱 회귀 (다항 사용)의 출력에서 발생하는 NA

  14. 14

    RapidMiner 데이터 마이닝 로지스틱 회귀 하나 레이블

  15. 15

    Pandas : OLS 회귀는 절편을 출력하지 않습니다.

  16. 16

    TensorFlow 회귀에서 2 개 이상의 출력 레이블을 지정하는 방법

  17. 17

    데이터 포인트마다 가중치가 다른가요? (처음부터 로지스틱 회귀)

  18. 18

    auc가 sklearn 및 R의 로지스틱 회귀와 다른 이유

  19. 19

    대규모 데이터 세트 (2 억 x 2 변수)에 대해 로지스틱 회귀를 실행하는 효율적인 방법은 무엇입니까?

  20. 20

    Spark : DataFrame을 LibSVM으로 변경하고 로지스틱 회귀를 수행하는 방법

  21. 21

    scikit에서 다른 특성 차원으로 로지스틱 회귀 모델 훈련

  22. 22

    Tensorflow 다중 변수 로지스틱 회귀가 작동하지 않음

  23. 23

    scikit-learn-확률을 목표 변수로하는 다항 로지스틱 회귀

  24. 24

    윤곽선 모양을 유지하면서 희소 행렬 압축

  25. 25

    TypeError : Scikit-learn에서 로지스틱 회귀 모델을 피팅하는 동안 잘못된 유형 승격

  26. 26

    계산 된 로지스틱 회귀 모델을 사용하여 R의 적절한 컷오프 값을 기반으로 분류기를 만듭니다.

  27. 27

    pyspark mlib에서 로지스틱 회귀를 실행하는 동안 오류가 발생했습니다.

  28. 28

    파이썬에서 모양이 다른 두 개의 'csc'희소 행렬 추가

  29. 29

    R의인지 로지스틱 회귀 모델링

뜨겁다태그

보관