Estoy tratando de ejecutar SVR usando scikit learn (python) en un conjunto de datos de entrenamiento que tiene 595605 filas y 5 columnas (características) y un conjunto de datos de prueba que tiene 397070 filas. Los datos han sido preprocesados y regularizados.
Puedo ejecutar con éxito los ejemplos de prueba, pero al ejecutar usando mi conjunto de datos y dejar que se ejecute durante más de una hora, aún no pude ver ningún resultado o finalización del programa. He intentado ejecutar usando un IDE diferente e incluso desde la terminal, pero ese no parece ser el problema. También he intentado cambiar el valor del parámetro 'C' de 1 a 1e3.
Estoy enfrentando problemas similares con todas las implementaciones de svm que usan scikit.
¿No estoy esperando lo suficiente para que se complete? ¿Cuánto tiempo debería llevar esta ejecución?
Desde mi experiencia, no debería requerir más de unos minutos.
Aquí está la configuración de mi sistema: Ubuntu 14.04, 8GB de RAM, mucha memoria libre, procesador i7 de cuarta generación
fuente
Respuestas:
Las SVM kernelizadas requieren el cálculo de una función de distancia entre cada punto en el conjunto de datos, que es el costo dominante de . El almacenamiento de las distancias es una carga para la memoria, por lo que se vuelven a calcular sobre la marcha. Afortunadamente, la mayoría de las veces solo se necesitan los puntos más cercanos al límite de decisión. Las distancias calculadas con frecuencia se almacenan en un caché. Si la memoria caché se está agotando, el tiempo de ejecución aumenta a O ( n características × n 3 observaciones ) .O ( ncaracteristicas× n2observaciones) O ( ncaracteristicas× n3observaciones)
Puede aumentar este caché invocando SVR como
En general, esto no va a funcionar. Pero no todo está perdido. Puede submuestrear los datos y usar el resto como un conjunto de validación, o puede elegir un modelo diferente. Por encima del rango de observación de 200,000, es aconsejable elegir estudiantes lineales.
Kernel SVM puede ser aproximado, aproximando la matriz del kernel y alimentándola a un SVM lineal. Esto le permite intercambiar entre precisión y rendimiento en tiempo lineal.
Una forma popular de lograr esto es usar aproximadamente 100 centros de clúster encontrados por kmeans / kmeans ++ como base de la función de su núcleo. Las nuevas características derivadas se introducen en un modelo lineal. Esto funciona muy bien en la práctica. Herramientas como sophia-ml y votepal wabbit son cómo Google, Yahoo y Microsoft hacen esto. La entrada / salida se convierte en el costo dominante para los aprendices lineales simples.
En la abundancia de datos, los modelos no paramétricos realizan aproximadamente lo mismo para la mayoría de los problemas. Las excepciones son entradas estructuradas, como texto, imágenes, series de tiempo, audio.
Otras lecturas
fuente
SVM resuelve un problema de optimización de orden cuadrático.
No tengo nada que agregar que no se haya dicho aquí. Solo quiero publicar un enlace en la página de sklearn sobre SVC que aclara lo que está sucediendo:
Si no desea utilizar núcleos, y un SVM lineal es suficiente, existe LinearSVR, que es mucho más rápido porque utiliza un enfoque de optimización para las regresiones lineales. Sin embargo, tendrá que normalizar sus datos, en caso de que aún no lo haga, porque aplica la regularización al coeficiente de intercepción, que probablemente no sea lo que desea. Significa que si su promedio de datos está lejos de cero, no podrá resolverlo satisfactoriamente.
Lo que también puede usar es el descenso de gradiente estocástico para resolver el problema de optimización. Sklearn presenta SGDRegressor . Debe usar
loss='epsilon_insensitive'
para tener resultados similares a SVM lineal. Ver la documentación. Sin embargo, solo usaría el descenso de gradiente como último recurso porque implica muchos ajustes de los hiperparámetros para evitar quedar atrapado en los mínimos locales. ÚseloLinearSVR
si puede.fuente
¿Incluyó el escalado en su paso de preprocesamiento? Tuve este problema al ejecutar mi SVM. Mi conjunto de datos es de ~ 780,000 muestras (fila) con 20 características (col). Mi conjunto de entrenamiento es de ~ 235k muestras. ¡Resulta que olvidé escalar mis datos! Si este es el caso, intente agregar este bit a su código:
escalar datos a [-1,1]; aumentar la velocidad SVM:
fuente
Con un conjunto de datos tan grande, creo que sería mejor usar una red neuronal, aprendizaje profundo, bosque aleatorio (son sorprendentemente buenos), etc.
Como se mencionó en las respuestas anteriores, el tiempo necesario es proporcional a la tercera potencia del número de muestras de entrenamiento. Incluso el tiempo de predicción es polinómico en términos de número de vectores de prueba.
Si realmente debe usar SVM, le recomiendo usar GPU para acelerar o reducir el tamaño del conjunto de datos de entrenamiento. Pruebe primero con una muestra (quizás 10,000 filas) de los datos para ver si no es un problema con el formato o la distribución de datos.
Como se mencionó en otras respuestas, los núcleos lineales son más rápidos.
fuente
Recientemente encontré un problema similar porque olvidé escalar características en mi conjunto de datos que se utilizó anteriormente para entrenar el tipo de modelo de conjunto. La imposibilidad de escalar los datos puede ser el culpable probable según lo indicado por Shelby Matlock. Puede probar diferentes escaladores disponibles en sklearn, como RobustScaler :
from sklearn.preprocessing import RobustScaler scaler = RobustScaler() X = scaler.fit_transfrom(X)
X ahora se transforma / escala y está listo para ser alimentado a su modelo deseado.
fuente
Esto tiene sentido. IIUC, la velocidad de ejecución de las operaciones de vectores de soporte está limitada por el número de muestras, no por la dimensionalidad. En otras palabras, está limitado por el tiempo de CPU y no por la RAM. No estoy seguro exactamente cuánto tiempo debería llevar esto, pero estoy ejecutando algunos puntos de referencia para averiguarlo.
fuente
Déjelo correr durante la noche o mejor durante 24 horas. ¿Cuál es la utilización de tu CPU? Si ninguno de los núcleos funciona al 100%, entonces tiene un problema. Probablemente con memoria. ¿Ha verificado si su conjunto de datos se ajusta a 8 GB? ¿Has probado el SGDClassifier? Es uno de los más rápidos allí. Vale la pena intentarlo primero con la esperanza de que se complete en una hora más o menos.
fuente
SGDClassifier
no es compatible con los núcleos. Si el OP quiere SVM lineal, entonces recomendaría primero intentarloLinearSVR
. Es mucho más rápido queSVR
porque resuelve el problema usando una biblioteca de regresión lineal, y el mínimo global está garantizado (a diferencia del gradiente decente).The loss function to be used. Defaults to ‘hinge’, which gives a linear SVM.
mismo paraSGDRegressor
.SGDRegressor
es equivalente a usarSVR(kernel='linear')
. Si eso es lo que OP quiere, eso es genial. Tenía la impresión de que quería usar SVM con un núcleo. Si ese no es el caso, recomendaría que primero lo intenteLinearSVR
.Intente normalizar los datos a [-1,1]. Me enfrenté a un problema similar y sobre la normalización todo funcionó bien. Puede normalizar datos fácilmente usando:
from sklearn import preprocessing X_train = preprocessing.scale(X_train) X_test = preprocessing.scale(X_test)
fuente
Me he encontrado con este problema y,
cache_size
como otros sugieren, no ayuda en absoluto. Puede ver esta publicación y esta, ya que el principal contribuyente sugirió que debería cambiar el código manualmente.Como ya saben,
SVC
ySVR
son problemas de optimización y se detendrá cuando el margen de error es tan pequeño que la optimización adicional es inútil. Entonces, hay otro parámetro en estos,max_iter
donde puede establecer cuántas iteraciones debe hacer.Lo he usado
sklearn
en Python ye1071
en R y R es mucho más rápido llegar al resultado sin configurar elmax_iter
ysklearn
tarda 2-4 veces más. La única forma en que podía reducir el tiempo de cálculo para Python era usandomax_iter
. Es relativo a la complejidad de su modelo, número de cuenta, granos y hiperparámetros, pero por lo pequeño conjunto de datos utilizado por alrededor de 4.000 puntos de datos ymax_iter
se10000
los resultados no fueron diferentes en absoluto y que era aceptable.fuente
Acabo de tener un problema similar con un conjunto de datos que contiene solo 115 elementos y una sola característica (datos de aerolíneas internacionales). La solución fue escalar los datos. Lo que me perdí en las respuestas hasta ahora fue el uso de una tubería:
Puede entrenar
model
como un modelo habitual de clasificación / regresión y evaluarlo de la misma manera. Nada cambia, solo la definición del modelo.fuente
Pipeline
? No lo estás importando.Necesita escalar sus datos. El escalado normalizará sus puntos de datos a un rango de -1 a 1, lo que ayudará a una convergencia más rápida.
Intenta usar el siguiente código:
fuente