La mancanza di una qualità dei dati coerente ostacola l'analisi dei dati e scoraggia molti dall'intraprendere un percorso di apprendimento automatico.
Nell'industria dei semiconduttori ci si aspetta che i processi vengano costantemente migliorati. Sfortunatamente, uno degli effetti collaterali di tali sforzi è un cambiamento nella struttura dei dati. Una ragione di ciò potrebbe essere la ridenominazione della fase del processo.
Di seguito ho simulato un caso del genere, in cui 20 lotti sono stati elaborati attraverso 4 fasi di processo con modifiche al nome delle fasi.
Per l'analisi delle cause profonde è necessario confrontare i risultati della sonda da apparecchiature associate a uno specifico passaggio. Nel caso seguente possiamo vedere che i dati sono diventati stratificati.
So che potrei continuare a usare la funzionalità "Combina colonne" in JMP (Cols\Utilities\Combina colonne...), ma in realtà ho diverse centinaia di colonne che devono essere controllate e combinate.
Utilizzando la funzionalità Tabelle\Modello dati mancanti in JMP riesco a vedere facilmente le strutture dati e le potenziali colonne da combinare.
Mi chiedevo se le informazioni del Missing Data Pattern potessero essere utilizzate per scrivere lo script del requisito di combinazione delle colonne?
Prima di automatizzare il processo sarebbero necessari diversi controlli, ad esempio:
Le colonne rappresentano lo stesso passaggio del processo?
Il contenuto di entrambi i passaggi è simile?
Il modello Dati mancanti è l'inverso per le colonne accoppiate?
I dati non funzionanti si presentano come segue:

Modello dati mancanti:

Dati ricostruiti:

- jpol
Ciao, per quelli di voi interessati a utilizzare il modello di dati mancanti per migliorare la qualità dei dati, sto fornendo un breve aggiornamento qui:
Stavo usando la sceneggiatura di @txnelson per creare set di dati migliori, ma poi mi sono reso conto che esiste un'istanza in cui vorrei combinare le colonne nonostante il rispettivo modello di dati mancanti (e complemento) non corrispondente. È quando entrambe le colonne hanno dati mancanti nelle stesse righe.
Ecco un esempio, basato sull'esempio originale:

Vorrei combinare le colonne associate a Step6 come visto sopra.
Mi è poi venuto in mente che sarebbe stato utile conoscere la percentuale di corrispondenza tra le colonne prima di qualsiasi gestione dei dati. Ciò darebbe la possibilità di utilizzare tali informazioni al momento di decidere se combinare o meno.
Aver comunicato con @txnelson ha gentilmente sviluppato la sua sceneggiatura.
In allegato la versione definitiva.
Includo anche di seguito alcuni esempi che utilizzano dati "reali" in cui questo metodo è stato utilizzato per migliorare la qualità dei dati:
Nota: le celle colorate in blu indicano i dati mancanti
Caso 1:
A partire dal

a

Caso 2:
A partire dal

a

C'è una grande riduzione delle colonne e molte meno celle "vuote".
Come puoi immaginare, ciò consente analisi delle cause alla radice migliorate, più rapide ed efficienti.
In allegato sono riportati gli script per creare l'esempio di dati mancanti simulati e lo script finale che riporta "Percentuale combinabile" e "Colonne che possono essere combinate" in base ai modelli di dati mancanti.
- Filippo
Durante la valutazione dello script di txnelson su una tabella di dati molto più grande dalla produzione, è stato riscontrato (Jim ha scoperto) che se alcune righe non hanno dati in tutte le colonne mirate, lo script non fornirà un elenco di output. Jim ha gentilmente fornito una correzione alla sceneggiatura. Vedi sotto:
Names Default To Here( 1 );
dtRaw = Current Data Table();
colNamesList = dtRaw << get column names( string );
Remove From( colNamesList, 1, 1 );
dt = dtRaw << Missing Data Pattern(
columns( Eval( colNamesList ) ),
Output Table( "Missing Data Pattern" )
);
// Get rid of all missing and all present patterns
dt << lock data table( 0 );
dt << select where( Contains( :patterns, "0" ) & !Contains( :Patterns, "1" ) );
Try( dt << delete rows );
dt << select where( Contains( :patterns, "1" ) & !Contains( :Patterns, "0" ) );
Try( dt << delete rows );
// Check for columns which could be combined
// *** JSL written by txnelson ***
cols1List = {};
cols2List = {};
For( i = 4, i <= N Cols( dt ), i++,
comp = Associative Array( dt << get rows where( As Column( dt, i ) == 1 ) );
compMissing = Associative Array( dt << get rows where( As Column( dt, i ) == 0 ) );
If( N Items( comp ) > 0,
For( k = i + 1, k <= N Cols( dt ), k++,
comp2 = Associative Array( dt << get rows where( As Column( dt, k ) == 1 ) );
comp2Missing = Associative Array( dt << get rows where( As Column( dt, k ) == 0 ) );
comp2 << intersect( comp );
comp2Missing << intersect( compMissing );
If( N Items( comp2 << get keys ) == 0 & N Items( comp2Missing << get keys ) == 0,
Insert Into( cols1List, Column( dt, i ) << get name );
Insert Into( cols2List, Column( dt, k ) << get name );
);
)
);
);
nw = New Window( "Results",
Outline Box( "Columns that can be combined",
Table Box( String Col Box( "Column", cols1List ), String Col Box( "With", cols2List ) )
)
);- Filippo
Grazie Jim per la risposta e la soluzione molto veloci.
Per coloro che desiderano vedere il tuo script in azione, includo lo script di creazione dei dati dall'esempio che ho fornito e il tuo JSL per segnalare le colonne che potrebbero essere combinate.
names default to here(1);
// Construct the initial data table
New Table( "Missing data initial",
Add Rows( 20 ),
New Column( "LOT_ID",
Character,
"Nominal",
Set Values(
{"AA_234_xx.1", "AA_234_xx.2", "AA_234_xx.3", "AA_234_xx.4",
"AA_234_xx.5", "AA_234_xx.6", "AA_234_xx.7", "AA_234_xx.8",
"AA_234_xx.9", "AA_234_xx.10", "AA_234_xx.11", "AA_234_xx.12",
"AA_234_xx.13", "AA_234_xx.14", "AA_234_xx.15", "AA_234_xx.16",
"AA_234_xx.17", "AA_234_xx.18", "AA_234_xx.19", "AA_234_xx.20"}
),
Set Display Width( 81 )
),
New Column( "Step1.v1",
Character( 6 ),
"Nominal",
Set Values(
{"SRD_01", "SRD_02", "SRD_01", "SRD_04", "SRD_02", "", "", "", "", "",
"SRD_01", "SRD_02", "SRD_01", "SRD_04", "SRD_02", "", "", "", "", ""}
),
Set Display Width( 58 )
),
New Column( "Step1.v2",
Character( 16 ),
"Nominal",
Set Values(
{"", "", "", "", "", "SRD_01", "SRD_02", "SRD_01", "SRD_04", "SRD_02",
"", "", "", "", "", "SRD_02", "SRD_02", "SRD_02", "SRD_02", "SRD_02"}
),
Set Display Width( 58 )
),
New Column( "Step2.v2",
Character( 16 ),
"Nominal",
Set Values(
{"COATER_02", "COATER_01", "", "", "COATER_02", "COATER_01", "COATER_02",
"COATER_02", "COATER_02", "COATER_01", "COATER_02", "COATER_02",
"COATER_01", "COATER_01", "COATER_01", "", "", "", "COATER_01",
"COATER_01"}
),
Set Display Width( 71 )
),
New Column( "Step2.v3",
Character( 16 ),
"Nominal",
Set Values(
{"", "", "COATER_01", "COATER_01", "", "", "", "", "", "", "", "", "",
"", "", "COATER_02", "COATER_02", "COATER_02", "", ""}
),
Set Display Width( 71 )
),
New Column( "Step3.v5",
Character( 16 ),
"Nominal",
Set Values(
{"DRIE_03", "DRIE_04", "DRIE_03", "", "", "", "", "", "", "DRIE_04",
"DRIE_03", "DRIE_04", "DRIE_03", "DRIE_04", "", "", "", "", "", ""}
),
Set Display Width( 58 )
),
New Column( "Step3.v6",
Character( 16 ),
"Nominal",
Set Values(
{"", "", "", "DRIE_04", "DRIE_03", "DRIE_04", "DRIE_03", "DRIE_04",
"DRIE_03", "", "", "", "", "", "DRIE_03", "DRIE_04", "DRIE_03",
"DRIE_04", "DRIE_03", "DRIE_04"}
),
Set Display Width( 58 )
),
New Column( "Step4.v1",
Character( 16 ),
"Nominal",
Set Values(
{"PRIME_06", "", "PRIME_07", "", "PRIME_06", "", "PRIME_07", "",
"PRIME_06", "", "PRIME_07", "", "PRIME_06", "", "PRIME_07", "",
"PRIME_06", "", "PRIME_07", ""}
),
Set Display Width( 61 )
),
New Column( "Step4.v2",
Character( 16 ),
"Nominal",
Set Values(
{"", "PRIME_06", "", "PRIME_07", "", "PRIME_06", "", "PRIME_07", "",
"PRIME_06", "", "PRIME_07", "", "PRIME_06", "", "PRIME_07", "",
"PRIME_06", "", "PRIME_07"}
),
Set Display Width( 61 )
)
);
// Check the Missings Data Patern
Data Table( "Missing data initial" ) <<
Missing Data Pattern(
columns(
:Step1.v1,
:Step1.v2,
:Step2.v2,
:Step2.v3,
:Step3.v5,
:Step3.v6,
:Step4.v1,
:Step4.v2
),
Output Table( "Missing Data Pattern" )
);
// Check for columns which could be combined
// *** JSL written by txnelson ***
dt=Data Table( "Missing Data Pattern");
cols1List = {};
cols2List = {};
For( i = 4, i <= N Cols( dt ), i++,
comp = Associative Array( dt << get rows where( As Column( dt, i ) == 1 ) );
compMissing = Associative Array( dt << get rows where( As Column( dt, i ) == 0 ) );
If( N Items( comp ) > 0,
For( k = i + 1, k <= N Cols( dt ), k++,
comp2 = Associative Array( dt << get rows where( As Column( dt, k ) == 1 ) );
comp2Missing = Associative Array( dt << get rows where( As Column( dt, k ) == 0 ) );
comp2 << intersect( comp );
comp2Missing << intersect( compMissing );
If( N Items( comp2 << get keys ) == 0 & N Items( comp2Missing << get keys ) == 0,
Insert Into( cols1List, Column( dt, i ) << get name );
Insert Into( cols2List, Column( dt, k ) << get name );
);
)
);
);
nw = New Window( "Results",
Outline Box( "Columns that can be combined",
Table Box( String Col Box( "Column", cols1List ), String Col Box( "With", cols2List ) )
)
);
- Filippo
Penso che tu possa utilizzare il modello di dati mancanti per identificare le colonne che hanno dati senza intersezioni sia per i modelli non mancanti che per i modelli mancanti.Questo script utilizza la tabella di output della piattaforma Missing Pattern, utilizzando una tabella di dati Missing Data Pattern leggermente modificata dalle tabelle di dati di esempio di JMP.Trova tutti i modelli abbinati inversamente e li visualizza in una finestra di visualizzazione

names default to here(1);
dt=New Table( "example",
Add Rows( 4 ),
New Column( "Count",
Numeric,
"Continuous",
Format( "Fixed Dec", 10, 0 ),
Preselect Role( Freq ),
Set Values( [1, 3, 1, 2] )
),
New Column( "Number of columns missing",
Numeric,
"Continuous",
Format( "Fixed Dec", 10, 0 ),
Set Values( [1, 2, 1, 2] )
),
New Column( "Patterns",
Character,
"Ordinal",
List Check( {"0010", "0011", "0100", "0101"} ),
Set Values( {"0010", "0011", "0100", "0101"} )
),
New Column( "Trial 1", Numeric( 1 ), "Nominal", Set Values( [0, 0, 0, 0] ) ),
New Column( "Trial 2", Numeric( 1 ), "Nominal", Set Values( [0, 0, 1, 1] ) ),
New Column( "Trial 3", Numeric( 1 ), "Nominal", Set Values( [1, 1, 0, 0] ) ),
New Column( "Trial 4", Numeric( 1 ), "Nominal", Set Values( [0, 1, 0, 1] ) )
);
cols1List = {};
cols2List = {};
For( i = 4, i <= N Cols( dt ), i++,
comp = Associative Array( dt << get rows where( As Column( dt, i ) == 1 ) );
compMissing = Associative Array( dt << get rows where( As Column( dt, i ) == 0 ) );
If( N Items( comp ) > 0,
For( k = i + 1, k <= N Cols( dt ), k++,
comp2 = Associative Array( dt << get rows where( As Column( dt, k ) == 1 ) );
comp2Missing = Associative Array( dt << get rows where( As Column( dt, k ) == 0 ) );
comp2 << intersect( comp );
comp2Missing << intersect( compMissing );
If( N Items( comp2 << get keys ) == 0 & N Items( comp2Missing << get keys ) == 0,
Insert Into( cols1List, Column( dt, i ) << get name );
Insert Into( cols2List, Column( dt, k ) << get name );
);
)
);
);
nw = New Window( "Results",
Outline Box( "Columns that can be combined",
Table Box( String Col Box( "Column", cols1List ), String Col Box( "With", cols2List ) )
)
);