Spaces:
Runtime error
Runtime error
File size: 5,114 Bytes
5e8ceb0 2029588 232e378 5e8ceb0 749e7d3 5e8ceb0 232e378 5e8ceb0 232e378 5e8ceb0 232e378 5e8ceb0 232e378 5e8ceb0 1ffd2e5 5e8ceb0 232e378 5e8ceb0 |
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 |
# Load required libraries
library(caret)
library(dplyr)
library(shiny)
library(jsonlite) # For JSON conversion
# Use the system's Python executable or configure Python path
python_path <- "python3"
model= readRDS("model.rds")
# Sample data table to display
difficulty_table <- data.frame(
Grade = c("Grade 3", "Grade 4", "Grade 5", "Grade 6", "Grade 7", "Grade 8"),
`Mean Grade-Level Difficulty` = c(0.3, 0.431, 0.533, 0.611, 0.656, 0.7)
)
# Define UI for the Shiny application
ui <- fluidPage(
titlePanel("Reading comprehension difficulty prediction using BERT embeddings"),
fluidRow(
column(
width = 12,
h4("How does this work?"),
p("This app predicts average difficulty for an item. Difficulty can be interpreted using the table below. As the table shows, difficulty increases with grade level.
For example, an item of difficulty 0.3 is of average difficulty for Grade 3, an item of difficulty 0.4 is of average difficulty for Grade 4, and so on. Note that as difficulty increases, probability of correct answer reduces."),
# Display the table as a rendered output
h5(""),
tableOutput("difficultyTable"),
# Add external link for NWEA norms
p("Difficulty outputs are on a linear scale. The scale is defined to have mean difficulty of 0.3 at Grade 3 and mean difficulty 0.7 at Grade 8. This scale is based on grade level growth norms reported by ",
a("NWEA MAP Spring 2020 Reading Student Achievement Norms",
href = "https://www.nwea.org/uploads/MAP-Growth-Normative-Data-Overview.pdf", target = "_blank"))
)
),
# App UI elements
sidebarLayout(
sidebarPanel(
width = 12,
textInput("passage", "Passage", placeholder = "Enter passage text here"),
textInput("question", "Question Text", placeholder = "Enter question text here"),
textInput("correctAnswer", "Correct Answer", placeholder = "Enter the correct answer here"),
# Numeric input to ask how many incorrect options (distractors)
numericInput("numDistractors", "Number of Incorrect Options:", value = 1, min = 1, max = 10),
# Dynamic UI for the distractors
uiOutput("distractorsInputs"),
actionButton("printBtn", "Estimate difficulty")
),
mainPanel(
h3("Estimated difficulty"),
verbatimTextOutput("inputsOutput")
)
)
)
# Function to call Python script and get combined input
call_python_script <- function(passage, question, distractors) {
# Prepare input data as JSON
input_data <- toJSON(list(
Passage = passage,
QuestionText = question,
Distractors = distractors
), auto_unbox = TRUE)
# Call the Python script and capture the output
result <- system2(
command = python_path, # Python executable
args = c("bertembedtoy.py"), # Python script name
input = input_data, # Pass input data as JSON
stdout = TRUE # Capture script output
)
# Return the result from Python
return(result)
}
# Read the CSV data into a dataframe
#embedding_df <- read.csv(text =result)
# Define server logic
server <- function(input, output, session) {
# Reactive value to store predictions
predictions <- reactiveVal(NULL)
#df <- reactiveVal(data.frame())
# Render the difficulty table in the UI
output$difficultyTable <- renderTable({
difficulty_table
}, rownames = FALSE) # Avoid showing rownames in the table
# Dynamically generate text inputs for distractors based on user input
output$distractorsInputs <- renderUI({
n <- input$numDistractors # Get the number of distractors
if (is.null(n) || n <= 0) return(NULL) # No inputs if value is invalid
# Generate textInput fields dynamically
lapply(1:n, function(i) {
textInput(inputId = paste0("distractor", i),
label = paste("Wrong answer", i),
placeholder = paste("Enter wrong answer", i))
})
})
# Event triggered when the button is clicked
observeEvent(input$printBtn, {
distractors <- c(sapply(1:input$numDistractors, function(i) {input[[paste0("distractor", i)]]}))
# Combine the distractors into a single string
for (i in 1:length(distractors)) {
distractors[i]= paste0("wrong answer ",i,":", distractors[i])
}
distractors <- c(paste0("Correct answer:",input$correctAnswer), distractors)
distractors=paste(distractors, collapse = " \n")
print(distractors)
# Call the Python script and capture the dataframe
python_output <- call_python_script(input$passage,
input$question,
distractors)
result_vector <- as.numeric(unlist(strsplit(python_output, ",")))
result_vector= as.data.frame(t(result_vector) )
names(result_vector) = paste0("embed.bert", 1:768)
model_predictions= predict(model, result_vector)
predictions(model_predictions)
})
# Output predictions to the UI (or use it elsewhere)
output$inputsOutput <- renderPrint({
predictions()
})
}
# Run the Shiny App
shinyApp(ui = ui, server = server)
|