Estou tentando executar o SVR usando o scikit learn (python) em um conjunto de dados de treinamento com 595605 linhas e 5 colunas (recursos) e o conjunto de dados de teste com 397070 linhas. Os dados foram pré-processados e regularizados.
Consigo executar os exemplos de teste com êxito, mas ao executar usando meu conjunto de dados e deixá-lo em execução por mais de uma hora, ainda não pude ver nenhuma saída ou término do programa. Eu tentei executar usando um IDE diferente e até mesmo do terminal, mas esse não parece ser o problema. Eu também tentei alterar o valor do parâmetro 'C' de 1 para 1e3.
Estou enfrentando problemas semelhantes com todas as implementações svm usando o scikit.
Não estou esperando o suficiente para concluir? Quanto tempo essa execução deve levar?
Pela minha experiência, não deve demorar alguns minutos.
Aqui está a configuração do meu sistema: Ubuntu 14.04, 8GB de RAM, muita memória livre, processador de quarta geração i7
fonte
Respostas:
SVMs kernelizados requerem o cálculo de uma função de distância entre cada ponto do conjunto de dados, que é o custo dominante de . O armazenamento das distâncias é um fardo para a memória, portanto elas são recalculadas em tempo real. Felizmente, apenas os pontos mais próximos do limite de decisão são necessários na maioria das vezes. As distâncias frequentemente calculadas são armazenadas em um cache. Se o cache estiver sendo debulhado, o tempo de execução aumentará para .O ( n características × n 3 observações )O(nfeatures×n2observations) O(nfeatures×n3observations)
Você pode aumentar esse cache chamando o SVR como
Em geral, isso não vai funcionar. Mas tudo não está perdido. Você pode subamostrar os dados e usar o restante como um conjunto de validação ou escolher um modelo diferente. Acima da faixa de 200.000 observações, é aconselhável escolher alunos lineares.
O SVM do kernel pode ser aproximado, aproximando a matriz do kernel e alimentando-o com um SVM linear. Isso permite que você alterne entre precisão e desempenho em tempo linear.
Um meio popular de conseguir isso é usar cerca de 100 centros de cluster encontrados por kmeans / kmeans ++ como base da função do seu kernel. Os novos recursos derivados são então alimentados em um modelo linear. Isso funciona muito bem na prática. Ferramentas como sophia-ml e vowpal wabbit são como o Google, Yahoo e Microsoft fazem isso. Entrada / saída se torna o custo dominante para alunos lineares simples.
Na abundância de dados, os modelos não paramétricos têm o mesmo desempenho na maioria dos problemas. As exceções são entradas estruturadas, como texto, imagens, séries temporais, áudio.
Leitura adicional
fonte
O SVM resolve um problema de otimização de ordem quadrática.
Não tenho nada a acrescentar que não tenha sido dito aqui. Eu só quero postar um link na página sklearn sobre SVC, que esclarece o que está acontecendo:
Se você não deseja usar kernels, e um SVM linear é suficiente, existe o LinearSVR, que é muito mais rápido porque usa uma abordagem de otimização em regressões lineares. Porém, você terá que normalizar seus dados, caso ainda não o esteja fazendo, porque aplica regularização ao coeficiente de interceptação, o que provavelmente não é o que você deseja. Isso significa que, se a média dos seus dados estiver longe de zero, não será possível resolvê-los satisfatoriamente.
O que você também pode usar é a descida estocástica do gradiente para resolver o problema de otimização. O Sklearn possui o SGDRegressor . Você precisa usar
loss='epsilon_insensitive'
para obter resultados semelhantes ao SVM linear. Veja a documentação. Eu usaria apenas a descida gradiente como último recurso, porque isso implica em muitos ajustes dos hiperparâmetros, a fim de evitar ficar preso nos mínimos locais. UseLinearSVR
se puder.fonte
Você incluiu a escala na sua etapa de pré-processamento? Eu tive esse problema ao executar meu SVM. Meu conjunto de dados é de ~ 780.000 amostras (linha) com 20 recursos (col). Meu conjunto de treinamento é de ~ 235k amostras. Acontece que eu esqueci de dimensionar meus dados! Se for esse o caso, tente adicionar este bit ao seu código:
dimensionar dados para [-1,1]; aumentar a velocidade SVM:
fonte
Com um conjunto de dados tão grande, acho que seria melhor usar uma rede neural, aprendizado profundo, floresta aleatória (eles são surpreendentemente bons) etc.
Como mencionado nas respostas anteriores, o tempo gasto é proporcional à terceira potência do número de amostras de treinamento. Até o tempo de previsão é polinomial em termos de número de vetores de teste.
Se você realmente deve usar o SVM, recomendo usar a GPU para acelerar ou reduzir o tamanho do conjunto de dados de treinamento. Tente com uma amostra (talvez 10.000 linhas) dos dados primeiro para verificar se não há problema com o formato ou a distribuição dos dados.
Como mencionado em outras respostas, os kernels lineares são mais rápidos.
fonte
Recentemente, encontrei um problema semelhante porque esqueci de dimensionar recursos no meu conjunto de dados, que antes era usado para treinar o tipo de modelo de conjunto. A falta de escala dos dados pode ser o provável culpado, conforme apontado por Shelby Matlock. Você pode experimentar diferentes dimensionadores disponíveis no sklearn, como o RobustScaler :
from sklearn.preprocessing import RobustScaler scaler = RobustScaler() X = scaler.fit_transfrom(X)
O X agora está transformado / dimensionado e pronto para ser alimentado no modelo desejado.
fonte
Isso faz sentido. IIUC, a velocidade de execução das operações do vetor de suporte é limitada pelo número de amostras, não pela dimensionalidade. Em outras palavras, é limitado pelo tempo da CPU e não pela RAM. Não sei exatamente quanto tempo isso deve levar, mas estou executando alguns benchmarks para descobrir.
fonte
Deixe-o funcionar durante a noite ou melhor por 24 horas. Qual é a sua utilização de CPU? Se nenhum dos núcleos estiver funcionando a 100%, você terá um problema. Provavelmente com memória. Você verificou se o seu conjunto de dados se encaixa em 8 GB? Você já experimentou o SGDClassifier? É um dos mais rápidos lá. Vale a pena tentar primeiro, esperando que seja concluído em mais ou menos uma hora.
fonte
SGDClassifier
não suporta kernels. Se o OP quiser SVM linear, recomendo que tente primeiroLinearSVR
. É muito mais rápido do queSVR
porque resolve o problema usando uma biblioteca de regressão linear e o mínimo global é garantido (diferente da descida do gradiente).The loss function to be used. Defaults to ‘hinge’, which gives a linear SVM.
mesma coisa paraSGDRegressor
.SGDRegressor
é equivalente a usarSVR(kernel='linear')
. Se é isso que o OP quer, isso é ótimo. Fiquei com a impressão de que ele queria usar o SVM com um kernel. Se não for esse o caso, eu recomendaria que ele tentasse primeiroLinearSVR
.Tente normalizar os dados para [-1,1]. Eu enfrentei um problema semelhante e, após a normalização, tudo funcionou bem. Você pode normalizar dados facilmente usando:
from sklearn import preprocessing X_train = preprocessing.scale(X_train) X_test = preprocessing.scale(X_test)
fonte
Eu encontrei esse problema e,
cache_size
como outros sugerem, não ajuda em nada. Você pode ver esta postagem e esta como o principal colaborador sugerido que você deve alterar o código manualmente.Como você sabe,
SVC
eSVR
são problemas de otimização e eles param quando a margem de erro é tão pouco onde a otimização é fútil. Portanto, há outro parâmetro neles,max_iter
onde você pode definir quantas iterações devem fazer.Eu usei
sklearn
em python ee1071
em R e R é muito mais rápido chegar ao resultado sem definir omax_iter
esklearn
leva 2-4 vezes mais. A única maneira de reduzir o tempo de computação do python era usandomax_iter
. É em relação à complexidade do modelo, o número de recursos, grãos e hiperparâmetros, mas para pequenas dataset eu usei por cerca de 4000 datapoint emax_iter
foi10000
os resultados não foram diferentes em tudo e foi aceitável.fonte
Acabei de ter um problema semelhante com um conjunto de dados que contém apenas 115 elementos e apenas um único recurso (dados de companhias aéreas internacionais). A solução foi dimensionar os dados. O que eu perdi nas respostas até agora foi o uso de um Pipeline:
Você pode treinar
model
como um modelo usual de classificação / regressão e avaliá-lo da mesma maneira. Nada muda, apenas a definição do modelo.fonte
Pipeline
? Você não está importando.Você precisa dimensionar seus dados. A escala normalizará seus pontos de dados para -1 a 1, o que ajudará a uma convergência mais rápida.
Tente usar o seguinte código:
fonte