JoVE Logo

Entrar

É necessária uma assinatura da JoVE para visualizar este conteúdo. Faça login ou comece sua avaliação gratuita.

Neste Artigo

  • Resumo
  • Resumo
  • Introdução
  • Protocolo
  • Resultados
  • Discussão
  • Divulgações
  • Agradecimentos
  • Materiais
  • Referências
  • Reimpressões e Permissões

Resumo

Este estudo avalia sistemas prognósticos para pacientes com carcinoma de células em anel de sinete colorretal usando modelos de aprendizado de máquina e análises de risco concorrentes. Ele identifica as chances logarítmicas de linfonodos positivos como um preditor superior em comparação com o estadiamento pN, demonstrando forte desempenho preditivo e auxiliando na tomada de decisões clínicas por meio de ferramentas robustas de previsão de sobrevida.

Resumo

O status dos linfonodos é um preditor prognóstico crítico para os pacientes; no entanto, o prognóstico do carcinoma colorretal de células em anel de sinete (SRCC) tem recebido atenção limitada. Este estudo investiga a capacidade preditiva prognóstica das chances logarítmicas de linfonodos positivos (LODDS), razão linfonodal (LNR) e estadiamento pN em pacientes com SRCC usando modelos de aprendizado de máquina (Random Forest, XGBoost e Neural Network) juntamente com modelos de risco concorrentes. Os dados relevantes foram extraídos do banco de dados Surveillance, Epidemiology, and End Results (SEER). Para os modelos de aprendizado de máquina, os fatores prognósticos para a sobrevida específica do câncer (CSS) foram identificados por meio de análises de regressão de Cox univariadas e multivariadas, seguidas pela aplicação de três métodos de aprendizado de máquina - XGBoost, RF e NN - para determinar o sistema ideal de estadiamento linfonodal. No modelo de risco competitivo, análises de risco competitivas univariadas e multivariadas foram empregadas para identificar fatores prognósticos, e um nomograma foi construído para prever o prognóstico de pacientes com CCRE. A área sob a curva característica de operação do receptor (AUC-ROC) e as curvas de calibração foram utilizadas para avaliar o desempenho do modelo. Um total de 2.409 pacientes com CEC foram incluídos neste estudo. Para validar a eficácia do modelo, uma coorte adicional de 15.122 pacientes com câncer colorretal, excluindo casos de SRCC, foi incluída para validação externa. Tanto os modelos de aprendizado de máquina quanto o nomograma de risco concorrente exibiram forte desempenho na previsão de resultados de sobrevida. Em comparação com o estadiamento pN, os sistemas de estadiamento LODDS demonstraram capacidade prognóstica superior. Após a avaliação, os modelos de aprendizado de máquina e os modelos de risco concorrentes alcançaram excelente desempenho preditivo caracterizado por boa discriminação, calibração e interpretabilidade. Nossos achados podem ajudar a informar a tomada de decisão clínica para os pacientes.

Introdução

O câncer colorretal (CCR) é o terceiro tumor maligno mais prevalente globalmente 1,2,3. O carcinoma de células em anel de sinete (CEC), um subtipo raro de CCR, compreende aproximadamente 1% dos casos e é caracterizado por mucina intracelular abundante deslocando o núcleo celular 1,2,4. O CEC é frequentemente associado a pacientes mais jovens, tem maior prevalência em mulheres e tem estágios tumorais avançados no momento do diagnóstico. Em comparação com o adenocarcinoma colorretal, o CEC apresenta menor diferenciação, maior risco de metástase à distância e sobrevida em 5 anos de apenas 12%-20%5,6. O desenvolvimento de um modelo prognóstico preciso e eficaz para o SRCC é crucial para otimizar as estratégias de tratamento e melhorar os resultados clínicos.

Este estudo tem como objetivo construir um modelo prognóstico robusto para pacientes com SRCC usando abordagens estatísticas avançadas, incluindo aprendizado de máquina (ML) e modelos de risco concorrentes. Essas metodologias podem acomodar relacionamentos complexos em dados clínicos, oferecendo avaliações de risco individualizadas e superando os métodos tradicionais em precisão preditiva. Modelos de aprendizado de máquina, como Random Forest, XGBoost e Neural Networks, se destacam no processamento de dados de alta dimensão e na identificação de padrões intrincados. Estudos mostraram que os modelos de IA preveem efetivamente os resultados de sobrevida no câncer colorretal, enfatizando o potencial do ML em aplicações clínicas 7,8. Complementando o ML, os modelos de risco concorrentes abordam vários tipos de eventos, como mortalidade específica por câncer versus outras causas de morte, para refinar a análise de sobrevida. Ao contrário dos métodos tradicionais, como o estimador de Kaplan-Meier, os modelos de risco competitivo estimam com precisão a probabilidade marginal de eventos na presença de riscos concorrentes, fornecendo avaliações de sobrevida mais precisas8. A integração de ML e análise de risco competitivo melhora o desempenho preditivo, oferecendo uma estrutura poderosa para ferramentas de prognóstico personalizadas no SRCC 9,10,11.

A metástase linfonodal influencia significativamente o prognóstico e a recorrência em pacientes com CCR. Embora a avaliação em estágio N na classificação TNM seja crítica, o exame inadequado dos linfonodos - relatado em 48% a 63% dos casos - pode levar à subestimação da doença. Para resolver isso, foram introduzidas abordagens alternativas, como a razão de linfonodos (LNR) e as chances logarítmicas de linfonodos positivos (LODDS). O LNR, a razão entre linfonodos positivos (PLNs) e linfonodos totais (TLNs), é menos afetado pela contagem de TLN e serve como um fator prognóstico no CCR. LODDS, a razão logarítmica de PLNs para linfonodos negativos (NLNs), mostrou capacidade preditiva superior tanto no SRCC gástrico quanto no câncer colorretal10,11. O aprendizado de máquina tem sido cada vez mais aplicado em oncologia, com modelos que melhoram a estratificação de risco e as previsões prognósticas em vários tipos de câncer, incluindo câncer de mama, próstata e pulmão 12,13,14. No entanto, sua aplicação no CEC colorretal permanece limitada.

Este estudo procura preencher essa lacuna integrando LODDS com ML e modelos de risco concorrentes para criar uma ferramenta de prognóstico abrangente. Ao avaliar o valor prognóstico do LODDS e alavancar técnicas preditivas avançadas, esta pesquisa visa melhorar a tomada de decisões clínicas e melhorar os resultados para pacientes com SRCC.

Access restricted. Please log in or start a trial to view this content.

Protocolo

Este estudo não se refere à aprovação ética e consentimento para participar. Os dados utilizados neste estudo foram obtidos de bancos de dados. Incluímos pacientes diagnosticados com carcinoma colorretal de células em anel de sinete de 2004 a 2015, bem como outros tipos de câncer colorretal. Os critérios de exclusão incluíram pacientes com tempo de sobrevida inferior a um mês, aqueles com informações clínico-patológicas incompletas e casos em que a causa da morte não era clara ou não especificada.

1. Aquisição de dados

  1. Baixar SEER. Obtenha o software de estatísticas 8.4.3 no site do banco de dados SEER (http://seer.cancer.gov/about/overview.html). Depois de fazer login no software, clique em Sessão de lista de casos > Dados e selecione o banco de dados Incidence SEER Research Plus Data, 17 Registries, Nov 2021 Sub (2000-2019).
  2. Clique em Seleção > Editar e escolha {Raça, Sexo, Ano Dx. Ano do diagnóstico} = '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015' E {Local e Morfologia. Recodificação do site CID-O-3/OMS 2008} = '8490/3'.
  3. Em seguida, clique em Tabela e, na interface de variáveis disponíveis, selecione Recodificação de idade com idades únicas e 100+, Sexo, Conjugal, Recodificação de local CID-O-3/OMS 2008, Tamanho do tumor CS, Regional nodes_examined (1988+), Regional nodes_positive (1988+), Grupo de estágios AJCC derivado, 6ª ed (2004-2015), AJCC derivado T, 6ª ed (2004-2015), AJCC derivado N, 6ª ed (2004-2015), AJCC M derivado, 6ª ed (2004-2015), CEA, Recodificação de radiação, Recodificação de quimioterapia (sim, não/desconhecido), Classificação de morte específica por causa SEER, Recodificação do estado vital (corte de estudo usado), Meses de sobrevida, Ano do diagnóstico.
  4. Por fim, clique em Saída, nomeie os dados e clique em Executar para gerar e salvar os dados. O processo de inclusão detalhado é mostrado na Figura 1.
  5. Baixe dados de pacientes com câncer colorretal, excluindo casos de SRCC, para validação externa subsequente. Clique em Seleção > Editar e escolha {Raça, Sexo, Ano Dx. Ano do diagnóstico} = '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015' E {Local Primário - rotulado} = 'C18-C20'. Repita as etapas 1.3 e 1.4 para obter informações clínico-patológicas e excluir amostras com {Site e Morfologia. Recodificação do site CID-O-3/OMS 2008} = '8490/3' do arquivo baixado.
  6. Para fins comparativos, processe várias variáveis. Classifique o status dos linfonodos usando a razão dos linfonodos (LNR) e o logaritmo das chances de linfonodos positivos (LODDS).
    1. Defina LNR como a proporção de linfonodos positivos (PLNs) para linfonodos totais (TLNs). Calcule o valor LODDS usando a fórmula:
      loge(número de PLNs + 0,5) / (número de linfonodos negativos (NLNs) + 0,5)
      onde 0,5 foi adicionado para evitar um resultado infinito. Os valores de corte para LNR, LODDS e tamanho do tumor foram determinados usando o software X-tile (versão 3.6.1) com base no método do valor mínimo de P.
  7. Abra o software X-tile, clique em Arquivo > Abrir e selecione o arquivo de dados para importá-lo para o software. Depois que os dados forem carregados, mapeie as variáveis: Censor corresponde ao status de sobrevivência, Tempo de sobrevivência corresponde ao tempo de sobrevivência e Marker1 é a variável a ser analisada, garantindo que os dados correspondam corretamente.
  8. Em seguida, clique em Do > Kaplan-Meier > Marker1 para realizar a análise de sobrevida de Kaplan-Meier e gerar a curva de sobrevida. Com base na separação das curvas de sobrevida de Kaplan-Meier, significância estatística (por exemplo, valor de p) e relevância clínica, determine o valor de corte ideal e, finalmente, registre ou exporte os resultados da análise.
    1. Divida o LNR em três grupos: LNR 1 (≤0,16), LNR 2 (0,16 - 0,78) e LNR 3 (≥ 0,78). Categorize os pacientes em três grupos com base no LODDS: LODDS 1 (≤ -1,44), LODDS 2 (-1,44 - 0,86) e LODDS 3 (≥ 0,86).
    2. Classifique o tamanho do tumor em três categorias: ≤ 3,5 cm, 3,5 - 5,5 cm e ≥ 5,5 cm. Converta a idade de uma variável contínua para uma variável categórica. Categorize a idade dos pacientes no momento do diagnóstico inicial em ≥60 anos e <60 anos. Classifique a localização do tumor com base na distribuição dos tumores de carcinoma de células em anel de sinete (SRCC) como cólon direito, cólon esquerdo e reto. O cólon direito inclui o ceco, o cólon ascendente, a flexura hepática e o cólon transverso, enquanto o cólon esquerdo inclui a flexura esplênica, o cólon descendente, o cólon sigmóide e a junção retossigmoide.
  9. Para este estudo, atribua aleatoriamente um total de 2409 dados de pacientes elegíveis com SRCC a uma coorte de treinamento (N = 1686) e uma coorte de validação (N = 723) em uma proporção de 7:3. Use o código a seguir para divisão aleatória e data.csv de origem do banco de dados SEER. Os arquivos gerados após a divisão aleatória serão usados para análise posterior.
    biblioteca (acento circunflexo)
    Dados <- read.csv("data.csv")
    set.seed(123)
    train_indices <- createDataPartition(dados$variável, p = 0,7, lista = FALSO)
    train_data <- dados[train_indices, ]
    test_data <- dados[-train_indices, ]
    write.csv(train_data, "traindata.csv", row.names = FALSE)
    write.csv(test_data, "testdata.csv", row.names = FALSE)

2. Desenvolvimento e verificação de modelos de ML

  1. Baixe o RStudio (2024.04.2+764) e o software R (4.4.1). Abra o RStudio para executar o software R. Clique em Novo Arquivo e selecione Script R para criar uma nova interface de programação R. Insira o código relevante no editor de código e clique em Executar para executar o código.
  2. Use o código a seguir para filtrar as variáveis incluídas nos modelos de ML pela análise de regressão de Cox. Além disso, explore o impacto do estadiamento LODDS, LNR e pN na sobrevida específica do câncer (CSS) em pacientes com SRCC. O traindata.csv são dados obtidos do banco de dados SEER.
    biblioteca ("sobrevivência")
    biblioteca("survminer")
    biblioteca("rms")
    biblioteca("dplyr")
    Dados <- read.csv("traindata.csv")
    dados$tempo=as.numeric(dados$tempo)
    dados$status=as.numeric(dados$status)
    variáveis <- c("Sexo", "Idade", "Raça", "Conjugal", "Estágio", "T", "N", "M","Tumor_size", "LNR", "LODDS", "CEA","Radiação", "Quimioterapia", "Local")
    dados <- dados %>%
    mutate(across(all_of(variáveis), as.factor))
    cox=coxph(Surv(tempo, status) ~ dados$T, dados = dados)
    cox$coeficientes
    pval=anova(cox)$Pr[2]
    clean_data=dados[,c(1:12, 14:18)]
    get_coxVariable=função(your_data;índice){cox_list=c() k=1
    for (i em 1:index) {mod=coxph(Surv(time, status) ~ your_data[,i],data=your_data) pval=anova(mod)$Pr[2] print(pval) print(colnames(your_data)[i]) if (pval<0.05) {cox_list[k]=colnames(your_data)[i] k=k+1}}return(cox_list)}
    variable_select=get_coxVariable(clean_data,15)
    for(i em 1:15){print(variable_select[i])}
    for (var em variable_select) {formula <- as.formula(paste("Surv(time, status) ~", var))cox_model <- coxph(formula, data = data) print(summary(cox_model))
    ggforest(cox)
    variáveis <- c("Sexo", "Idade", "Raça", "Conjugal", "Estágio", "T", "N", "M", "Tumor_size", "LNR", "LODDS", "Quimioterapia")
    dados <- dados %>%
    mutate(across(all_of(variáveis), as.factor))
    cox=coxph(Surv(tempo, status) ~ Sexo+Idade+Raça+Conjugal+T+N+M+Tumor_size+LNR+
    LODDS+Quimioterapia, dados = dados)
    ggforest(cox,data = data)
    ggplot_forest <- ggforest(cox, dados = dados)
  3. Use o código a seguir para comparar as habilidades de previsão prognóstica de três sistemas LN (LODDS, LNR e pN staging) nas coortes de treinamento, validação e validação externa.
    Biblioteca (RMS)
    biblioteca (sobrevivência)
    Biblioteca (Survminer)
    library(riskRegression)
    biblioteca(gt)
    train_data <- read.csv("train_data123.csv")
    validation_data <- read.csv("test_data123.csv")
    DD <- distDados(train_data)
    opções(distDados(DistDados= "DD")
    model_LNR <- cph(Surv(tempo, status) ~ LNR, dados = train_data, x = VERDADEIRO, y = VERDADEIRO)
    model_LODDS <- cph(Surv(tempo, status) ~ LODDS, dados = train_data, x = VERDADEIRO, y = VERDADEIRO)
    model_pN <- cph(Surv(tempo, status) ~ N, dados = train_data, x = VERDADEIRO, y = VERDADEIRO)
    calculate_performance <- function(model, data) {pred <- predict(model, newdata = data) c_index_result <- concordance(Surv(data$time, data$status) ~ pred) c_index <- c_index_result$concordance aic <- AIC(model) bic <- BIC(model) return(c(C_index = round(c_index, 3), AIC = round(aic, 2), BIC = round(bic, 2)))}
    calculate_performance <- function(model, data) {pred <- predict(model, newdata = data, type = "lp") concordance_result <- concordancefit(Surv(data$time, data$status), x = pred) c_index <- concordance_result$concordance ci_lower <- c_index - 1.96 * sqrt(concordance_result$var) ci_upper <- c_index + 1.96 * sqrt(concordance_result$var) aic <- AIC(modelo) bic <- BIC(modelo) return(c(C_Index = round(c_index, 3), CI_Lower = round(ci_lower, 3), CI_Upper = round(ci_upper, 3), AIC = round(aic, 2), BIC = round(bic, 2)))}
    train_LNR <- calculate_performance(model_LNR, train_data)
    train_LODDS <- calculate_performance(model_LODDS, train_data)
    train_pN <- calculate_performance(model_pN, train_data)
    model_LNR_val <- cph(Surv(tempo, status) ~ LNR, dados = validation_data, x = VERDADEIRO, y = VERDADEIRO)
    model_LODDS_val <- cph(Surv(tempo, status) ~ LODDS, dados = validation_data, x = VERDADEIRO, y = VERDADEIRO)
    model_pN_val <- cph(Surv(tempo, status) ~ N, dados = validation_data, x = VERDADEIRO, y = VERDADEIRO)
    val_LNR <- calculate_performance(model_LNR_val, validation_data)
    val_LODDS <- calculate_performance(model_LODDS_val, validation_data)
    val_pN <- calculate_performance(model_pN_val, validation_data)
    resultados <- data.frame(Variável = c("LNR", "LODDS", "pN"), Training_C_Index = c(paste(train_LNR["C_Index"], "(", train_LNR["CI_Lower"], ", ", train_LNR["CI_Upper"], ")", sep = ""), paste(train_LODDS["C_Index"], "(", train_LODDS["CI_Lower"], ", ", train_LODDS["CI_Upper"], ")", sep = ""), paste(train_pN["C_Index"], "(", train_pN["CI_Lower"], ", ", train_pN["CI_Upper"], ")", sep = "")Training_AIC = c(train_LNR["AIC"], train_LODDS["AIC"], train_pN["AIC"]), Training_BIC = c(train_LNR["BIC"], train_LODDS["BIC"], train_pN["BIC"]), Validation_C_Index = c(paste(val_LNR["C_Index"], "(", val_LNR["CI_Lower"], ", ", ", val_LNR["CI_Upper"], ")", sep = ""), paste(val_LODDS["C_Index"], "(", val_LODDS["CI_Lower"], ", ", val_LODDS["CI_Upper"], ")", sep = ""), paste(val_pN["C_Index"], "(", val_pN["CI_Lower"], ", ", val_pN["CI_Upper"], ")", sep = "")), Validation_AIC = c(val_LNR["AIC"], val_LODDS["AIC"], val_pN["AIC"]), Validation_BIC = c(val_LNR["BIC"], val_LODDS["BIC"], val_pN["BIC"]))
    results_table <- gt(resultados) %>%
    tab_header(title = "Desempenho de previsão dos três sistemas de estadiamento linfonodal") %>%
    cols_label(Variável = "Variável",Training_C_Index = "Índice C (IC 95%) (Treinamento)", Training_AIC = "AIC (Treinamento)", Training_BIC = "BIC (Treinamento)", Validation_C_Index = "Índice C (IC 95%) (Validação)", Validation_AIC = "AIC (Validação)", Validation_BIC = "BIC (Validação)")
    write.csv(resultados, "prediction_performance.csv", row.names = FALSE)
  4. Use o código a seguir para criar um modelo XGBoost e gerar gráficos de barras da importância relativa das variáveis, para comparar a importância dos três sistemas LN. Da mesma forma, gere curvas ROC e curvas de calibração. Os dados são obtidos do banco de dados SEER.
    Biblioteca(xgboost)
    biblioteca (acento circunflexo)
    biblioteca (pROC)
    train_data <- read.csv("train_data.csv")
    test_data <- read.csv("test_data.csv")
    train_matrix <- XGB. DMatrix(dados = as.matrix(train_data[, c('Idade', 'T', 'N', 'M', 'LODDS', 'Quimioterapia')]), rótulo = train_data$status)
    test_matrix <- XGB. DMatrix(dados = as.matrix(test_data[, c('Idade', 'T', 'N', 'M', 'LODDS', 'Quimioterapia')]), rótulo = test_data$status)
    params <- list(booster = "gbtree", objective = "binary:logistic", eval_metric = "auc", eta = 0,1, max_depth = 6, subsample = 0,8, colsample_bytree = 0,8)
    xgb_model <- xgb.train(params = params, dados = train_matrix, nrounds = 100, watchlist= list(train = train_matrix), verbose = 1)
    pred_probs <- prever(xgb_model, newdata = test_matrix)
    pred_labels <- senão(pred_probs > 0,5, 1, 0)
    conf_matrix <- confusionMatrix(as.factor(pred_labels), as.factor(test_data$status))
    roc_curve <- roc(test_data$status, pred_probs)
    auc_value <- AUC(roc_curve)
    ci_auc <- ci.auc(roc_curve)
    sensibilidade <- conf_matrix$byClass["Sensibilidade"]
    especificidade <- conf_matrix$byClass["Especificidade"]
    precisão <- conf_matrix$overall["Precisão"]
    ppv <- conf_matrix$byClass["Valor Pos Pred"]
    npv <- conf_matrix$byClass["Neg Pred Value"]
    result_table <- data.frame(Model = "XGBoost", AUC = sprintf("%.3f (%.3f-%.3f)", auc_value, ci_auc[1], ci_auc[3]), Sensibilidade = sprintf("%.3f", sensibilidade), Especificidade = sprintf("%.3f", especificidade), Precisão = sprintf("%.3f", precisão), PPV = sprintf("%.3f", ppv), NPV = sprintf("%.3f", npv))
    write.csv(result_table, "xgboost_model_performance.csv", row.names = FALSE)
    roc_df <- data.frame(FPR = 1 - roc_curve$especificidades, TPR = roc_curve$sensibilidades)
    roc_plot <- ggplot(roc_df, aes(x = FPR, y = TPR)) +geom_line(color = "steelblue", size = 1.2) + geom_abline(intercept = 0, slope = 1, linetype = "tracejado", color = "gray") + annotate("text", x = 0.9, y = 0.2, label = paste("AUC =", round(auc_value, 3)), size = 5, color = "black") + labs(title = "Curva ROC para o modelo XGBoost", x = "Taxa de falsos positivos", y = "Taxa de verdadeiros positivos") + theme_minimal() + theme(panel.border = element_rect(color = "black", fill = NA, tamanho = 1))
    calibration_data <- data.frame(Status = as.factor(test_data$status), pred_probs = pred_probs)
    calib_model <- calibração(Status ~ pred_probs, dados = calibration_data, classe = "1", cortes = 5)
    ggplot(calib_model$data, aes(x = ponto médio, y = Porcentagem)) + geom_line(cor = "steelblue", tamanho = 1) + geom_point(cor = "vermelho", tamanho = 2) + geom_abline(interceptação = 0, inclinação = 1, tipo de linha = "tracejado", cor = "preto") +labs(title = "Curva de calibração para o modelo XGBoost", x = "Probabilidade prevista", y = "Proporção observada") + theme_minimal() + theme(panel.border = element_rect(cor = "preto", preenchimento = NA, tamanho = 0,5))
  5. Use o código a seguir para construir um modelo de RF e gerar gráficos de barras da importância relativa das variáveis, comparando assim a importância dos três sistemas LN. Da mesma forma, gere curvas ROC e curvas de calibração. Os dados são obtidos do banco de dados SEER.library(randomForest)
    biblioteca (dplyr)
    biblioteca(ggplot2)
    biblioteca (pROC)
    biblioteca (acento circunflexo)
    Biblioteca (RMS)
    Composição <- read.csv("train_data.csv")
    Testado <- read.csv("test_data.csv")
    trainset$status=factor(trainset$status)
    variáveis1 <- c("Idade", "T", "N", "M", "LODDS", "Quimioterapia")
    Trem < - Trem %>%
    mutate(across(all_of(variables1), as.numeric))
    testado$status=fator(testado$status)
    Testado < - Testado %>%
    mutate(across(all_of(variables1), as.numeric))
    RF=randomForest(trainset$status ~ Idade + T + N + M + LODDS + Quimioterapia, data=trainset,ntree=100,importance=TRUE,proximity=TRUE)
    imp=importância(RF)
    varImpPlot(RF)
    impvar=rownames(imp)[order(imp[,4],decrescente = TRUE)]
    importance_df <- as.data.frame(imp)
    importance_df$Variáveis <- rownames(importance_df)
    importance_plot <- ggplot(importance_df, aes(x = reorder(Variables, MeanDecreaseAccuracy), y = MeanDecreaseAccuracy)) +geom_bar(stat = "identity", fill = "steelblue") +coord_flip() + labs(title = "Variable Importance", x = "Variables", y = "Mean Decrease Accuracy") + theme_minimal()
    pred_probs <- predict(RF, conjunto de testes, tipo = "prob")[,2]
    roc_obj <- roc(testset$status, pred_probs)
    auc_value <- AUC(roc_obj)
    roc_plot <- ggplot() +geom_line(aes(x = 1 - roc_obj$especificidades, y = roc_obj$sensibilidades), cor = "steelblue", tamanho = 1,2) +geom_abline(interceptação = 0, inclinação = 1, tipo de linha = "tracejado", cor = "cinza") + anotar("texto", x = 0,8, y = 0,2, rótulo = colar("AUC =", redondo(auc_value, 3)), cor = "preto", tamanho = 5, hjust = 0) + labs(título = "Curva ROC para Modelo de Floresta Aleatória", x = "Taxa de falsos positivos", y = "Taxa de verdadeiros positivos") +theme_minimal() + theme(panel.border = element_rect(color = "black", fill = NA, size = 1))
    calibration_data <- data.frame(pred_probs = pred_probs, status = testado$status)
    calib_model <- calibração(status ~ pred_probs, dados = calibration_data, classe = "1", cortes = 5)
    calib_df <- as.data.frame(calib_model[["data"]])
    calib_df$mid <- calib_df$midpoint
    calib_df $ por cento < - calib_df $ por cento
    calibration_plot <- ggplot(calib_df, aes(x = mid, y = Percent)) + geom_line(color = "steelblue", size = 1.2) + geom_point(color = "steelblue", size = 3) + geom_abline(intercept = 0, slope = 1, linetype = "tracejado", color = "black", size = 0.8) + labs(title = "Curva de calibração para floresta aleatória", x = "Probabilidade prevista", y = "Probabilidade real") + theme_minimal() + theme(panel.border = element_rect(color = "preto", fill = NA, tamanho = 1), plot.title = element_text(hjust = -0,05, vjust = -1,5, face = "negrito", tamanho = 12))
    rf_probs <- predict(RF, newdata=tested, type="prob")[, 2]
    rf_auc <- roc(testado$status, rf_probs)
    auc_value <- AUC(rf_auc)
    ci_auc <- ci.auc(rf_auc)
    rf_predictions <- predict(RF, newdata=testado)
    conf_matrix <- confusionMatrix(rf_predictions, testado$status)
    sensibilidade <- conf_matrix$byClass["Sensibilidade"]
    especificidade <- conf_matrix$byClass["Especificidade"]
    precisão <- conf_matrix$overall["Precisão"]
    ppv <- conf_matrix$byClass["Valor Pos Pred"]
    npv <- conf_matrix$byClass["Neg Pred Value"]
    result_table <- data.frame(Model = "RF", AUC = sprintf("%.3f (%.3f-%.3f)", auc_value, ci_auc[1], ci_auc[3]), Sensibilidade = sprintf("%.3f", sensibilidade), Especificidade = sprintf("%.3f", especificidade), Precisão = sprintf("%.3f", precisão), PPV = sprintf("%.3f", ppv), NPV = sprintf("%.3f", npv))
    write.csv(result_table, "RF_model_performance.csv", row.names = FALSE)
  6. Use o código a seguir para criar um modelo NN e gerar gráficos de barras da importância relativa das variáveis, comparando assim a importância dos três sistemas LN. Da mesma forma, gere curvas ROC e curvas de calibração. Os dados são obtidos do banco de dados SEER.library(nnet)
    biblioteca (acento circunflexo)
    biblioteca (pROC)
    biblioteca(ggplot2)
    train_data <- read.csv("train_data.csv")
    test_data <- read.csv("test_data.csv")
    train_data$status <- as.factor(train_data$status)
    test_data$status <- as.factor(test_data$status)
    características <- c("Idade", "T", "N", "M", "LODDS", "Quimioterapia")
    x_train <- train_data[, recursos]
    y_train <- train_data$status
    x_test <- test_data[, recursos]
    y_test <- test_data$status
    nn_model <- nnet(status ~ Idade + T + N + M + LODDS + Quimioterapia, dados = train_data, tamanho = 5, decaimento = 0,01, maxit = 200)
    pred_probs <- predict(nn_model, newdata = x_test, type = "raw")
    pred_labels <- senão(pred_probs > 0,5, 1, 0)
    roc_curve <- roc(as.numeric(y_test), pred_probs)
    auc_value <- AUC(roc_curve)
    auc_ci <- ci.auc(roc_curve)
    auc_text <- colar0(rodada(auc_value, 3), " (", rodada(auc_ci[1], 3), "-", rodada(auc_ci[3], 3), ")")
    conf_matrix <- confusionMatrix(as.factor(pred_labels), y_test)
    precisão <- conf_matrix$overall["Precisão"]
    sensibilidade <- conf_matrix$byClass["Sensibilidade"]
    especificidade <- conf_matrix$byClass["Especificidade"]
    ppv <- conf_matrix$byClass["Valor Pos Pred"]
    npv <- conf_matrix$byClass["Neg Pred Value"]
    performance_table <- data.frame(Métrica = c("AUC (IC 95%)", "Precisão", "Sensibilidade", "Especificidade", "PPV", "VPN"),Valor = c(auc_text, redondo(precisão, 3), redondo(sensibilidade, 3), redondo(especificidade, 3), redondo(ppv, 3), redondo(npv, 3)))
    write.csv(performance_table, "NN_performance_table.csv", row.names = FALSE)
    roc_curve <- roc(y_test, pred_probs)
    auc_value <- AUC(roc_curve)
    roc_plot <- ggplot() + geom_line(aes(x = 1 - roc_curve$especificidades, y = roc_curve$sensibilidades), cor = "steelblue", tamanho = 1,2) +geom_abline(interceptação = 0, inclinação = 1, tipo de linha = "tracejado", cor = "cinza") + anotação("texto", x = 0,8, y = 0,2, rótulo = colar("AUC =", redondo(auc_value, 3)), cor = "preto", tamanho = 5, hjust = 0) + labs(título = "Curva ROC para Modelo de Rede Neural", x = "Taxa de falsos positivos", y = "Taxa de verdadeiros positivos") + theme_minimal() + theme(panel.border = element_rect(color = "black", fill = NA, size = 1))
    calibration_data <- data.frame(pred_probs = pred_probs, status = as.numeric(y_test) - 1)
    calibration_data$pred_probs <- as.numeric(calibration_data$pred_probs)
    calibration_data$calibration_bin <- cut(calibration_data$pred_probs, breaks = seq(0, 1, by = 0.2), include.lowest = TRUE)
    calibration_summary <- aggregate(status ~ calibration_bin, dados = calibration_data, FUN = média)
    calibration_summary$pred_mean <- aggregate(pred_probs ~ calibration_bin, data = calibration_data, FUN = mean)$pred_probs
    calibration_plot <- ggplot(calibration_summary, aes(x = pred_mean, y = status)) + geom_line(color = "steelblue", size = 1.2) + geom_point(color = "red", size = 3) + geom_abline(intercept = 0, slope = 1, linetype = "tracejado", color = "black", size = 0.8) + labs(title = "Curva de calibração para rede neural", x = "Probabilidade prevista", y = "Probabilidade real") + theme_minimal() + theme(panel.border = element_rect(color = "preto", fill = NA, tamanho = 1))
    nn_var_importance <- varImp(nn_model)
    importance_df <- data.frame(Recurso = rownames(nn_var_importance), Importância = nn_var_importance$Geral )
    importance_plot <- ggplot(importance_df, aes(x = reorder(Feature, Importance), y = Importance)) + geom_bar(stat = "identity", fill = "steelblue") + coord_flip() + labs(title = "Importância Variável para Rede Neural", x = "Features", y = "Importância") + theme_minimal()

3. Desenvolvimento e verificação de modelos de risco concorrentes

  1. Use o código a seguir para executar a análise univariada e plotar a curva da função de incidência cumulativa (CIF). O data.csv são os dados obtidos do banco de dados SEER. O método para salvar imagens subsequentes será o mesmo desta etapa. Substitua Site no código um por um por outros fatores para executar a análise univariada para todos os fatores.
    biblioteca(tidycmprsk)
    Biblioteca(gtResumo)
    biblioteca(ggplot2)
    biblioteca(ggsurvfit)
    Biblioteca (ggprism)
    AA <- read.csv("data.csv")
    cif2 <- tidycmprsk::cuminc(Surv(time, Status1) ~Site, data = aa)
    arrumado(CIF2,vezes = C(12,24,36,48,60))
    tbl_cuminc(cif2, times =c(12,24,36,48,60), outcomes = c("CSS", "OSS"),estimate_fun = NULL, label_header = "**{time/12}-year cuminc**") %>%
    add_p() %>%
    add_n(localização = "nível")
    cuminc_plot <- ggcuminc(cif2, resultado = c("CSS", "OSS"), tamanho = 1,5) + labs(x = "tempo") +add_quantile(y_value = 0,20, tamanho = 1) + scale_x_continuous(breaks = seq(0, 84, by = 12), limites = c(0, 84)) +scale_y_continuous(label = scales::p ercent, breaks = seq(0, 1, by = 0,2), limits = c(0, 1)) + theme_prism() + theme(legend.position = c(0,2, 0.8), panel.grid = element_blank(),panel.grid.major.y = element_line(cor = "grey80")) + tema(legenda.espaçamento.x = unidade(0.1, "cm"), legenda.espaçamento.y = unidade(0.01, "cm")) + tema(axis.ticks.comprimento.x = unidade(-0.2, "cm"), axis.ticks.x = element_line(cor = "preto", tamanho = 1, lineend = 1)) + tema(axis.ticks.comprimento.y = unidade(-0.2, "cm"), axis.ticks.y = element_line(cor = "preto", tamanho = 1, lineend = 1))
  2. Use o código a seguir para executar análise e visualização multivariadas. O data1.csv vem dos resultados do código anterior. Depois de executar o código, clique em Exportar, clique em Salvar como PDF e, finalmente, clique em Salvar para salvar a imagem.
    biblioteca(tidycmprsk)
    Biblioteca(gtResumo)
    AA <-read.csv('data1.csv')
    for (i em nomes(aa)[c(1:16, 19)]){aa[,i] <- as.factor(aa[,i])}
    mul1Tabela2 <- MUL1 %>%
    gtsummary::tbl_regression(exponentiate = TRUE) %>%
    add_n(localização = "nível"); Tabela 2
    table_df <- as_tibble(Tabela 2)
    guia <- tabela2$table_body
    tab1 <- tab[,c(12,19,20,22:29)]
  3. Use o código a seguir para plotar o nomograma, a curva ROC e a curva de calibração. Depois de treinar o modelo usando dados da coorte de treinamento, use os dados de coortes de validação e validação externa para validar o model.library(QHScrnomo). Os dados da coorte externa consistem em amostras de câncer colorretal que não sejam carcinoma de células em anel, que foram selecionadas na etapa 1.4.
    Biblioteca (RMS)
    biblioteca(timeROC)
    biblioteca (sobrevivência)
    AA <-read.csv('data3.csv')
    for (i em nomes(aa)[c(1:16, 19)]){aa[,i] <- as.factor(aa[,i])}
    DD <- distDados(AA)
    opções(distDados(DistDados= "DD")
    mul <- cph(Surv(tempo, Status1 == 1) ~ T + N + M + LODDS + Site, dados = aa, x = VERDADEIRO, y = VERDADEIRO, surv = VERDADEIRO)
    m3 <- crr.fit(mul, failcode = 1, cencode = 0)
    nomo <-Newlabels(fit = m3, labels =c(T="T", N= "N", M = "M", LODDS = "LODDS", Site = "Site"))
    nomoc("N0","N1","N2"),M=c("M0","M1"),LODDS=c
    ("LODDS1","LODDS2","LODDS3"),Site=
    c("RSC","LSC","Reto")))
    nomogram.crr(fit =nomo , lp = F, xfrac = 0.3, fun.at =seq(from=0, to=1, by= 0.1) , failtime =c(12,36,60), funlabel = c("Incidência Cumulativa de CSS de 1 ano","Incidência Cumulativa de CSS de 3 anos","Incidência Cumulativa de CSS de 5 anos"))
    time_points <- c(12, 36, 60)
    pred_risks_list <- lapply(time_points, function(time_point) {predict(m3, newdata = aa, type = "risk", time = time_point)})
    pred_risks_df <- data.frame(do.call(cbind, pred_risks_list))
    colnames(pred_risks_df) <- paste("risk_at", time_points, "meses", sep = "_")
    roc_1year <- timeROC(T = aa$time, delta = ifelse(aa$Status1 == "CSS", 1, 0), marker = pred_risks_df$risk_at_12_months, cause = 1, times = 12, iid = TRUE)
    roc_3year <- timeROC(T = aa$time, delta = ifelse(aa$Status1 == "CSS", 1, 0), marker = pred_risks_df$risk_at_36_months, cause = 1, times = 36, iid = TRUE)
    roc_5year <- timeROC(T = aa$time, delta = ifelse(aa$Status1 == "CSS", 1, 0), marker = pred_risks_df$risk_at_60_months, cause = 1,times = 60, iid = TRUE)
    legend("canto inferior direito",legenda = c("CSS de 1 ano", "CSS de 3 anos", "CSS de 5 anos"), col = c("#BF1D2D", "#262626", "#397FC7"), lwd = 2)
    sas.cmprsk(m3,tempo = 36)
    set.seed(123)
    aa$pro <- tenf.crr(m3,tempo = 36)
    cindex(prob = aa$pro, fstatus = aa$Status1, ftime = aa$time, type = "crr", failcode = 1, cencode = 0, tol = 1e-20)
    groupci(x=aa$pro, ftime = aa$time, fstatus = aa$Status1, failcode = 1, cencode = 0, ci = TRUE, g = 5, m = 1000, u = 36, xlab = "Probabilidade prevista", ylab = "Probabilidade real", lty=1, lwd=2, col="#262626",xlim=c(0,1.0), ylim=c(0,1.0), add =TRUE)

Access restricted. Please log in or start a trial to view this content.

Resultados

Características dos pacientes
Este estudo se concentrou em pacientes diagnosticados com CEC colorretal, usando dados do banco de dados SEER de 2004 a 2015. Os critérios de exclusão incluíram pacientes com tempo de sobrevida inferior a um mês, aqueles com informações clínico-patológicas incompletas e casos em que a causa da morte não era clara ou não especificada. Um total de 2409 pacientes com SRCC colorretal que atenderam aos critérios de inclusão foram ...

Access restricted. Please log in or start a trial to view this content.

Discussão

Câncer colorretal (CRC) O CCR é um subtipo raro e especial de câncer colorretal com prognóstico ruim. Portanto, maior atenção precisa ser dada ao prognóstico dos pacientes com CEC. A previsão precisa da sobrevida para pacientes com SRCC é crucial para determinar seu prognóstico e tomar decisões de tratamento individualizadas. Neste estudo, exploramos a relação entre as características clínicas e o prognóstico em pacientes com SRCC e identificamos o sistema de estadiamento...

Access restricted. Please log in or start a trial to view this content.

Divulgações

Os autores não têm conflitos de interesse financeiros a divulgar.

Agradecimentos

Nenhum

Access restricted. Please log in or start a trial to view this content.

Materiais

NameCompanyCatalog NumberComments
SEER databaseNational Cancer institiute at NIH
X-tile softwareYale school of medicine
R-studioPosit

Referências

  1. Siegel, R. L., Giaquinto, A. N., Jemal, A. Cancer statistics, 2024. CA Cancer J Clin. 74 (1), 12-49 (2024).
  2. Korphaisarn, K., et al. Signet ring cell colorectal cancer: Genomic insights into a rare subpopulation of colorectal adenocarcinoma. Br J Cancer. 121 (6), 505-510 (2019).
  3. Willauer, A. N., et al. Clinical and molecular characterization of early-onset colorectal cancer. Cancer. 125 (12), 2002-2010 (2019).
  4. Watanabe, A., et al. A case of primary colonic signet ring cell carcinoma in a young man which preoperatively mimicked Phlebosclerotic colitis. Acta Med Okayama. 73 (4), 361-365 (2019).
  5. Kim, H., Kim, B. H., Lee, D., Shin, E. Genomic alterations in signet ring and mucinous patterned colorectal carcinoma. Pathol Res Pract. 215 (10), 152566(2019).
  6. Deng, X., et al. Neoadjuvant radiotherapy versus surgery alone for stage II/III mid-low rectal cancer with or without high-risk factors: A prospective multicenter stratified randomized trial. Ann Surg. 272 (6), 1060-1069 (2020).
  7. Buk Cardoso, L., et al. Machine learning for predicting survival of colorectal cancer patients. Sci Rep. 13 (1), 8874(2023).
  8. Monterrubio-Gómez, K., Constantine-Cooke, N., Vallejos, C. A. A review on statistical and machine learning competing risks methods. Biom J. 66 (2), e2300060(2024).
  9. Kim, H. J., Choi, G. S. Clinical implications of lymph node metastasis in colorectal cancer: Current status and future perspectives. Ann Coloproctol. 35 (3), 109-117 (2019).
  10. Xu, T., et al. Log odds of positive lymph nodes is an excellent prognostic factor for patients with rectal cancer after neoadjuvant chemoradiotherapy. Ann Transl Med. 9 (8), 637(2021).
  11. Chen, Y. R., et al. Prognostic performance of different lymph node classification systems in young gastric cancer. J Gastrointest Oncol. 12 (4), 285-1300 (2021).
  12. Bouvier, A. M., et al. How many nodes must be examined to accurately stage gastric carcinomas? Results from a population based study. Cancer. 94 (11), 2862-2866 (2002).
  13. Coburn, N. G., Swallow, C. J., Kiss, A., Law, C. Significant regional variation in adequacy of lymph node assessment and survival in gastric cancer. Cancer. 107 (9), 2143-2151 (2006).
  14. Li Destri, G., Di Carlo, I., Scilletta, R., Scilletta, B., Puleo, S. Colorectal cancer and lymph nodes: the obsession with the number 12. World J Gastroenterol. 20 (8), 1951-1960 (2014).
  15. Dinaux, A. M., et al. Outcomes of persistent lymph node involvement after neoadjuvant therapy for stage III rectal cancer. Surgery. 163 (4), 784-788 (2018).
  16. Sun, Y., Zhang, Y., Huang, Z., Chi, P. Prognostic implication of negative lymph node count in ypN+ rectal cancer after neoadjuvant chemoradiotherapy and construction of a prediction nomogram. J Gastrointest Surg. 23 (5), 1006-1014 (2019).
  17. Xu, Z., Jing, J., Ma, G. Development and validation of prognostic nomogram based on log odds of positive lymph nodes for patients with gastric signet ring cell carcinoma. Chin J Cancer Res. 32 (6), 778-793 (2020).
  18. Scarinci, A., et al. The impact of log odds of positive lymph nodes (LODDS) in colon and rectal cancer patient stratification: a single-center analysis of 323 patients. Updates Surg. 70 (1), 23-31 (2018).
  19. Nitsche, U., et al. Prognosis of mucinous and signet-ring cell colorectal cancer in a population-based cohort. J Cancer Res Clin Oncol. 142 (11), 2357-2366 (2016).
  20. Kang, H., O'Connell, J. B., Maggard, M. A., Sack, J., Ko, C. Y. A 10-year outcomes evaluation of mucinous and signet-ring cell carcinoma of the colon and rectum. Dis Colon Rectum. 48 (6), 1161-1168 (2005).
  21. Sung, C. O., et al. Clinical significance of signet ring cells in colorectal mucinous adenocarcinoma. Mod Pathol. 21 (12), 1533-1541 (2008).
  22. Alvi, M. A., et al. Molecular profiling of signet ring cell colorectal cancer provides a strong rationale for genomic targeted and immune checkpoint inhibitor therapies. Br J Cancer. 117 (2), 203-209 (2017).
  23. Brownlee, S., et al. Evidence for overuse of medical services around the world. Lancet. 390 (10090), 156-168 (2017).

Access restricted. Please log in or start a trial to view this content.

Reimpressões e Permissões

Solicitar permissão para reutilizar o texto ou figuras deste artigo JoVE

Solicitar Permissão

Explore Mais Artigos

MedicinaEdi o 218aprendizado de m quinacarcinoma colorretal de c lulas em anel de sinetelog de chances de linfonodos positivosest gio linfonodal

This article has been published

Video Coming Soon

JoVE Logo

Privacidade

Termos de uso

Políticas

Pesquisa

Educação

SOBRE A JoVE

Copyright © 2025 MyJoVE Corporation. Todos os direitos reservados