Código completo | Aplicação clássica de floresta aleatória em análise de regressão

O histórico da conta oficial registra vários indicadores de leitura de artigos publicados, incluindo: título do conteúdo, número total de leitores, número total de leituras, número total de compartilhadores, número total de compartilhamentos, número de seguidores após leitura, taxa de leitura entregue, número de leituras geradas pelo compartilhamento, taxa de compartilhamento pela primeira vez, número de leituras trazidas por cada compartilhamento e taxa de conclusão de leitura.

Tentamos usar o algoritmo de floresta aleatória no aprendizado de máquina para prever se existem certos indicadores ou combinações de indicadores que podem prever o número de seguidores após a leitura.

Formato de dados e dados lidos

O conjunto de dados inclui 9 indicadores estatísticos para 1.588 artigos.

  • Leia a matriz de estatísticas: WeChatOfficialAccount.txt

  • Número de seguidores após a leitura:

    WeChatOfficialAccountFollowers.txt

feature_file <- "data/WeChatOfficialAccount.txt"
metadata_file <- "data/WeChatOfficialAccountFollowers.txt"

feature_mat <- read.table(feature_file, row.names = 1, header = T, sep="\t", stringsAsFactors =T)

# 处理异常的特征名字
# rownames(feature_mat) <- make.names(rownames(feature_mat))

metadata <- read.table(metadata_file, row.names=1, header=T, sep="\t", stringsAsFactors =T)

dim(feature_mat)
## [1] 1588    9

A representação das estatísticas de leitura é a seguinte:

feature_mat[1:4,1:5]
##   TotalReadingPeople TotalReadingCounts TotalSharingPeople TotalSharingCounts ReadingRate
## 1               8278              11732                937               1069      0.0847
## 2               8951              12043                828                929      0.0979
## 3              18682              22085                781                917      0.0608
## 4               4978               6166                525                628      0.0072

A representação de metadados é a seguinte

head(metadata)
##   FollowersAfterReading
## 1                   227
## 2                   188
## 3                   119
## 4                   116
## 5                   105
## 6                   100

Triagem e sequenciamento de amostras

É também uma operação que precisa garantir que a ordem da amostra na tabela de amostra e a tabela de expressão estejam alinhadas .

feature_mat_sampleL <- rownames(feature_mat)
metadata_sampleL <- rownames(metadata)

common_sampleL <- intersect(feature_mat_sampleL, metadata_sampleL)

# 保证表达表样品与METAdata样品顺序和数目完全一致
feature_mat <- feature_mat[common_sampleL,,drop=F]
metadata <- metadata[common_sampleL,,drop=F]

Seja para julgar classificação ou regressão 

Os parâmetros foram fornecidos durante a leitura dos dados anteriormente stringsAsFactors =T, portanto esta etapa pode ser ignorada.

  • Se a coluna correspondente ao grupo for um número, converta-a para um tipo numérico - faça regressão

  • Se a coluna correspondente ao grupo estiver agrupada, converta para tipo de fator - faça classificação

# R4.0之后默认读入的不是factor,需要做一个转换
# devtools::install_github("Tong-Chen/ImageGP")
library(ImageGP)

# 此处的FollowersAfterReading根据需要修改
group = "FollowersAfterReading"

# 如果group对应的列为数字,转换为数值型 - 做回归
# 如果group对应的列为分组,转换为因子型 - 做分类
if(numCheck(metadata[[group]])){
    if (!is.numeric(metadata[[group]])) {
      metadata[[group]] <- mixedToFloat(metadata[[group]])
    }
} else{
  metadata[[group]] <- as.factor(metadata[[group]])
}

Análise Preliminar de Floresta Aleatória 

library(randomForest)

# 查看参数是个好习惯
# 有了前面的基础概述,再看每个参数的含义就明确了很多
# 也知道该怎么调了
# 每个人要解决的问题不同,通常不是别人用什么参数,自己就跟着用什么参数
# 尤其是到下游分析时
# ?randomForest

# 查看源码
# randomForest:::randomForest.default

Após carregar o pacote, analise-o diretamente e ajuste os parâmetros após ver o resultado.

# 设置随机数种子,具体含义见 https://mp.weixin.qq.com/s/6plxo-E8qCdlzCgN8E90zg
set.seed(304)

# 直接使用默认参数
rf <- randomForest(feature_mat, metadata[[group]])

Olhando para os resultados preliminares, o tipo de floresta aleatória é julgado à medida que uma árvore 分类é construída, e a decisão ótima é tomada 500a partir de indicadores selecionados aleatoriamente 3cada vez que uma decisão é tomada ( mtry), o resíduo quadrado médio Mean of squared residuals: 39,82736, e o grau de variação explicado % Var explained: 74,91. O resultado parece normal.

rf
## 
## Call:
##  randomForest(x = feature_mat, y = metadata[[group]]) 
##                Type of random forest: regression
##                      Number of trees: 500
## No. of variables tried at each split: 3
## 
##           Mean of squared residuals: 39.82736
##                     % Var explained: 74.91

Observando o efeito de predição do modelo no conjunto de treinamento, parece que a consistência não é ruim.

library(ggplot2)

followerDF <- data.frame(Real_Follower=metadata[[group]], Predicted_Follower=predict(rf, newdata=feature_mat))

sp_scatterplot(followerDF, xvariable = "Real_Follower", yvariable = "Predicted_Follower",
               smooth_method = "auto") + coord_fixed(1)

26eb69b78b8b5e6cb4072025633a1f61.png

Procedimento Operacional Padrão Florestal Aleatório

Dividir conjuntos de treinamento e teste

library(caret)
seed <- 1
set.seed(seed)
train_index <- createDataPartition(metadata[[group]], p=0.75, list=F)
train_data <- feature_mat[train_index,]
train_data_group <- metadata[[group]][train_index]

test_data <- feature_mat[-train_index,]
test_data_group <- metadata[[group]][-train_index]
dim(train_data)
## [1] 1192    9
dim(test_data)
## [1] 396   9

Seleção de recursos Boruta para identificar as principais variáveis ​​​​categóricas

# install.packages("Boruta")
library(Boruta)
set.seed(1)

boruta <- Boruta(x=train_data, y=train_data_group, pValue=0.01, mcAdj=T, 
       maxRuns=300)

boruta
## Boruta performed 14 iterations in 5.917085 secs.
##  8 attributes confirmed important: AverageReadingCountsForEachSharing, FirstSharingRate,
## ReadingRate, TotalReadingCounts, TotalReadingCountsOfSharing and 3 more;
##  1 attributes confirmed unimportant: ReadingFinishRate;

Observe os resultados da identificação de importância da variável (na verdade, isso também foi refletido na saída acima), 8uma variável importante, 0uma variável possivelmente importante ( tentative variable, a pontuação de importância não tem diferença estatística da melhor pontuação da variável sombra), 1um é não são variáveis ​​importantes.

table(boruta$finalDecision)
## 
## Tentative Confirmed  Rejected 
##         0         8         1

Trace a importância das variáveis ​​identificadas. Se houver poucas variáveis, você pode usar o desenho padrão. Quando há muitas variáveis, a imagem desenhada não pode ser vista com clareza e você precisa organizar os dados e desenhar sozinho.

Defina uma função para extrair o valor de importância correspondente a cada variável.

library(dplyr)
boruta.imp <- function(x){
  imp <- reshape2::melt(x$ImpHistory, na.rm=T)[,-1]
  colnames(imp) <- c("Variable","Importance")
  imp <- imp[is.finite(imp$Importance),]

  variableGrp <- data.frame(Variable=names(x$finalDecision), 
                            finalDecision=x$finalDecision)

  showGrp <- data.frame(Variable=c("shadowMax", "shadowMean", "shadowMin"),
                        finalDecision=c("shadowMax", "shadowMean", "shadowMin"))

  variableGrp <- rbind(variableGrp, showGrp)

  boruta.variable.imp <- merge(imp, variableGrp, all.x=T)

  sortedVariable <- boruta.variable.imp %>% group_by(Variable) %>% 
    summarise(median=median(Importance)) %>% arrange(median)
  sortedVariable <- as.vector(sortedVariable$Variable)


  boruta.variable.imp$Variable <- factor(boruta.variable.imp$Variable, levels=sortedVariable)

  invisible(boruta.variable.imp)
}
boruta.variable.imp <- boruta.imp(boruta)

head(boruta.variable.imp)
##                             Variable Importance finalDecision
## 1 AverageReadingCountsForEachSharing   4.861474     Confirmed
## 2 AverageReadingCountsForEachSharing   4.648540     Confirmed
## 3 AverageReadingCountsForEachSharing   6.098471     Confirmed
## 4 AverageReadingCountsForEachSharing   4.701201     Confirmed
## 5 AverageReadingCountsForEachSharing   3.852440     Confirmed
## 6 AverageReadingCountsForEachSharing   3.992969     Confirmed

Somente Confirmedas variáveis ​​são plotadas. Pode-se observar na figura que as principais 4variáveis ​​​​no ranking de importância estão todas relacionadas ao “compartilhamento” (o número de leituras geradas pelo compartilhamento, o número total de compartilhadores, o número total de compartilhamentos, a primeira taxa de compartilhamento), e o compartilhamento de artigos é muito importante para aumentar a atenção.

library(ImageGP)

sp_boxplot(boruta.variable.imp, melted=T, xvariable = "Variable", yvariable = "Importance",
           legend_variable = "finalDecision", legend_variable_order = c("shadowMax", "shadowMean", "shadowMin", "Confirmed"),
           xtics_angle = 90, coordinate_flip =T)

b26e6fe743309e905fcd50ec5938a7c6.png

Extraia variáveis ​​importantes e variáveis ​​potencialmente importantes

boruta.finalVarsWithTentative <- data.frame(Item=getSelectedAttributes(boruta, withTentative = T), Type="Boruta_with_tentative")
data <- cbind(feature_mat, metadata)

variableFactor <- rev(levels(boruta.variable.imp$Variable))

sp_scatterplot(data, xvariable = group, yvariable = variableFactor[1], smooth_method = "auto")

7da578582522c491ef487e4f4cb4cd60.png

Como não há muitas variáveis, você também pode usá-lo ggpairspara ver como todas as variáveis ​​estão relacionadas entre si e como estão relacionadas com a variável de resposta.

library(GGally)

ggpairs(data, progress = F)

f16775ea61a09e8d0f9b7e17ef0416b1.png

Validação cruzada para escolher parâmetros e ajustar o modelo

Defina uma função para gerar algumas colunas para teste mtry(uma série de valores não maior que o número total de variáveis).

generateTestVariableSet <- function(num_toal_variable){
  max_power <- ceiling(log10(num_toal_variable))
  tmp_subset <- c(unlist(sapply(1:max_power, function(x) (1:10)^x, simplify = F)), ceiling(max_power/3))
  #return(tmp_subset)
  base::unique(sort(tmp_subset[tmp_subset<num_toal_variable]))
}
# generateTestVariableSet(78)

Selecione dados relacionados às principais variáveis ​​características

# 提取训练集的特征变量子集
boruta_train_data <- train_data[, boruta.finalVarsWithTentative$Item]
boruta_mtry <- generateTestVariableSet(ncol(boruta_train_data))

Ajustando e modelando com Caret

library(caret)

if(file.exists('rda/wechatRegression.rda')){
  borutaConfirmed_rf_default <- readRDS("rda/wechatRegression.rda")
} else {

# Create model with default parameters
trControl <- trainControl(method="repeatedcv", number=10, repeats=5)

seed <- 1
set.seed(seed)
# 根据经验或感觉设置一些待查询的参数和参数值
tuneGrid <- expand.grid(mtry=boruta_mtry)

borutaConfirmed_rf_default <- train(x=boruta_train_data, y=train_data_group, method="rf", 
                                    tuneGrid = tuneGrid, # 
                                    metric="RMSE", #metric='Kappa'
                                    trControl=trControl)
saveRDS(borutaConfirmed_rf_default, "rda/wechatRegression.rda")
}

borutaConfirmed_rf_default
## Random Forest 
## 
## 1192 samples
##    8 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 5 times) 
## Summary of sample sizes: 1073, 1073, 1073, 1072, 1073, 1073, ... 
## Resampling results across tuning parameters:
## 
##   mtry  RMSE      Rsquared   MAE     
##   1     6.441881  0.7020911  2.704873
##   2     6.422848  0.7050505  2.720557
##   3     6.418449  0.7052825  2.736505
##   4     6.431665  0.7039496  2.742612
##   5     6.453067  0.7013595  2.754239
##   6     6.470716  0.6998307  2.758901
##   7     6.445304  0.7020575  2.756523
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was mtry = 3.

Plotando precisão vs. hiperparâmetros

plot(borutaConfirmed_rf_default)

032a4c0dfe4de896363f7faf7196174e.png

Plote as 20 variáveis ​​com maior contribuição (a importância das variáveis ​​avaliadas por Boruta é um pouco diferente da importância avaliada pelo próprio modelo)

dotPlot(varImp(borutaConfirmed_rf_default))

299966cdea1ee172501a66456a07a372.png

Extraia o modelo final selecionado e avalie seu desempenho.

borutaConfirmed_rf_default_finalmodel <- borutaConfirmed_rf_default$finalModel

Primeiro, use o conjunto de dados de treinamento para avaliar o efeito de treinamento do modelo construído, RMSE=3.1, Rsquared=0.944, o que é bastante bom.

# 获得模型结果评估参数
predictions_train <- predict(borutaConfirmed_rf_default_finalmodel, newdata=train_data)
postResample(pred = predictions_train, obs = train_data_group)
##      RMSE  Rsquared       MAE 
## 3.1028533 0.9440182 1.1891391

Use os dados de teste para avaliar o efeito preditivo do modelo, RMSE=6.2, Rsquared=0.825, ok. Acompanhe outros métodos para ver se pode ser melhorado.

predictions_train <- predict(borutaConfirmed_rf_default_finalmodel, newdata=test_data)
postResample(pred = predictions_train, obs = test_data_group)
##      RMSE  Rsquared       MAE 
## 6.2219834 0.8251457 2.7212806
library(ggplot2)

testfollowerDF <- data.frame(Real_Follower=test_data_group, Predicted_Follower=predictions_train)

sp_scatterplot(testfollowerDF, xvariable = "Real_Follower", yvariable = "Predicted_Follower",
               smooth_method = "auto") + coord_fixed(1)

31c6f84e1f8ac81982f1ddac5731e53c.png

Desvantagens da regressão florestal aleatória

Os valores previstos pelo modelo de regressão florestal aleatória não excederão a faixa de valores da variável resposta no conjunto de treinamento e não poderão ser usados ​​para extrapolação.

Florestas Aleatórias Aprimoradas por Regressão (RERFs) podem ser usadas como uma solução.

Referências

  1. https://medium.com/swlh/random-forest-and-its-implementation-71824ced454f

  2. https://neptune.ai/blog/random-forest-regression-when-does-it-fail-and-why

  3. https://levelup.gitconnected.com/random-forest-regression-209c0f354c84

  4. https://rpubs.com/Isaac/caret_reg

Série de tutoriais de aprendizado de máquina

Começando com florestas aleatórias, entenda os conceitos e práticas de árvores de decisão, florestas aleatórias, ROC/AUC, conjuntos de dados e validação cruzada passo a passo.

Use texto para palavras que possam ser explicadas claramente, use imagens para exibição, fórmulas para descrições pouco claras e escreva um código simples para fórmulas pouco claras para esclarecer cada link e conceito passo a passo.

Em seguida, amadureça a aplicação de código, ajuste de modelo, comparação de modelo, avaliação de modelo e aprenda o conhecimento e as habilidades necessárias para todo o aprendizado de máquina.

Produtos anteriores (clique na imagem para ir diretamente ao texto do tutorial correspondente)

5b60bd03881933573b8d5f8fde64196b.jpeg

ce0cc939102f1377512a571ebad7f97a.jpeg

8678ac111485d7720aaa29cb26b2bea5.jpeg

33e5e9678405cf6296c68152a8ac37ca.jpeg

e9d143c84dc12c5abdf0ac98580d884a.jpeg

ca4453f46f76491fd2d2a5389abeb6c2.jpeg

df9b57a46102033f8a507a0be7934fb1.jpeg

94a006cb7e9391277aa45687f457568f.jpeg

12c4c6dfe2cb4e43ccd7f4459a2181b8.jpeg

3f3fec5828244bbe7df6460c0237b72b.jpeg

b3075b86695dcde5b0e5ecefbdff620d.jpeg

9205c2f89827ced95cf5b5ce343994f5.jpeg

ce80d62e45baec9cc478b3c8eba83fef.png

22807f6f6421c6dd5c8f7ec1847ca6db.png

b1f595dd47bd16e9634203d775dacd82.png

231a8408df64dccf3058f9fde720a578.png

f08a59c6926c982f4c17ec95d7edb7a0.jpeg

805c7165723824d15dea70b19a8dc381.jpeg

789d3d368809445f4837de4f2c9bf327.jpeg

c602430b3d129a0a473712d424e5f2ff.jpeg

790ccb6946a9584695524ff8a0fdece2.png

6bdfae34c1e8af780957e5ac0e17799c.png

e4fc02e75792a4a2774bd663719aa557.jpeg

091e3a9e5fafc6cb32d6001b459e5bfa.png

8c72f04b49dbdf36e02825853d0b633f.png

5ca9e3b8e6f2fb7fcb074fc8ed0d65b0.jpeg

34fd3856584d8d3b988c08db4e86aa8f.png

d840b0a420e30344b55c3baa416123ec.png

aprendizado de máquina

Responda em segundo plano com "A primeira onda de benefícios na coleção Life Letter" ou clique para ler o texto original para obter uma coleção de tutoriais

65ebb5633638849664f6ad19b8b25968.jpeg

0b89d690585b208f5b647471b2596795.jpeg

42a0148a8b68fed02de8d99281e2ba30.png

Acho que você gosta

Origin blog.csdn.net/qazplm12_3/article/details/132680446
Recomendado
Clasificación