-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproceso.Rmd
336 lines (264 loc) · 11 KB
/
proceso.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
---
title: "Proceso"
output:
html_document: default
pdf_document: default
date: "2023-05-30"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
Data <- read.csv("train_data.csv")
```
No podemos garantizar que todos estos sets de datos inicien con el mismo remanente de vida útil, por lo tanto se debe considerar partir del final, el cual se nos garantiza que representa el fallo del sistema
```{r}
Data <- data.frame(apply(Data, 2, rev))
Data$Cycle <- rev(Data$Cycle)
```
```{r echo=FALSE}
plot(Data$Cycle, Data$Height)
```
```{r}
tmp <- split(Data, Data$Throttle)
Data60 <- as.data.frame(tmp[1])
Data100 <- as.data.frame(tmp[2])
names(Data60) <- names(Data)
names(Data100) <- names(Data)
```
De esta forma se tienen los datos más homogéneos para un régimen de trabajo con el 60% de regulador
```{r echo=FALSE}
plot(Data60$Cycle, Data60$Height)
```
Mientras que los datos de 100% siguen mostrando contenido de distintos regímenes, al menos 5 distintos
```{r}
plot(Data100$Cycle, Data100$Height)
```
```{r}
splittedData <- split(Data, cut(Data$Height, c(-5,5,15,24,30,40,45)))
```
Los datos de estos sub grupos presentan comportamiento homogéneo
```{r echo=FALSE}
plottingData <- data.frame(splittedData[6])
names(plottingData) <- names(Data)
plot(plottingData$Cycle, plottingData$Height)
```
Se ha notado en todos los gráficos generados, que a partir del ciclo 200 hay una disminución en la densidad de datos, o eso aparenta, se realiza un análisis general de cada sub set, auque primero se debe determinar cuáles datos no vale la pena analizar, algunos fáciles de descartar corresponden al motor, ciclo y regulador, ya que son valores discretos con variaciones conocidas que de momento no nos interesan, por ejemplo
Se separan los datos a mostrar por regiones, ya que son muchos sensores para mostrar todos en una sóla salida, es posible observar para los datos a 60%, que la altura es casi constante, con variaciones de 0,01 unidades, el número Mach presenta variaciones ligeramente mayores, con 0,022 unidades, ambos variando hacia el tercer cuartil y el sensor 1 es constante
El sensor 5 es constante y el 8 sólo tiene una mínima variación en el máximo, la cual no llega a ser significativa ni para el tercer cuartil
Para simplificar la discriminación de variables, se decide emplear únicamente los cuártiles, sumando todos estos y dividiendo según el valor del primer cuartíl multiplicado por 5, para obtener un número sencillo que si es 1, significa que la variable no es significativa para el análisis
```{r}
# Versión larga de la función, para mayor claridad
getSig <- function(columna) {
cuartiles <- quantile(columna)
sumaCuartiles <- sum(cuartiles)
ultimoCuartil <- cuartiles[5]
calculoSignificancia <- sumaCuartiles/(ultimoCuartil*5)
return(calculoSignificancia)
}
# Se aplica la función a todas las columnas de los datos
Significancia <- data.frame(as.list(apply(Data60[,-c(1,2,5)], 2, getSig)))
row.names(Significancia) <- c("60%")
```
Con base en la prueba anterior podemos ver que la signficiancia a 60% del sensor 1 es de 1, al igual que el sensor 5, por lo que seguiremos empleando este valor para simplificar la selección de dator, pero con una versión más corta de la función
```{r}
# Versión final de la función
getInsig <- function(dataFrame, rowName) {
insig <- data.frame(as.list(apply(dataFrame, 2, (function(col) sum(quantile(col))/(quantile(col)[5]*5)))))
row.names(insig) <- c(rowName)
return(insig)
}
```
Esto permite generar los datos faltantes y unirlos al data frame ya existente, esto se realiza a continuación
```{r}
Significancia <- rbind(Significancia, getSig(Data100_1[-c(1,2,5)], "100%_1"))
Significancia <- rbind(Significancia, getSig(Data100_2[-c(1,2,5)], "100%_2"))
Significancia <- rbind(Significancia, getSig(Data100_3[-c(1,2,5)], "100%_3"))
Significancia <- rbind(Significancia, getSig(Data100_4[-c(1,2,5)], "100%_4"))
Significancia <- rbind(Significancia, getSig(Data100_5[-c(1,2,5)], "100%_5"))
```
Con los datos encontrados, es posible afirmar que los sensores 1, 5, 18 y 19 no son significativos para nuestro análisis, y tomando un enfoque muy restrictivo se considerarán únicamente los datos donde por lo menos un valor sea menor a 0,99, esto nos lleva a eliminar los sensores 1, 2, 5, 6, 8, 10, 13, 18 y 19; automatizando este filtro es posible llegar a
```{r}
filtrar <- function(sig, criterio) {
tmp <- apply(sig, 2, (function(col) any(col > criterio)))
return(sig[,- as.array(which(tmp == "FALSE", arr.ind = FALSE))])
}
Significancia <- filtrar(Significancia,0.99)
```
La altura y Mach pueden ser significativos pese a esto por lo que aun no se descartan
```{r}
Significancia <- Significancia[,-c(1:2)]
```
```{r}
func <- function(name,df) {
return(grep(paste("^",name,"$",sep=""), colnames(df)))
}
Data100_1 <- Data100_1[,-apply(as.array(names(Significancia)), 1, func, Data100_1)]
```
Ahora conocemos los datos a considerar y se tienen separados los datos según su régimen correspondiente, el siguiente paso será separar los datos según el motor utilizado, ya que existen muchos valores que se repiten en los gráficos lo que indica superposición de datos en el mismo ciclo, para esto se tiene el script para separar por tipo de motor
```{r}
tmp <- data.frame(as.list(split(Data100_1, Data100_1$Motor)[1]))
names(tmp) <- names(Data100_1)
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor21, type='l')
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor15, type='l')
```
Los datos obtenidos generan curvas útiles, sin embargo, algunas de estas son crecientes mientras que otras son decrecientes, por lo que se realiza una transformacion para que todas sean crecientes, ya que estamos representando el crecimiento de salud
```{r}
getGrowing <- function(col) {
if (col[length(col)] < col[1]) {
col <- rev(col)
}
return(col)
}
tmp[,-(1:5)] <- apply(tmp[,-(1:5)], 2, getGrowing)
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor15, type='l')
```
Sin embargo, esta grafica presenta muchas irregularidades, para limpiar estas se tiene una funcion que aplica una regresion a los datos
```{r}
tmp2 <- tmp
tmp2[,-c(1:5)] <- apply(tmp2[,-c(1:5)], 2, (function(col) predict(loess(col~tmp2$Cycle))))
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor15, type='l')
lines(tmp2$Cycle, tmp2$Sensor15, type='l', col='red')
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor21, type='l')
lines(tmp2$Cycle, tmp2$Sensor21, type='l', col='red')
```
Con los datos suavizados, el unico paso faltante corresponde a normalizar los datos, pues de esta forma es posible notar tendencias sin importar los rangos de operacion que se esten analizando
```{r}
tmp <- tmp2
```
Para realizar la normalizacion se tiene una funcion
```{r}
tmp <- data.frame(apply(tmp, 2, (function(col) col/max(col))))
```
```{r echo=FALSE}
plot(tmp$Cycle, tmp$Sensor21, type='l')
lines(tmp2$Cycle, tmp2$Sensor21, type='l', col='red')
```
Con todas las transformaciones realizadas, se grafican todos los sensores para ver su comportamiento
```{r echo=FALSE}
plot(tmp$Cycle, tmp[,6], type='l', col=colors()[100])
for (x in 7:length(tmp)) {
lines(tmp$Cycle, tmp[,x], type='l', col=colors()[x+30])
}
```
Para repetir este procedimiento con cada uno de los subsets de datos, y con cada motor respectivamente, se programa una funcion que junte todos los elementos demostrados en este segmento
```{r}
write.csv(tmp, file = "Datos_100_1_Motor_1.csv")
```
# Organizando proceso
Se cargan los datos totales del csv
```{r}
Data <- read.csv("train_data.csv")
```
Se invierte el orden de los datos
```{r}
#Data <- data.frame(apply(Data, 2, rev))
```
Separamos con base en los porcentajes del regulador
```{r}
tmp <- split(Data, Data$Throttle)
Data60_1 <- as.data.frame(tmp[1])
Data100 <- as.data.frame(tmp[2])
rm(tmp)
names(Data60_1) <- names(Data)
names(Data100) <- names(Data)
```
Y se separa el subset de 100% en cinco subsets adicionales
```{r}
tmp <- split(Data100, cut(Data100$Height, c(-10,5,15,24,39,55)))
Data100_1 <- as.data.frame(tmp[1])
Data100_2 <- as.data.frame(tmp[2])
Data100_3 <- as.data.frame(tmp[3])
Data100_4 <- as.data.frame(tmp[4])
Data100_5 <- as.data.frame(tmp[5])
rm(tmp, Data100)
names(Data100_1) <- names(Data)
names(Data100_2) <- names(Data)
names(Data100_3) <- names(Data)
names(Data100_4) <- names(Data)
names(Data100_5) <- names(Data)
```
Definimos funcion para insignificancia
```{r}
insignificance <- function(dataFrame, rowName) {
insig <- data.frame(as.list(apply(dataFrame, 2, (function(col) sum(quantile(col))/(quantile(col)[5]*5)))))
row.names(insig) <- c(rowName)
return(insig)
}
```
Calculamos la insignificancia
```{r}
Insignificancia <- insignificance(Data100_1[-c(1,2,5)], "60%_1")
Insignificancia <- rbind(Insignificancia, insignificance(Data100_1[-c(1,2,5)], "100%_1"))
Insignificancia <- rbind(Insignificancia, insignificance(Data100_2[-c(1,2,5)], "100%_2"))
Insignificancia <- rbind(Insignificancia, insignificance(Data100_3[-c(1,2,5)], "100%_3"))
Insignificancia <- rbind(Insignificancia, insignificance(Data100_4[-c(1,2,5)], "100%_4"))
Insignificancia <- rbind(Insignificancia, insignificance(Data100_5[-c(1,2,5)], "100%_5"))
```
Se define funcion para filtrar insignificancia con base en criterio numerico
```{r}
filtrar <- function(sig, criterio) {
tmp <- apply(sig, 2, (function(col) min(col) > criterio))
return(sig[,- as.array(which(tmp == "FALSE", arr.ind = FALSE))])
}
Insignificancia <- filtrar(Insignificancia,0.988)
```
Se usan los resultados de la insignificancia para remover estos datos de los subsets
```{r}
remover <- function(insig,df) {
val <- df[,-apply(as.array(names(insig)), 1, (function(name,df) grep(paste("^",name,"$",sep=""), colnames(df))), df)]
return(val)
}
Data60_1 <- remover(Insignificancia, Data60_1)
Data100_1 <- remover(Insignificancia, Data100_1)
Data100_2 <- remover(Insignificancia, Data100_2)
Data100_3 <- remover(Insignificancia, Data100_3)
Data100_4 <- remover(Insignificancia, Data100_4)
Data100_5 <- remover(Insignificancia, Data100_5)
```
El proceso mas pesado computacionalmente
- Separar segun el motor
- Estandarizar curvas crecientes
- Normalizar datos
- Invertir los ciclos
```{r}
getGrowing <- function(col) {
if (col[length(col)] < col[1]) {
col <- rev(col)
}
return(col)
}
```
```{r}
tmp <- data.frame(as.list(split(Data100_1, Data100_1$Motor)[1]))
names(tmp) <- names(Data100_1)
tmp[,-(1:5)] <- apply(tmp[,-(1:5)], 2, getGrowing)
tmp[,-c(1:5)] <- apply(tmp[,-c(1:5)], 2, (function(col) predict(loess(col~tmp$Cycle))))
tmp[,-c(1:5)] <- data.frame(apply(tmp[,-c(1:5)], 2, (function(col) col/max(col))))
```
```{r echo=FALSE}
par(mar=c(5.1, 4.8, 1.1, 8.1), xpd=TRUE)
colores = rainbow(500)
plot(tmp$Cycle, tmp[,6], type='l', col=colores[100], ylim=c(min(tmp[,-(1:5)]),max(tmp[,-(1:5)])), ylab = 'Sensores', xlab = 'Ciclos', lwd=4.0)
leg <- c(names(tmp)[6])
col <- c(colores[100])
for (x in 7:length(tmp)) {
lines(tmp$Cycle, tmp[,x], type='l', col=colores[x+(30*x)], lwd=4.0)
leg <- rbind(leg, c(names(tmp)[x]))
col <- rbind(col, c(colores[x+(30*x)]))
}
legend("topright", inset=c(-0.32,0), box.col = "brown",
bg ="yellow", box.lwd = 2,
legend=leg,
fill = col)
```