Форум врачей-аспирантов

Здравствуйте, гость ( Вход | Регистрация )

 
Добавить ответ в эту темуОткрыть тему
> Подскажите со стат.методом
Де бин Анатолий
сообщение 12.10.2017 - 13:33
Сообщение #1





Группа: Пользователи
Сообщений: 25
Регистрация: 15.08.2014
Пользователь №: 26591



Приветствую. help.gif, пожалуйста, мне тут метод выбрать в такой задаче.
У меня есть данные по 80 приборам, по каждому циклу, для каждого прибор, разные датчики дают указание. Как я могу предложить на основании этих данных, что прибор неисправен? Какой статистический метод я должен использовать?
Прибор считается вышедшим из строя, если больше измерений по нему нет. Например, есть измерения по циклам 1-151. Значит, что на 152 цикле прибор вышел из строя.

Может ли тут помочь анализ выживаемости?

Сообщение отредактировал Де бин Анатолий - 12.10.2017 - 18:09
Прикрепленные файлы
Прикрепленный файл  mydat.zip ( 586,63 килобайт ) Кол-во скачиваний: 218
 
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
leo_biostat
сообщение 14.10.2017 - 19:24
Сообщение #2





Группа: Пользователи
Сообщений: 105
Регистрация: 23.11.2016
Пользователь №: 28953



Анатолий, hi.gif!

У Вас отличный массив данных! 25 признаков и 16139 наблюдений. Задача непростая, и поэтому не стоит ориентироваться на элементарные, примитивные методы. Лет 40 назад у меня была одна подобная задача, когда я работал в одном техническом НИИ.
Нужно было сравнить полтора десятка приборов, и установить идентичность и различие этих приборов. Число наблюдений было гораздо больше. И тоже возникла проблема выбора оптимальной коллекции методов анализа. Исходя из своего опыта решения этой и иных подобных задач, рекомендую использовать следующие методы анализа:
1. Кластерный анализ.
2. Анализ таблиц сопряжённости, с анализом структуры связи.
3. Дискриминантный анализ.
4. Анализ канонической корреляции, с графикой распределения по новым осям.
5. Анализ функций распределения признаков по имеющимся группировкам, и установленным кластерам.
6. Сравнение параметров распределения уже имеющихся группировок, и установленных кластеров.

По результатам этих анализов нужно будет установить те приборы, которые статистически значимо отличаются по своим показаниям от идентичных группировок, а также установить наличие аномальных значений измеряемых величин у конкретных приборов в конкретных группах. Это и будет аргументацией для принятия подобных приборов аномальными.

Желаю успеха!


Цитата(Де бин Анатолий @ 12.10.2017 - 13:33) *
Приветствую. help.gif, пожалуйста, мне тут метод выбрать в такой задаче.
У меня есть данные по 80 приборам, по каждому циклу, для каждого прибор, разные датчики дают указание. Как я могу предложить на основании этих данных, что прибор неисправен? Какой статистический метод я должен использовать?
Прибор считается вышедшим из строя, если больше измерений по нему нет. Например, есть измерения по циклам 1-151. Значит, что на 152 цикле прибор вышел из строя.

Может ли тут помочь анализ выживаемости?

Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 15.10.2017 - 20:33
Сообщение #3





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Цитата(Де бин Анатолий @ 12.10.2017 - 13:33) *
Приветствую. help.gif, пожалуйста, мне тут метод выбрать в такой задаче.
У меня есть данные по 80 приборам, по каждому циклу, для каждого прибор, разные датчики дают указание. Как я могу предложить на основании этих данных, что прибор неисправен? Какой статистический метод я должен использовать?
Прибор считается вышедшим из строя, если больше измерений по нему нет. Например, есть измерения по циклам 1-151. Значит, что на 152 цикле прибор вышел из строя.

Может ли тут помочь анализ выживаемости?


Можно использовать анализ выживаемости, но тогда придется "ручками" сводить многомерную последовательность индивидуальных показаний прибора к строке фиксированной длинны.

Это задача в целом стандартная и описывается паттерном "many to one". Решение тоже стандартное -- грузиться library(keras) и описывается сетка с LSTM (хот для такого размера выборки GRU) слоем который и сворачивает историю прибора в вектор стандартной длины. На выходе предиктор "авария есть -- аварии нет". На входе список с историями приборов + всякая его нормализация.

Если "прогноз момента отказа" надо сделать, то тогда придется делать архитектуру seq2seq, и на выход модели пристраивать еще один слой GRU который будет выдавать цепочку непрерывную "все ок"кончающуюся "всё плохо" для сломавшихся приборов.

В общем тут надо конкретно разбираться что предсказывать надо.

PS
Но конечно можно и марковские цепочки попробовать пообучать, хоть это и весьма геморройное занятие. smile.gif


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
Де бин Анатолий
сообщение 16.10.2017 - 12:41
Сообщение #4





Группа: Пользователи
Сообщений: 25
Регистрация: 15.08.2014
Пользователь №: 26591



Код
Это задача в целом стандартная и описывается паттерном "many to one". Решение тоже стандартное -- грузиться library(keras) и описывается сетка с LSTM (хот для такого размера выборки GRU) слоем который и сворачивает историю прибора в вектор стандартной длины. На выходе предиктор "авария есть -- аварии нет". На входе список с историями приборов + всякая его нормализация.

установил библиотечку keras
нашел в хелпе описание

Код
layer_conv_lstm_2d {keras}    R Documentation
Convolutional LSTM.

Description

It is similar to an LSTM layer, but the input transformations and recurrent transformations are both convolutional.

Usage

layer_conv_lstm_2d(object, filters, kernel_size, strides = c(1L, 1L),
  padding = "valid", data_format = NULL, dilation_rate = c(1L, 1L),
  activation = "tanh", recurrent_activation = "hard_sigmoid",
  use_bias = TRUE, kernel_initializer = "glorot_uniform",
  recurrent_initializer = "orthogonal", bias_initializer = "zeros",
  unit_forget_bias = TRUE, kernel_regularizer = NULL,
  recurrent_regularizer = NULL, bias_regularizer = NULL,
  activity_regularizer = NULL, kernel_constraint = NULL,
  recurrent_constraint = NULL, bias_constraint = NULL,
  return_sequences = FALSE, go_backwards = FALSE, stateful = FALSE,
  dropout = 0, recurrent_dropout = 0, batch_size = NULL, name = NULL,
  trainable = NULL, weights = NULL, input_shape = NULL)



А прикладного примера в хелпе нет, обычно он есть. Мне без него сложно перенести идею на мои данные.
в роле object
мой датасет должен быть?
setwd(mydir)
mydat=read.csv(mydat)

Сообщение отредактировал Де бин Анатолий - 16.10.2017 - 12:43
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 16.10.2017 - 19:54
Сообщение #5





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Цитата(Де бин Анатолий @ 16.10.2017 - 12:41) *
А прикладного примера в хелпе нет, обычно он есть. Мне без него сложно перенести идею на мои данные.


У самого кераса точно также с документацией, все лежит в руководствах.

На странице пакета в cran много руководств лежит (и в этих руководствах много ссылок на дополнительную информацию с сайта Революшен)

https://cran.r-project.org/web/packages/keras/index.html

Начинаете с Getting Started with Keras и потом Guide to the Functional API.


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 18.10.2017 - 16:03
Сообщение #6





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Цитата(Де бин Анатолий @ 16.10.2017 - 12:41) *
Код
Это задача в целом стандартная и описывается паттерном "many to one". Решение тоже стандартное -- грузиться library(keras) и описывается сетка с LSTM (хот для такого размера выборки GRU) слоем который и сворачивает историю прибора в вектор стандартной длины. На выходе предиктор "авария есть -- аварии нет". На входе список с историями приборов + всякая его нормализация.

установил библиотечку keras
нашел в хелпе описание

Код
layer_conv_lstm_2d {keras}    R Documentation
Convolutional LSTM.

Description

It is similar to an LSTM layer, but the input transformations and recurrent transformations are both convolutional.

Usage

layer_conv_lstm_2d(object, filters, kernel_size, strides = c(1L, 1L),
  padding = "valid", data_format = NULL, dilation_rate = c(1L, 1L),
  activation = "tanh", recurrent_activation = "hard_sigmoid",
  use_bias = TRUE, kernel_initializer = "glorot_uniform",
  recurrent_initializer = "orthogonal", bias_initializer = "zeros",
  unit_forget_bias = TRUE, kernel_regularizer = NULL,
  recurrent_regularizer = NULL, bias_regularizer = NULL,
  activity_regularizer = NULL, kernel_constraint = NULL,
  recurrent_constraint = NULL, bias_constraint = NULL,
  return_sequences = FALSE, go_backwards = FALSE, stateful = FALSE,
  dropout = 0, recurrent_dropout = 0, batch_size = NULL, name = NULL,
  trainable = NULL, weights = NULL, input_shape = NULL)



А прикладного примера в хелпе нет, обычно он есть. Мне без него сложно перенести идею на мои данные.
в роле object
мой датасет должен быть?
setwd(mydir)
mydat=read.csv(mydat)




Массив входных данных вот как то так готовиться

Код
df.data <- read.csv2("mydat.csv")
library(dplyr)
library(keras)



data.list <- lapply(split(df.data, df.data$id), as.list)
pribor_order <- names(data.list)
names(data.list) <- NULL
data.list <- lapply(data.list, function(l) {names(l) <- NULL; l[5:25]})
data.list <- lapply(data.list, function(l) lapply(l, as.numeric))

data.list <- lapply(data.list, function(l) as.matrix(data.frame(l)))


В результате мы можем подготовить входные истории для GRU

Код
> str(pad_sequences(data.list))
int [1:80, 1:362, 1:21] 0 0 0 0 0 0 0 0 0 0 ...


максимальная история 362 события, остальные добиты "0" до той же длинны


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 18.10.2017 - 18:22
Сообщение #7





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Вот собственно сетка целиком.

Код
df.data <- read.csv2("mydat.csv")
library(dplyr)
library(keras)

data.list <- lapply(split(df.data, df.data$id), as.list)
pribor_order <- names(data.list)
names(data.list) <- NULL
data.list <- lapply(data.list, function(l) {names(l) <- NULL; l[5:25]})
data.list <- lapply(data.list, function(l) lapply(l, as.numeric))

data.list <- lapply(data.list, function(l) as.matrix(data.frame(l)))

pribor.out <- sapply(pribor_order, function(n) sum(df.data$id == n))

seqLength <- 50

in_seq_event <- pad_sequences(data.list, truncating = 'post', maxlen = seqLength)

## model

drop <- 0.4

K <- backend()
K$clear_session()

main_input <- layer_input(shape = c(seqLength, 21), dtype = 'float32', name = 'main_input')

data_in_norm <- main_input %>%
    layer_batch_normalization()

## bidirectional()

lstm_out.forw <- data_in_norm %>%
    layer_lstm(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2) %>%
    layer_batch_normalization()

lstm_out.back <- data_in_norm %>%
    layer_lstm(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2,
               go_backwards=T) %>%
    layer_batch_normalization()


main_output <- layer_concatenate(c(lstm_out.forw,
                                   lstm_out.back)) %>%  
    layer_dense(units = 8, activation = 'relu') %>%
    layer_batch_normalization() %>%
    layer_dropout(drop) %>%
    layer_dense(units = 8, activation = 'relu') %>%
    layer_batch_normalization() %>%
    layer_dropout(drop) %>%
    layer_dense(units = 1, activation = 'linear', name = 'main_output')


model <- keras_model(
    inputs = c(main_input),
    outputs = c(main_output)
)

model %>%
    compile(
        optimizer = 'adam',
        loss = 'mean_squared_error'
    )

summary(model)

history <- model %>%
    fit(x = list(in_seq_event),
        y = list(pribor.out),
        validation_split = 0.1,
        epochs = 340,
        batch_size = 8)

plot(history)


pribor_predict <- model %>%
    predict(x = list(in_seq_event),
            batch_size = 8,
            verbose = 1)

plot(pribor.out, pribor_predict)


По первым 50 записям логов приборов


Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 19.10.2017 - 10:22
Сообщение #8





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Нормализацию забыл, вот так намного устойчивее и точнее...

В принципе приборов похоже две группы.

Код
df.data <- read.csv2("mydat.csv")

str(df.data)

df.data.norm <- (data.frame(lapply(df.data[,!sapply(df.data, is.factor)], scale))+2)[, -c(1,2,3,4,10,12,13)]

library(dplyr)
library(keras)



data.list <- lapply(split(df.data.norm, df.data$id), as.list)
pribor_order <- names(data.list)
names(data.list) <- NULL
data.list <- lapply(data.list, function(l) {names(l) <- NULL; l})

data.list <- lapply(data.list, function(l) lapply(l, as.numeric))

data.list <- lapply(data.list, function(l) as.matrix(data.frame(l)))

## data.list <- lapply(data.list, normalize)

pribor.out <- sapply(pribor_order, function(n) sum(df.data$id == n))

seqLength <- 50

in_seq_event <- pad_sequences(data.list, truncating = 'post', maxlen = seqLength)

## model

drop <- 0.4

K <- backend()
K$clear_session()

main_input <- layer_input(shape = c(seqLength, 18), dtype = 'float32', name = 'main_input')

data_in_norm <- main_input %>%
    layer_batch_normalization()

## bidirectional()

lstm_out.forw <- data_in_norm %>%
    layer_gru(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2,
               return_sequences = T) %>%
    layer_batch_normalization() %>%
    layer_gru(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2) %>%
    layer_batch_normalization()

lstm_out.back <- data_in_norm %>%
    layer_gru(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2,
               return_sequences = T,
               go_backwards=T) %>%
    layer_batch_normalization() %>%
    layer_gru(units = 8,
               dropout = 0.2,
               recurrent_dropout = 0.2,
               go_backwards=T) %>%
    layer_batch_normalization()


main_output <- layer_concatenate(c(lstm_out.forw,
                                   lstm_out.back)) %>%  
    layer_dense(units = 8, activation = 'relu') %>%
    layer_batch_normalization() %>%
    layer_dropout(drop) %>%
#    layer_dense(units = 8, activation = 'relu') %>%
#    layer_batch_normalization() %>%
#    layer_dropout(drop) %>%
    layer_dense(units = 8, activation = 'relu') %>%
    layer_batch_normalization() %>%
    layer_dropout(drop) %>%
    layer_dense(units = 1, activation = 'linear', name = 'main_output')


model <- keras_model(
    inputs = c(main_input),
    outputs = c(main_output)
)

model %>%
    compile(
        ## optimizer = 'rmsprop',
        ## optimizer = 'nadam',
        optimizer = 'adam',
        loss = 'mean_squared_error'
        ## loss = 'binary_crossentropy'
        ## loss_weights = c(1.0, 0.2)
    )

summary(model)

history <- model %>%
    fit(x = list(in_seq_event),
        y = list(pribor.out),
        ## y = list(labels, labels),
        validation_split = 0.1,
        #class_weight = list("0"=0.1392319, "1"=1),
        epochs = 177*2+77,
        #callbacks = list(callback_reduce_lr_on_plateau(monitor = "val_loss", factor = 0.1),
        #                 callback_tensorboard("logs/run_a", write_images = T, embeddings_freq = 1)),
        batch_size = 8)

plot(history)


pribor_predict <- model %>%
    predict(x = list(in_seq_event),
            batch_size = 8,
            verbose = 1)

plot(pribor.out, pribor_predict)


Сообщение отредактировал p2004r - 19.10.2017 - 10:24
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 21.10.2017 - 16:03
Сообщение #9





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Ну и собственно кластеризация по "импульсным переходным функция" восстановленным рекуррентными слоями модели

Код
lstm_out.forw_model <- keras_model(inputs = model$input,
                                   outputs = lstm_out.forw)
lstm_out.forw_output <- predict(lstm_out.forw_model, x = list(in_seq_event), batch_size = 8, verbose = 1)

lstm_out.back_model <- keras_model(inputs = model$input,
                                   outputs = lstm_out.back)
lstm_out.back_output <- predict(lstm_out.back_model, x = list(in_seq_event), batch_size = 8, verbose = 1)

str(lstm_out.forw_output)
str(lstm_out.back_output)

pairs(cbind(prcomp(cbind(lstm_out.forw_output,
                         lstm_out.back_output),
                   center=T, scale.=T)$x[,1:3],
            pribor.out))


Как видно из графика действительно две группы приборов + некая функция "наработки на отказ".


Эскизы прикрепленных изображений
Прикрепленное изображение
 


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 
p2004r
сообщение 21.10.2017 - 16:08
Сообщение #10





Группа: Пользователи
Сообщений: 1091
Регистрация: 26.08.2010
Пользователь №: 22699



Ну и по именам приборы в разных группах

Код
> pribor_order[which(prcomp(cbind(lstm_out.forw_output,
+                                 lstm_out.back_output),
+                           center=T, scale.=T)$x[,1] < 0)]
[1] "Engine_1"  "Engine_10" "Engine_11" "Engine_15" "Engine_17" "Engine_18"
[7] "Engine_2"  "Engine_28" "Engine_3"  "Engine_30" "Engine_31" "Engine_33"
[13] "Engine_41" "Engine_43" "Engine_44" "Engine_45" "Engine_46" "Engine_47"
[19] "Engine_48" "Engine_5"  "Engine_51" "Engine_54" "Engine_58" "Engine_59"
[25] "Engine_61" "Engine_64" "Engine_65" "Engine_67" "Engine_69" "Engine_7"
[31] "Engine_72" "Engine_74" "Engine_78" "Engine_79" "Engine_9"
>
> pribor_order[which(prcomp(cbind(lstm_out.forw_output,
+                                 lstm_out.back_output),
+                           center=T, scale.=T)$x[,1] >= 0)]
[1] "Engine_12" "Engine_13" "Engine_14" "Engine_16" "Engine_19" "Engine_20"
[7] "Engine_21" "Engine_22" "Engine_23" "Engine_24" "Engine_25" "Engine_26"
[13] "Engine_27" "Engine_29" "Engine_32" "Engine_34" "Engine_35" "Engine_36"
[19] "Engine_37" "Engine_38" "Engine_39" "Engine_4"  "Engine_40" "Engine_42"
[25] "Engine_49" "Engine_50" "Engine_52" "Engine_53" "Engine_55" "Engine_56"
[31] "Engine_57" "Engine_6"  "Engine_60" "Engine_62" "Engine_63" "Engine_66"
[37] "Engine_68" "Engine_70" "Engine_71" "Engine_73" "Engine_75" "Engine_76"
[43] "Engine_77" "Engine_8"  "Engine_80"


Сообщение отредактировал p2004r - 21.10.2017 - 21:39
Эскизы прикрепленных изображений
Прикрепленное изображение
 


Signature
Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения
 

Добавить ответ в эту темуОткрыть тему