En un post anterior , Yo mencione un nuevo complemento JMP que se puede utilizar para dividir los datos antes de modelado predictivo . Esta publicación trata sobre cómo funciona esto y, por lo tanto, toca necesariamente el tema de JMP Scripting Language, o JSL, para abreviar.
Este es un tema importante, por lo que aquí solo quiero mostrar la anatomía de un script JSL que hace algo útil. Esta publicación asume que has descargado e instalado el complemento y están familiarizados con lo que hace. (Nota: la descarga del complemento requiere un inicio de sesión SAS gratuito).
Si selecciona el elemento de menú 'Ver> Complementos ...' en JMP 9, debería ver 'División estratificada' en el cuadro combinado. La elección de este elemento le brinda un enlace a la 'Carpeta de inicio' del complemento, y al seleccionar este enlace y al hacer doble clic en 'stratifiedSplit.jsl' se abre el código fuente en el editor de JMP. Para continuar, asegúrese de haber optado por mostrar los números de línea en el editor ('Archivo> Preferencias', y luego seleccione 'Editor de secuencias de comandos' como el 'Grupo de preferencias').
El JSL se puede deconstruir de la siguiente manera:
(1) Líneas 11-13: Las proporciones predeterminadas en las que se dividirán los datos. Tenga en cuenta que un sufijo de '0', '1' o '2' en un nombre denota algo que ver con los datos de 'Entrenamiento', 'Validación' o 'Prueba' (reflejando los valores generados en la columna de indicadores aleatorios que hace JMP) .
(2) Líneas 15-29: Una función que se llama si actualiza una de las proporciones predeterminadas, que comprueba que su nuevo valor se encuentra entre 0 y 1.
(3) Líneas 31-55: La interfaz de usuario: presenta todas las columnas de la tabla de datos actual y le permite seleccionar la columna de respuesta. También puede anular las proporciones divididas predeterminadas.

(4) Líneas 58-85: Muestra ayuda en una nueva ventana si se presiona el botón 'Ayuda' en (3).
(5) Líneas 88-104: Se ejecuta cuando se presiona el botón 'OK' en (3) y verifica si las tres proporciones especificadas realmente suman a la unidad. Si no, (3) se muestra de nuevo con las proporciones de división predeterminadas.
(6) Líneas 107-135: Comprueba que se haya seleccionado realmente una columna de respuesta y se detiene si no lo está. Si se seleccionó una columna de respuesta, encuentra el número de niveles distintos en esa columna, y si es mayor que 100, da la opción de detener.
(7) Líneas 138-182: Al usar una asignación de qué filas de la tabla actual corresponden a qué nivel de la columna de respuesta (6) y las proporciones de división especificadas (3), se construye la nueva columna de validación. Luego usa Distribución para mostrar cómo se dividieron aleatoriamente las filas en la tabla.
Para aquellos que ya están familiarizados con JSL, el código aquí no es destacable. Sin embargo, a un nivel más alto, siempre hay que tomar decisiones de diseño y, por lo general, se requiere un compromiso cuando se tiene en cuenta que el resultado final debe ser "lo suficientemente bueno" para su uso previsto.
En este caso, por ejemplo, se hizo una elección específica para separar la comprobación de errores en dos partes, (2) y (5) anteriores, para simplificar la lógica detrás de la interfaz de usuario. Incluso si eres nuevo en JSL, con un poco de paciencia y con la ayuda de la Guía JSL ('Ayuda> Libros> Guía de secuencias de comandos'), deberías poder descubrir los detalles de cómo funciona realmente cada sección de código. Después de todo, una de las mejores maneras de comenzar a aprender un nuevo idioma es comenzar con algo que funcione. Por razones de espacio, solo veremos aquí (6) y (7).
Como ya se mencionó, una de las partes clave en este problema es encontrar información sobre los niveles en la columna de respuesta (6). Aunque hay muchas maneras de hacer esto, matriz asociativa Es el más versátil.
El fragmento de código que se muestra a continuación crea una tabla para jugar. La línea 5 obtiene los 20 valores de 'Respuesta' en un vector, y la línea 6 crea una matriz asociativa y le envía un mensaje 'Obtener claves' para revelar los distintos valores en el orden lexicográfico. Una de las ventajas de la matriz asociativa es que funciona con cualquier tipo de datos (no solo números, como en este caso), pero tenga en cuenta que "Obtener claves" siempre devuelve una lista. Por lo tanto, en la línea 7, necesitamos usar 'N elementos ()' para averiguar cuántos artículos contiene esta lista.

Una vez que tenemos los valores para 'yLev' y 'nLevs' de (6), los pasos en (7) son los siguientes:
1. Construya un vector de valores faltantes, 'vVals' que luego se usarán para completar la nueva columna de validación (línea 141).
2. Recorra los distintos niveles mantenidos en 'yLev' (líneas 143 a 161).
3. Localice los números de fila en 'yVals' (y, por lo tanto, la tabla de datos) que corresponden al nivel actual y almacénelos en la variable 'stratum' (línea 145). Tenga en cuenta que la sintaxis para hacer esto depende de si 'yVals' es un vector o una lista (y, por lo tanto, si la columna de respuesta original tenía un tipo de datos de 'Numeric' o 'Character').
4. La variable 'stratumN' contiene el número de filas que corresponden al nivel actual (línea 147). Convierta las proporciones divididas especificadas en enteros, y asegúrese de que estas sumas sean a 'estrato N' (líneas 149 a 154).
5. Construya los vectores 'v0', 'v1' y 'v2' de las longitudes correctas y que contengan los valores '0', '1' y '2' respectivamente (líneas 157 a 159). Tenga en cuenta que para garantizar que el siguiente paso siempre funcione, debemos permitir la posibilidad de que una de las proporciones sea 0.0 y configurar el vector correspondiente a '[]'.
6. Apile estos vectores al final (usando 'VConCat ()'), y mezcle el resultado para que los valores '0', '1' y '2' se distribuyan aleatoriamente. Asigne estos valores a las filas correctas en 'vVals' para que los valores que faltan en ellos sean reemplazados (línea 160).
7. Una vez finalizado el bucle, use 'vVals' para crear una nueva columna de validación o reemplace una columna de validación existente (líneas 163 a 170). Tenga en cuenta que usamos una propiedad de columna 'Etiqueta de valor' para que los valores enteros de '0', '1' y '2' aparezcan como 'Entrenamiento', 'Validación' y 'Prueba' respectivamente.
8. Use 'Distribución' con una variable 'Por' para mostrar los valores de la columna de validación para cada nivel en la respuesta.
Aunque rutinario, hay quizás algunos aspectos no obvios al código:
• No hicimos ninguna suposición innecesaria sobre el tipo de datos o el tipo de modelo de la columna de respuesta que seleccionó (el código funcionaría perfectamente bien, por ejemplo, con una columna 'Numérica', 'Continua' que tiene valores que son '' agrupados 'en niveles).
• Los valores faltantes en la columna de respuesta se propagan como valores faltantes a la columna de validación que se genera, lo cual es deseable. Pero tenga en cuenta que, en el caso de una columna numérica, el '.' el valor provocará una alerta JMP benigna cuando la plataforma de distribución intente procesar el grupo 'Por' con el '.' valores. Para una columna de caracteres, la cadena nula “” se procesa igual que los otros niveles en el grupo 'Por' sin alerta.
• La expresión 'ColListBox ()' en la línea 42 no presenta columnas de estado de fila para su selección, incluso si existen en la tabla, lo que es deseable en este caso.
Si usas JMP y te gusta jugar con el código, hay muchas maneras de aprender más. Podrías empezar por mirar esto. Entrada de intercambio de archivos .