mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-59057 analytics: static models changes
Part of MDL-57791 epic.
This commit is contained in:
parent
a40952d384
commit
357507b4e6
@ -137,6 +137,17 @@ class course_dropout extends \core_analytics\local\target\binary {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_valid_sample
|
||||||
|
*
|
||||||
|
* @param int $sampleid
|
||||||
|
* @param \core_analytics\analysable $course
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is_valid_sample($sampleid, \core_analytics\analysable $course) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate_sample
|
* calculate_sample
|
||||||
*
|
*
|
||||||
@ -148,11 +159,9 @@ class course_dropout extends \core_analytics\local\target\binary {
|
|||||||
* @param \core_analytics\analysable $course
|
* @param \core_analytics\analysable $course
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function calculate_sample($sampleid, \core_analytics\analysable $course) {
|
protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) {
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
// TODO Even if targets are aware of the data the analyser returns, we can probably still feed samples
|
|
||||||
// data with cached data.
|
|
||||||
$sql = "SELECT ue.* FROM {user_enrolments} ue JOIN {user} u ON u.id = ue.userid WHERE ue.id = :ueid";
|
$sql = "SELECT ue.* FROM {user_enrolments} ue JOIN {user} u ON u.id = ue.userid WHERE ue.id = :ueid";
|
||||||
$userenrol = $DB->get_record_sql($sql, array('ueid' => $sampleid));
|
$userenrol = $DB->get_record_sql($sql, array('ueid' => $sampleid));
|
||||||
|
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No teaching target.
|
||||||
|
*
|
||||||
|
* @package tool_models
|
||||||
|
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace tool_models\analytics\target;
|
||||||
|
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No teaching target.
|
||||||
|
*
|
||||||
|
* @package tool_models
|
||||||
|
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
class no_teaching_activity extends \core_analytics\local\target\binary {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Machine learning backends are not required to predict.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function based_on_assumptions() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_name() {
|
||||||
|
return get_string('target:noteachingactivity', 'tool_models');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prediction_actions(\core_analytics\prediction $prediction) {
|
||||||
|
global $USER;
|
||||||
|
|
||||||
|
// No need to call the parent as the only default action is view details and this target only have 1 feature.
|
||||||
|
$actions = array();
|
||||||
|
|
||||||
|
$sampledata = $prediction->get_sample_data();
|
||||||
|
$course = $sampledata['course'];
|
||||||
|
|
||||||
|
if (has_capability('moodle/course:enrolreview', $sampledata['context'])) {
|
||||||
|
$url = new \moodle_url('/enrol/users.php', array('id' => $course->id));
|
||||||
|
$pix = new \pix_icon('i/enrolusers', get_string('enrolledusers', 'enrol'));
|
||||||
|
$actions['enrolusers'] = new \core_analytics\prediction_action('enrolusers', $prediction,
|
||||||
|
$url, $pix, get_string('enrolledusers', 'enrol'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_capability('moodle/course:viewparticipants', $sampledata['context'])) {
|
||||||
|
$url = new \moodle_url('/user/index.php', array('id' => $course->id));
|
||||||
|
$pix = new \pix_icon('i/cohort', get_string('participants'));
|
||||||
|
$actions['viewparticipants'] = new \core_analytics\prediction_action('viewparticipants', $prediction,
|
||||||
|
$url, $pix, get_string('participants'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function classes_description() {
|
||||||
|
return array(
|
||||||
|
get_string('labelteachingactivityyes', 'tool_models'),
|
||||||
|
get_string('labelteachingactivityno', 'tool_models'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the predicted classes that will be ignored.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function ignored_predicted_classes() {
|
||||||
|
// No need to list the course if there is teaching activity.
|
||||||
|
return array(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_analyser_class() {
|
||||||
|
return '\\core_analytics\\local\\analyser\\courses';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_valid_analysable(\core_analytics\analysable $site, $fortraining = true) {
|
||||||
|
// The analysable is the site, so yes, it is always valid.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_valid_sample($sampleid, \core_analytics\analysable $site) {
|
||||||
|
|
||||||
|
$course = $this->retrieve('course', $sampleid);
|
||||||
|
if (!$course->startdate || $course->startdate - WEEKSECS > time()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate_sample
|
||||||
|
*
|
||||||
|
* @param int $sampleid
|
||||||
|
* @param \core_analytics\analysable $site
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function calculate_sample($sampleid, \core_analytics\analysable $site, $starttime = false, $endtime = false) {
|
||||||
|
|
||||||
|
$noteachersindicator = $this->retrieve('\core_course\analytics\indicator\no_teacher', $sampleid);
|
||||||
|
if ($noteachersindicator != \core_course\analytics\indicator\no_teacher::get_min_value()) {
|
||||||
|
// No teachers flagged as 1.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -80,17 +80,19 @@ class models_list implements \renderable, \templatable {
|
|||||||
|
|
||||||
// Actions.
|
// Actions.
|
||||||
$actionsmenu = new \action_menu();
|
$actionsmenu = new \action_menu();
|
||||||
$actionsmenu->set_menu_trigger(get_string('edit'));
|
$actionsmenu->set_menu_trigger(get_string('actions'));
|
||||||
$actionsmenu->set_owner_selector('model-actions-' . $model->get_id());
|
$actionsmenu->set_owner_selector('model-actions-' . $model->get_id());
|
||||||
$actionsmenu->set_alignment(\action_menu::TL, \action_menu::BL);
|
$actionsmenu->set_alignment(\action_menu::TL, \action_menu::BL);
|
||||||
|
|
||||||
// Edit model.
|
// Edit model.
|
||||||
$url = new \moodle_url('model.php', array('action' => 'edit', 'id' => $model->get_id()));
|
if (!$model->is_static()) {
|
||||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit'));
|
$url = new \moodle_url('model.php', array('action' => 'edit', 'id' => $model->get_id()));
|
||||||
$actionsmenu->add($icon);
|
$icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit'));
|
||||||
|
$actionsmenu->add($icon);
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluate model.
|
// Evaluate machine-learning-based models.
|
||||||
if ($model->get_indicators()) {
|
if ($model->get_indicators() && !$model->is_static()) {
|
||||||
$url = new \moodle_url('model.php', array('action' => 'evaluate', 'id' => $model->get_id()));
|
$url = new \moodle_url('model.php', array('action' => 'evaluate', 'id' => $model->get_id()));
|
||||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_models')),
|
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_models')),
|
||||||
get_string('evaluate', 'tool_models'));
|
get_string('evaluate', 'tool_models'));
|
||||||
@ -98,16 +100,19 @@ class models_list implements \renderable, \templatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($modeldata->enabled && !empty($modeldata->timesplitting)) {
|
if ($modeldata->enabled && !empty($modeldata->timesplitting)) {
|
||||||
$url = new \moodle_url('model.php', array('action' => 'execute', 'id' => $model->get_id()));
|
$url = new \moodle_url('model.php', array('action' => 'getpredictions', 'id' => $model->get_id()));
|
||||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/notifications',
|
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/notifications',
|
||||||
get_string('executemodel', 'tool_models')), get_string('executemodel', 'tool_models'));
|
get_string('getpredictions', 'tool_models')), get_string('getpredictions', 'tool_models'));
|
||||||
$actionsmenu->add($icon);
|
$actionsmenu->add($icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = new \moodle_url('model.php', array('action' => 'log', 'id' => $model->get_id()));
|
// Machine-learning-based models evaluation log.
|
||||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_models')),
|
if (!$model->is_static()) {
|
||||||
get_string('viewlog', 'tool_models'));
|
$url = new \moodle_url('model.php', array('action' => 'log', 'id' => $model->get_id()));
|
||||||
$actionsmenu->add($icon);
|
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_models')),
|
||||||
|
get_string('viewlog', 'tool_models'));
|
||||||
|
$actionsmenu->add($icon);
|
||||||
|
}
|
||||||
|
|
||||||
$modeldata->actions = $actionsmenu->export_for_template($output);
|
$modeldata->actions = $actionsmenu->export_for_template($output);
|
||||||
|
|
||||||
|
@ -70,10 +70,10 @@ class renderer extends plugin_renderer_base {
|
|||||||
* Web interface evaluate results.
|
* Web interface evaluate results.
|
||||||
*
|
*
|
||||||
* @param \stdClass[] $results
|
* @param \stdClass[] $results
|
||||||
* @param string[] $executionlog
|
* @param string[] $logs
|
||||||
* @return string HTML
|
* @return string HTML
|
||||||
*/
|
*/
|
||||||
public function render_evaluate_results($results, $executionlog = array()) {
|
public function render_evaluate_results($results, $logs = array()) {
|
||||||
global $OUTPUT;
|
global $OUTPUT;
|
||||||
|
|
||||||
$output = '';
|
$output = '';
|
||||||
@ -90,9 +90,9 @@ class renderer extends plugin_renderer_base {
|
|||||||
$langstrdata = (object)array('name' => $timesplitting->get_name(), 'id' => $timesplittingid);
|
$langstrdata = (object)array('name' => $timesplitting->get_name(), 'id' => $timesplittingid);
|
||||||
|
|
||||||
if (CLI_SCRIPT) {
|
if (CLI_SCRIPT) {
|
||||||
$output .= $OUTPUT->heading(get_string('executionresultscli', 'tool_models', $langstrdata), 3);
|
$output .= $OUTPUT->heading(get_string('getpredictionsresultscli', 'tool_models', $langstrdata), 3);
|
||||||
} else {
|
} else {
|
||||||
$output .= $OUTPUT->heading(get_string('executionresults', 'tool_models', $langstrdata), 3);
|
$output .= $OUTPUT->heading(get_string('getpredictionsresults', 'tool_models', $langstrdata), 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +120,10 @@ class renderer extends plugin_renderer_base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info logged during execution.
|
// Info logged during evaluation.
|
||||||
if (!empty($executionlog) && debugging()) {
|
if (!empty($logs) && debugging()) {
|
||||||
$output .= $OUTPUT->heading(get_string('extrainfo', 'tool_models'), 3);
|
$output .= $OUTPUT->heading(get_string('extrainfo', 'tool_models'), 3);
|
||||||
foreach ($executionlog as $log) {
|
foreach ($logs as $log) {
|
||||||
$output .= $OUTPUT->notification($log, \core\output\notification::NOTIFY_WARNING);
|
$output .= $OUTPUT->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class renderer extends plugin_renderer_base {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Web interface execution results.
|
* Web interface training & prediction results.
|
||||||
*
|
*
|
||||||
* @param array $trainresults
|
* @param array $trainresults
|
||||||
* @param string[] $trainlogs
|
* @param string[] $trainlogs
|
||||||
@ -145,7 +145,7 @@ class renderer extends plugin_renderer_base {
|
|||||||
* @param string[] $predictlogs
|
* @param string[] $predictlogs
|
||||||
* @return string HTML
|
* @return string HTML
|
||||||
*/
|
*/
|
||||||
public function render_execute_results($trainresults = false, $trainlogs = array(), $predictresults = false, $predictlogs = array()) {
|
public function render_getpredictions_results($trainresults = false, $trainlogs = array(), $predictresults = false, $predictlogs = array()) {
|
||||||
global $OUTPUT;
|
global $OUTPUT;
|
||||||
|
|
||||||
$output = '';
|
$output = '';
|
||||||
@ -159,7 +159,7 @@ class renderer extends plugin_renderer_base {
|
|||||||
$output .= $OUTPUT->notification(get_string('trainingprocessfinished', 'tool_models'),
|
$output .= $OUTPUT->notification(get_string('trainingprocessfinished', 'tool_models'),
|
||||||
\core\output\notification::NOTIFY_SUCCESS);
|
\core\output\notification::NOTIFY_SUCCESS);
|
||||||
} else if ($trainresults->status === \core_analytics\model::NO_DATASET) {
|
} else if ($trainresults->status === \core_analytics\model::NO_DATASET) {
|
||||||
$output .= $OUTPUT->notification(get_string('nodatatotrain', 'analytics'),
|
$output .= $OUTPUT->notification(get_string('nodatatotrain', 'tool_models'),
|
||||||
\core\output\notification::NOTIFY_WARNING);
|
\core\output\notification::NOTIFY_WARNING);
|
||||||
} else {
|
} else {
|
||||||
$output .= $OUTPUT->notification(get_string('generalerror', 'analytics', $result->status),
|
$output .= $OUTPUT->notification(get_string('generalerror', 'analytics', $result->status),
|
||||||
@ -175,7 +175,7 @@ class renderer extends plugin_renderer_base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($predictresults || (!empty($predictlogs) && debugging())) {
|
if ($predictresults || (!empty($predictlogs) && debugging())) {
|
||||||
$output .= $OUTPUT->heading(get_string('predictionresults', 'tool_models'), 3);
|
$output .= $OUTPUT->heading(get_string('predictionresults', 'tool_models'), 3, 'main m-t-3');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($predictresults) {
|
if ($predictresults) {
|
||||||
@ -183,7 +183,7 @@ class renderer extends plugin_renderer_base {
|
|||||||
$output .= $OUTPUT->notification(get_string('predictionprocessfinished', 'tool_models'),
|
$output .= $OUTPUT->notification(get_string('predictionprocessfinished', 'tool_models'),
|
||||||
\core\output\notification::NOTIFY_SUCCESS);
|
\core\output\notification::NOTIFY_SUCCESS);
|
||||||
} else if ($predictresults->status === \core_analytics\model::NO_DATASET) {
|
} else if ($predictresults->status === \core_analytics\model::NO_DATASET) {
|
||||||
$output .= $OUTPUT->notification(get_string('nodatatopredict', 'analytics'),
|
$output .= $OUTPUT->notification(get_string('nodatatopredict', 'tool_models'),
|
||||||
\core\output\notification::NOTIFY_WARNING);
|
\core\output\notification::NOTIFY_WARNING);
|
||||||
} else {
|
} else {
|
||||||
$output .= $OUTPUT->notification(get_string('generalerror', 'analytics', $result->status),
|
$output .= $OUTPUT->notification(get_string('generalerror', 'analytics', $result->status),
|
||||||
|
@ -54,7 +54,7 @@ class predict_models extends \core\task\scheduled_task {
|
|||||||
if ($result) {
|
if ($result) {
|
||||||
echo $OUTPUT->heading(get_string('modelresults', 'tool_models', $model->get_target()->get_name()));
|
echo $OUTPUT->heading(get_string('modelresults', 'tool_models', $model->get_target()->get_name()));
|
||||||
$renderer = $PAGE->get_renderer('tool_models');
|
$renderer = $PAGE->get_renderer('tool_models');
|
||||||
echo $renderer->render_execute_results(false, array(), $result, $model->get_analyser()->get_logs());
|
echo $renderer->render_getpredictions_results(false, array(), $result, $model->get_analyser()->get_logs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,17 @@ class train_models extends \core\task\scheduled_task {
|
|||||||
foreach ($models as $modelobj) {
|
foreach ($models as $modelobj) {
|
||||||
$model = new \core_analytics\model($modelobj);
|
$model = new \core_analytics\model($modelobj);
|
||||||
|
|
||||||
|
if ($model->is_static()) {
|
||||||
|
// Skip models based on assumptions.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$result = $model->train();
|
$result = $model->train();
|
||||||
if ($result) {
|
if ($result) {
|
||||||
echo $OUTPUT->heading(get_string('modelresults', 'tool_models', $model->get_target()->get_name()));
|
echo $OUTPUT->heading(get_string('modelresults', 'tool_models', $model->get_target()->get_name()));
|
||||||
|
|
||||||
$renderer = $PAGE->get_renderer('tool_models');
|
$renderer = $PAGE->get_renderer('tool_models');
|
||||||
echo $renderer->render_execute_results($result, $model->get_analyser()->get_logs());
|
echo $renderer->render_getpredictions_results($result, $model->get_analyser()->get_logs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ if (!empty($validdatasets) && !$model->is_enabled() && $options['non-interactive
|
|||||||
// Set the time splitting method file and enable it.
|
// Set the time splitting method file and enable it.
|
||||||
$model->enable($input);
|
$model->enable($input);
|
||||||
|
|
||||||
mtrace(get_string('executingmodel', 'tool_models'));
|
mtrace(get_string('trainandpredictmodel', 'tool_models'));
|
||||||
|
|
||||||
// Train the model with the selected time splitting method and start predicting.
|
// Train the model with the selected time splitting method and start predicting.
|
||||||
$model->train();
|
$model->train();
|
||||||
|
@ -31,12 +31,17 @@ defined('MOODLE_INTERNAL') || die();
|
|||||||
*/
|
*/
|
||||||
function xmldb_tool_models_install() {
|
function xmldb_tool_models_install() {
|
||||||
|
|
||||||
// TODO All of them for the moment, we will define a limited set of them once in core.
|
// Students at risk of dropping out of courses.
|
||||||
$target = \core_analytics\manager::get_target('\tool_models\analytics\target\course_dropout');
|
$target = \core_analytics\manager::get_target('\tool_models\analytics\target\course_dropout');
|
||||||
$indicators = \core_analytics\manager::get_all_indicators();
|
|
||||||
|
|
||||||
// We need the model to be created in order to know all its potential indicators and set them.
|
// We need the model to be created in order to know all its potential indicators and set them.
|
||||||
$model = \core_analytics\model::create($target, array());
|
$model = \core_analytics\model::create($target, array());
|
||||||
|
// TODO All of them for the moment, we will define a limited set of them once in core.
|
||||||
$model->update(0, $model->get_potential_indicators());
|
$model->update(0, $model->get_potential_indicators());
|
||||||
|
|
||||||
|
// Course without teachers.
|
||||||
|
$target = \core_analytics\manager::get_target('\tool_models\analytics\target\no_teaching_activity');
|
||||||
|
$weekbeforestart = '\core_analytics\local\time_splitting\week_before_course_start';
|
||||||
|
$noteacher = \core_analytics\manager::get_indicator('\core_course\analytics\indicator\no_teacher');
|
||||||
|
$key = '\\' . get_class($noteacher);
|
||||||
|
\core_analytics\model::create($target, array($key => $noteacher), $weekbeforestart);
|
||||||
}
|
}
|
||||||
|
@ -26,32 +26,37 @@ $string['accuracy'] = 'Accuracy';
|
|||||||
$string['allindicators'] = 'All indicators';
|
$string['allindicators'] = 'All indicators';
|
||||||
$string['analysingsitedata'] = 'Analysing the site';
|
$string['analysingsitedata'] = 'Analysing the site';
|
||||||
$string['analyticmodels'] = 'Analytic models';
|
$string['analyticmodels'] = 'Analytic models';
|
||||||
$string['bettercli'] = 'Models\' evaluation and execution are heavy processes, it is better to run them through command line interface';
|
$string['bettercli'] = 'To evaluate models and to get predictions are heavy processes, it is better to run them through command line interface';
|
||||||
$string['cantguessstartdate'] = 'Can\'t guess the start date';
|
$string['cantguessstartdate'] = 'Can\'t guess the start date';
|
||||||
$string['cantguessenddate'] = 'Can\'t guess the end date';
|
$string['cantguessenddate'] = 'Can\'t guess the end date';
|
||||||
$string['clienablemodel'] = 'You can enable the model by selecting a time splitting method by its id. Note that you can also enable it later using the web interface (\'none\' to exit)';
|
$string['clienablemodel'] = 'You can enable the model by selecting a time splitting method by its id. Note that you can also enable it later using the web interface (\'none\' to exit)';
|
||||||
$string['coursenotyetstarted'] = 'The course is not yet started';
|
$string['coursenotyetstarted'] = 'The course is not yet started';
|
||||||
$string['coursenotyetfinished'] = 'The course is not yet finished';
|
$string['coursenotyetfinished'] = 'The course is not yet finished';
|
||||||
$string['editmodel'] = 'Edit model {$a}';
|
$string['editmodel'] = 'Edit "{$a}" model';
|
||||||
$string['edittrainedwarning'] = 'This model has already been trained, note that changing its indicators or its time splitting method will delete its previous predictions and start generating the new ones';
|
$string['edittrainedwarning'] = 'This model has already been trained, note that changing its indicators or its time splitting method will delete its previous predictions and start generating the new ones';
|
||||||
$string['enabled'] = 'Enabled';
|
$string['enabled'] = 'Enabled';
|
||||||
$string['errorcantenablenotimesplitting'] = 'You need to select a time splitting method before enabling the model';
|
$string['errorcantenablenotimesplitting'] = 'You need to select a time splitting method before enabling the model';
|
||||||
$string['errornoenabledandtrainedmodels'] = 'There are not enabled and trained models to predict';
|
$string['errornoenabledandtrainedmodels'] = 'There are not enabled and trained models to predict';
|
||||||
$string['errornoenabledmodels'] = 'There are not enabled models to train';
|
$string['errornoenabledmodels'] = 'There are not enabled models to train';
|
||||||
|
$string['errornostaticedit'] = 'Models based on assumptions can not be edited';
|
||||||
|
$string['errornostaticevaluated'] = 'Models based on assumptions can not be evaluated, they are always 100% correct according to how they were defined';
|
||||||
|
$string['errornostaticlog'] = 'Models based on assumptions can not be evaluated, there is no preformance log';
|
||||||
$string['evaluate'] = 'Evaluate';
|
$string['evaluate'] = 'Evaluate';
|
||||||
$string['evaluatemodel'] = 'Evaluate model';
|
$string['evaluatemodel'] = 'Evaluate model';
|
||||||
$string['evaluationinbatches'] = 'The site contents are calculated and stored in batches, during evaluation you can stop the process at any moment, the next time you run it it will continue from the point you stopped it.';
|
$string['evaluationinbatches'] = 'The site contents are calculated and stored in batches, during evaluation you can stop the process at any moment, the next time you run it it will continue from the point you stopped it.';
|
||||||
$string['executemodel'] = 'Execute';
|
$string['trainandpredictmodel'] = 'Training model and calculating predictions';
|
||||||
$string['executingmodel'] = 'Training model and calculating predictions';
|
$string['getpredictionsresultscli'] = 'Results using {$a->name} (id: {$a->id}) course duration splitting';
|
||||||
$string['executionresultscli'] = 'Results using {$a->name} (id: {$a->id}) course duration splitting';
|
$string['getpredictionsresults'] = 'Results using {$a->name} course duration splitting';
|
||||||
$string['executionresults'] = 'Results using {$a->name} course duration splitting';
|
|
||||||
$string['extrainfo'] = 'Info';
|
$string['extrainfo'] = 'Info';
|
||||||
$string['generalerror'] = 'Evaluation error. Status code {$a}';
|
$string['generalerror'] = 'Evaluation error. Status code {$a}';
|
||||||
$string['goodmodel'] = 'This is a good model and it can be used to predict, enable it and execute it to start getting predictions.';
|
$string['getpredictions'] = 'Get predictions';
|
||||||
|
$string['goodmodel'] = 'This is a good model and it can be used to predict, enable it to start getting predictions.';
|
||||||
$string['indicators'] = 'Indicators';
|
$string['indicators'] = 'Indicators';
|
||||||
$string['info'] = 'Info';
|
$string['info'] = 'Info';
|
||||||
$string['labelstudentdropoutyes'] = 'Student at risk of dropping out';
|
$string['labelstudentdropoutyes'] = 'Student at risk of dropping out';
|
||||||
$string['labelstudentdropoutno'] = 'Not at risk';
|
$string['labelstudentdropoutno'] = 'Not at risk';
|
||||||
|
$string['labelteachingactivityyes'] = 'Teaching activity';
|
||||||
|
$string['labelteachingactivityno'] = 'No teaching activity';
|
||||||
$string['loginfo'] = 'Log extra info';
|
$string['loginfo'] = 'Log extra info';
|
||||||
$string['lowaccuracy'] = 'The model accuracy is low';
|
$string['lowaccuracy'] = 'The model accuracy is low';
|
||||||
$string['modelresults'] = '{$a} results';
|
$string['modelresults'] = '{$a} results';
|
||||||
@ -61,9 +66,11 @@ $string['nocompletiondetection'] = 'No method available to detect course complet
|
|||||||
$string['nocourseactivity'] = 'Not enough course activity between the start and the end of the course';
|
$string['nocourseactivity'] = 'Not enough course activity between the start and the end of the course';
|
||||||
$string['nocourseendtime'] = 'The course does not have an end time';
|
$string['nocourseendtime'] = 'The course does not have an end time';
|
||||||
$string['nocoursesections'] = 'No course sections';
|
$string['nocoursesections'] = 'No course sections';
|
||||||
|
$string['nocoursestarttime'] = 'The course does not have an start time';
|
||||||
$string['nocoursestudents'] = 'No students';
|
$string['nocoursestudents'] = 'No students';
|
||||||
$string['nodatatoevaluate'] = 'There is no data to evaluate the model';
|
$string['nodatatoevaluate'] = 'There is no data to evaluate the model';
|
||||||
$string['nodatatopredict'] = 'There is no data to use for predictions';
|
$string['nodatatopredict'] = 'No new elements to get predictions for';
|
||||||
|
$string['nodatatotrain'] = 'There is no new data that can be used for training';
|
||||||
$string['notdefined'] = 'Not yet defined';
|
$string['notdefined'] = 'Not yet defined';
|
||||||
$string['pluginname'] = 'Analytic models';
|
$string['pluginname'] = 'Analytic models';
|
||||||
$string['predictionresults'] = 'Prediction results';
|
$string['predictionresults'] = 'Prediction results';
|
||||||
@ -74,6 +81,7 @@ $string['samestartdate'] = 'Current start date is good';
|
|||||||
$string['sameenddate'] = 'Current end date is good';
|
$string['sameenddate'] = 'Current end date is good';
|
||||||
$string['target'] = 'Target';
|
$string['target'] = 'Target';
|
||||||
$string['target:coursedropout'] = 'Students at risk of dropping out';
|
$string['target:coursedropout'] = 'Students at risk of dropping out';
|
||||||
|
$string['target:noteachingactivity'] = 'No teaching activity';
|
||||||
$string['target:coursedropoutinfo'] = 'Here you can find a list of students at risk of dropping out.';
|
$string['target:coursedropoutinfo'] = 'Here you can find a list of students at risk of dropping out.';
|
||||||
$string['timemodified'] = 'Last modification';
|
$string['timemodified'] = 'Last modification';
|
||||||
$string['trainingprocessfinished'] = 'Training process finished';
|
$string['trainingprocessfinished'] = 'Training process finished';
|
||||||
|
@ -45,8 +45,8 @@ switch ($action) {
|
|||||||
case 'evaluate':
|
case 'evaluate':
|
||||||
$title = get_string('evaluatemodel', 'tool_models');
|
$title = get_string('evaluatemodel', 'tool_models');
|
||||||
break;
|
break;
|
||||||
case 'execute':
|
case 'getpredictions':
|
||||||
$title = get_string('executemodel', 'tool_models');
|
$title = get_string('getpredictions', 'tool_models');
|
||||||
break;
|
break;
|
||||||
case 'log':
|
case 'log':
|
||||||
$title = get_string('viewlog', 'tool_models');
|
$title = get_string('viewlog', 'tool_models');
|
||||||
@ -65,6 +65,11 @@ switch ($action) {
|
|||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
|
||||||
|
if ($model->is_static()) {
|
||||||
|
echo $OUTPUT->header();
|
||||||
|
throw new moodle_exception('errornostaticedit', 'tool_models');
|
||||||
|
}
|
||||||
|
|
||||||
$customdata = array(
|
$customdata = array(
|
||||||
'id' => $model->get_id(),
|
'id' => $model->get_id(),
|
||||||
'model' => $model,
|
'model' => $model,
|
||||||
@ -103,6 +108,11 @@ switch ($action) {
|
|||||||
|
|
||||||
case 'evaluate':
|
case 'evaluate':
|
||||||
echo $OUTPUT->header();
|
echo $OUTPUT->header();
|
||||||
|
|
||||||
|
if ($model->is_static()) {
|
||||||
|
throw new moodle_exception('errornostaticevaluate', 'tool_models');
|
||||||
|
}
|
||||||
|
|
||||||
// Web interface is used by people who can not use CLI nor code stuff, always use
|
// Web interface is used by people who can not use CLI nor code stuff, always use
|
||||||
// cached stuff as they will change the model through the web interface as well
|
// cached stuff as they will change the model through the web interface as well
|
||||||
// which invalidates the previously analysed stuff.
|
// which invalidates the previously analysed stuff.
|
||||||
@ -111,7 +121,7 @@ switch ($action) {
|
|||||||
echo $renderer->render_evaluate_results($results, $model->get_analyser()->get_logs());
|
echo $renderer->render_evaluate_results($results, $model->get_analyser()->get_logs());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'execute':
|
case 'getpredictions':
|
||||||
echo $OUTPUT->header();
|
echo $OUTPUT->header();
|
||||||
|
|
||||||
$trainresults = $model->train();
|
$trainresults = $model->train();
|
||||||
@ -123,11 +133,16 @@ switch ($action) {
|
|||||||
$predictlogs = $model->get_analyser()->get_logs();
|
$predictlogs = $model->get_analyser()->get_logs();
|
||||||
|
|
||||||
$renderer = $PAGE->get_renderer('tool_models');
|
$renderer = $PAGE->get_renderer('tool_models');
|
||||||
echo $renderer->render_execute_results($trainresults, $trainlogs, $predictresults, $predictlogs);
|
echo $renderer->render_getpredictions_results($trainresults, $trainlogs, $predictresults, $predictlogs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'log':
|
case 'log':
|
||||||
echo $OUTPUT->header();
|
echo $OUTPUT->header();
|
||||||
|
|
||||||
|
if ($model->is_static()) {
|
||||||
|
throw new moodle_exception('errornostaticlog', 'tool_models');
|
||||||
|
}
|
||||||
|
|
||||||
$renderer = $PAGE->get_renderer('tool_models');
|
$renderer = $PAGE->get_renderer('tool_models');
|
||||||
$modellogstable = new \tool_models\output\model_logs('model-' . $model->get_id(), $model->get_id());
|
$modellogstable = new \tool_models\output\model_logs('model-' . $model->get_id(), $model->get_id());
|
||||||
echo $renderer->render_table($modellogstable);
|
echo $renderer->render_table($modellogstable);
|
||||||
|
62
course/classes/analytics/indicator/no_teacher.php
Normal file
62
course/classes/analytics/indicator/no_teacher.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No teacher indicator.
|
||||||
|
*
|
||||||
|
* @package core_course
|
||||||
|
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace core_course\analytics\indicator;
|
||||||
|
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No teacher indicator.
|
||||||
|
*
|
||||||
|
* @package core_analytics
|
||||||
|
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
|
||||||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
class no_teacher extends \core_analytics\local\indicator\binary {
|
||||||
|
|
||||||
|
public static function get_name() {
|
||||||
|
return get_string('indicator:noteacher', 'moodle');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function required_sample_data() {
|
||||||
|
// We require course because, although calculate_sample only reads context, we need the context to be course
|
||||||
|
// or below.
|
||||||
|
return array('context', 'course');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculate_sample($sampleid, $sampleorigin, $notusedstarttime = false, $notusedendtime = false) {
|
||||||
|
|
||||||
|
$context = $this->retrieve('context', $sampleid);
|
||||||
|
|
||||||
|
$teacherroles = get_config('analytics', 'teacherroles');
|
||||||
|
$teacherroleids = explode(',', $teacherroles);
|
||||||
|
foreach ($teacherroleids as $role) {
|
||||||
|
if (get_role_users($role, $context)) {
|
||||||
|
return self::get_max_value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::get_min_value();
|
||||||
|
}
|
||||||
|
}
|
@ -61,11 +61,11 @@ class prediction implements \renderable, \templatable {
|
|||||||
$data = new \stdClass();
|
$data = new \stdClass();
|
||||||
|
|
||||||
// Sample info (determined by the analyser).
|
// Sample info (determined by the analyser).
|
||||||
list($data->sampledescription, $sampleimage) = $this->model->prediction_sample_description($this->prediction);
|
list($data->sampledescription, $samplerenderable) = $this->model->prediction_sample_description($this->prediction);
|
||||||
|
|
||||||
// Sampleimage is a renderable we should pass it to HTML.
|
// Sampleimage is a renderable we should pass it to HTML.
|
||||||
if ($sampleimage) {
|
if ($samplerenderable) {
|
||||||
$data->sampleimage = $output->render($sampleimage);
|
$data->samplelink = $output->render($samplerenderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prediction info.
|
// Prediction info.
|
||||||
|
@ -34,19 +34,19 @@
|
|||||||
}}
|
}}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="row m-a-1">
|
<div class="row m-a-1">
|
||||||
{{#sampleimage}}
|
{{#samplelink}}
|
||||||
<div class="col-sm-1 span1 m-b-1">
|
<div class="col-sm-1 span1 m-b-1">
|
||||||
{{{sampleimage}}}
|
{{{samplelink}}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3 span3 m-b-1">
|
<div class="col-sm-3 span3 m-b-1">
|
||||||
{{{sampledescription}}}
|
{{{sampledescription}}}
|
||||||
</div>
|
</div>
|
||||||
{{/sampleimage}}
|
{{/samplelink}}
|
||||||
{{^sampleimage}}
|
{{^samplelink}}
|
||||||
<div class="col-sm-4 span4 m-b-1">
|
<div class="col-sm-4 span4 m-b-1">
|
||||||
{{{sampledescription}}}
|
{{{sampledescription}}}
|
||||||
</div>
|
</div>
|
||||||
{{/sampleimage}}
|
{{/samplelink}}
|
||||||
<div class="col-sm-4 span4">
|
<div class="col-sm-4 span4">
|
||||||
<div class="{{predictionstyle}}">{{predictiondisplayvalue}}</div>
|
<div class="{{predictionstyle}}">{{predictiondisplayvalue}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user