public function topEnrichment(Request $request)
 {
     try {
         $users = MecanexUser::all();
         $videos = Video::all();
         $euscreen_id = $request->video;
         $video_id = $videos->where('video_id', $euscreen_id)->first()->id;
         $username = $request->user;
         $user_id = $users->where('username', $username)->first()->id;
         if ($request->num != 0) {
             $num = $request->num;
         } else {
             $num = 3;
         }
         $topEnrichments = [];
         $listEnrichments = DB::select(DB::raw('SELECT * FROM enrichments_videos_time WHERE video_id=?'), [$video_id]);
         $listEnrichments = json_decode(json_encode($listEnrichments), true);
         $topEnrichments = $this->recommend_enr($listEnrichments, $user_id);
         $topEnrichments = array_slice($topEnrichments, 0, $num, true);
         foreach ($topEnrichments as $key => $score) {
             $response[] = array('enrichment_id' => Enrichment::find($key)->enrichment_id, 'score' => $score);
         }
         $statusCode = 200;
         return $response;
     } catch (Exception $e) {
         $statusCode = 400;
     } finally {
         return Response::json($response, $statusCode);
     }
 }
 /**
  * Display a listing of the resource.
  *
  * @return Response
  */
 public function index()
 {
     try {
         $statusCode = 200;
         $response = ['Mecanex_Users' => []];
         $mecanexusers = MecanexUser::all();
         foreach ($mecanexusers as $mecanexuser) {
             $response['Mecanex_Users'][] = $mecanexuser;
             //					[
             //					'email' => $mecanexuser->email,
             //					'name' => $mecanexuser->name,
             //					'surname' => $mecanexuser->surname,
             //					'gender' => $mecanexuser->gender_id,
             //					'age' => $mecanexuser->age_id,
             //					'education' => $mecanexuser->education_id,
             //					'occupation' => $mecanexuser->occupation_id,
             //					'country' => $mecanexuser->country_id,
             //										];
         }
     } catch (Exception $e) {
         $statusCode = 400;
     } finally {
         return Response::json($response, $statusCode);
     }
 }
 private function similar_neighbors($user_id, $N)
 {
     $result = [];
     $temp_profile_scores = [];
     $terms = Term::all();
     $neighbors = MecanexUser::all();
     $user = MecanexUser::where('id', $user_id)->get()->first();
     $user_terms_scores = $user->profilescore;
     foreach ($user_terms_scores as $user_term_score) {
         $temp_profile_scores[] = $user_term_score->pivot->profile_score;
     }
     foreach ($neighbors as $neighbor) {
         if ($neighbor->id == $user_id) {
             continue;
         }
         $arithmitis = 0;
         $sumA = 0;
         $sumB = 0;
         $temp_neighbor_scores = [];
         $neighbor_terms_scores = DB::select(DB::raw('SELECT * FROM users_terms_profilescores WHERE mecanex_user_id=? ORDER BY term_id'), [$neighbor->id]);
         foreach ($neighbor_terms_scores as $neighbor_term_score) {
             $temp_neighbor_scores[] = $neighbor_term_score->profile_score;
         }
         for ($i = 0; $i < count($terms); $i++) {
             $arithmitis = $arithmitis + $temp_neighbor_scores[$i] * $temp_profile_scores[$i];
             $sumA = $sumA + pow($temp_neighbor_scores[$i], 2);
             $sumB = $sumB + pow($temp_profile_scores[$i], 2);
         }
         $neighborScores[$neighbor->id] = $arithmitis / (sqrt($sumA) + sqrt($sumB));
     }
     arsort($neighborScores);
     $neighborScores = array_slice($neighborScores, 0, $N, true);
     foreach ($neighborScores as $key => $score) {
         $neighbor = $neighbors->find($key);
         $result[] = array('neighbor' => $neighbor->id, 'similarity' => $score);
     }
     return $result;
 }
 /**
  * Display a listing of the resource.
  *
  * @return Response
  */
 public function target(Request $request)
 {
     try {
         $mecanexusers = MecanexUser::all();
         // filter by demographics
         if ($request->gender_id != 0) {
             $mecanexusers = $mecanexusers->where("gender_id", (int) $request->gender_id);
         }
         if ($request->age_id != 0) {
             $mecanexusers = $mecanexusers->where("age_id", (int) $request->age_id);
         }
         if ($request->education_id != 0) {
             $mecanexusers = $mecanexusers->where("education_id", (int) $request->education_id);
         }
         if ($request->occupation_id != 0) {
             $mecanexusers = $mecanexusers->where("occupation_id", (int) $request->occupation_id);
         }
         if ($request->country_id != 0) {
             $mecanexusers = $mecanexusers->where("country_id", (int) $request->country_id);
         }
         // filter by preference on terms
         // keep mecanex users whose term profile score is more than 0.7 when normalized by the max term value of the user
         $statusCode = 200;
         if ($request->terms != []) {
             $all_terms = Term::all();
             foreach ($all_terms as $term) {
                 if (strpos($request->terms, $term->term) !== false) {
                     $mecanexusers = $mecanexusers->filter(function ($user) use($term) {
                         $myquery = DB::select(DB::raw(' SELECT MAX(profile_score) as mymax
                                                        FROM users_terms_profilescores
                                                        WHERE mecanex_user_id=' . $user->id . ''));
                         if ($myquery[0]->mymax == 0) {
                             // don't take into account users that have not provided any information
                             return false;
                         }
                         return $user->profilescore[$term->id - 1]['pivot']['profile_score'] / $myquery[0]->mymax > 0.7;
                         // minus one because terms start from 0 where id starts from 1
                     });
                     //                        $response[] = $mecanexusers[1]->profilescore[$term->id-1]['pivot']['profile_score'];
                     //                        $myquery = DB::select(DB::raw(' SELECT MAX(profile_score) as mymax
                     //                                                           FROM users_terms_profilescores
                     //                                                           WHERE mecanex_user_id='. $mecanexusers[2]->id .''));
                 }
             }
         }
         $array_of_users = array();
         // If no mecanexusers exist from the filters selected, we return a random list of videos
         if ($mecanexusers->isEmpty()) {
             $response = [];
             $response['message'][] = "No information for the target group";
             $statusCode = 200;
             return $response;
         }
         foreach ($mecanexusers as $mecanexuser) {
             $array = array();
             $terms = $mecanexuser->profilescore;
             foreach ($terms as $term) {
                 $temp = (double) $term['pivot']['profile_score'];
                 array_push($array, $temp);
             }
             // normalize with maximum because that way the clustering seems more accurate
             $maximum = max($array);
             if ($maximum != 0) {
                 for ($i = 0; $i < count($array); $i++) {
                     $array[$i] = $array[$i] / $maximum;
                 }
             }
             array_push($array_of_users, $array);
         }
         /** return the array of users so that we can see whether the profiles have normalized
          * values so that they can be clustered properly
          */
         $space = new Space(14);
         $num_of_clusters = 5;
         foreach ($array_of_users as $point) {
             $space->addPoint($point);
         }
         $clusters = $space->solve($num_of_clusters);
         $all_users = [];
         //            foreach ($clusters as $i => $cluster)
         //                printf("Cluster %d [%d,%d]: %d points\n", $i, $cluster[0], $cluster[1], count($cluster));
         foreach ($clusters as $i => $cluster) {
             $terms = [];
             for ($j = 0; $j < 14; $j++) {
                 array_push($terms, $cluster[$j]);
             }
             $all_users[] = ['cluster_id' => $i, 'cluster_terms' => $terms, 'num_of_users' => count($cluster)];
         }
         $statusCode = 200;
         $response = $all_users;
         return $response;
     } catch (Exception $e) {
         $statusCode = 400;
     } finally {
         return Response::json($response, $statusCode);
     }
 }
 /**
  * Return clusterheads and corresponding videos for filtered users.
  *
  * @return Clusterheads and videos
  */
 public function professional(Request $request)
 {
     try {
         $mecanexusers = MecanexUser::all();
         // filter by demographics
         if ($request->gender_id != 0) {
             $mecanexusers = $mecanexusers->where("gender_id", (int) $request->gender_id);
         }
         if ($request->age_id != 0) {
             $mecanexusers = $mecanexusers->where("age_id", (int) $request->age_id);
         }
         if ($request->education_id != 0) {
             $mecanexusers = $mecanexusers->where("education_id", (int) $request->education_id);
         }
         if ($request->occupation_id != 0) {
             $mecanexusers = $mecanexusers->where("occupation_id", (int) $request->occupation_id);
         }
         if ($request->country_id != 0) {
             $mecanexusers = $mecanexusers->where("country_id", (int) $request->country_id);
         }
         if ($request->num != 0) {
             $num = $request->num;
         } else {
             $num = 50;
         }
         // filter by preference on terms
         // keep mecanex users whose term profile score is more than 0.7 when normalized by the max term value of the user
         if ($request->terms != []) {
             $all_terms = Term::all();
             foreach ($all_terms as $term) {
                 if (strpos($request->terms, $term->term) !== false) {
                     $mecanexusers = $mecanexusers->filter(function ($user) use($term) {
                         $myquery = DB::select(DB::raw(' SELECT MAX(profile_score) as mymax
                                                        FROM users_terms_profilescores
                                                        WHERE mecanex_user_id=' . $user->id . ''));
                         if ($myquery[0]->mymax == 0) {
                             // don't take into account users that have not provided any information
                             return false;
                         }
                         return $user->profilescore[$term->id - 1]['pivot']['profile_score'] / $myquery[0]->mymax > 0.7;
                         // minus one because terms start from 0 where id starts from 1
                     });
                     //                        $response[] = $mecanexusers[1]->profilescore[$term->id-1]['pivot']['profile_score'];
                     //                        $myquery = DB::select(DB::raw(' SELECT MAX(profile_score) as mymax
                     //                                                           FROM users_terms_profilescores
                     //                                                           WHERE mecanex_user_id='. $mecanexusers[2]->id .''));
                 }
             }
         }
         $array_of_users = array();
         // If no mecanexusers exist from the filters selected, we return a random list of videos
         if ($mecanexusers->isEmpty()) {
             if ($request->videos == null) {
                 $videos = Video::orderByRaw('RAND()')->take($num)->get();
             } else {
                 $reqvideos = "'" . str_replace(",", "','", $request->videos) . "'";
                 //                    $videos = Video::where('video_id','in',['EUS_025A722EA4B240D8B6F6330A8783143C'])->orderByRaw('RAND()')->take($num)->get();
                 $videos = DB::select(DB::raw(' SELECT *
                                         FROM videos
                                         WHERE video_id IN (' . $reqvideos . ') ORDER BY RAND()  LIMIT ' . $num . ''));
             }
             $response = [];
             foreach ($videos as $video) {
                 $response['videos'][] = $video->video_id;
             }
             $statusCode = 200;
             return $response;
         }
         foreach ($mecanexusers as $mecanexuser) {
             $array = array();
             $terms = $mecanexuser->profilescore;
             foreach ($terms as $term) {
                 $temp = (double) $term['pivot']['profile_score'];
                 array_push($array, $temp);
             }
             array_push($array_of_users, $array);
         }
         /** return the array of users so that we can see whether the profiles have normalized
          * values so that they can be clustered properly
          */
         //            return $array_of_users;
         $space = new Space(14);
         $num_of_clusters = 5;
         foreach ($array_of_users as $point) {
             $space->addPoint($point);
         }
         $clusters = $space->solve($num_of_clusters);
         $statusCode = 200;
         $all_users = [];
         //            foreach ($clusters as $i => $cluster)
         //                printf("Cluster %d [%d,%d]: %d points\n", $i, $cluster[0], $cluster[1], count($cluster));
         foreach ($clusters as $i => $cluster) {
             $terms = [];
             for ($j = 0; $j < 14; $j++) {
                 array_push($terms, $cluster[$j]);
             }
             $all_users[] = ['cluster_id' => $i, 'cluster_terms' => $terms, 'num_of_users' => count($cluster)];
         }
         $cluster_list = [];
         foreach ($all_users as $user) {
             $cluster_list[] = ['cluster_id' => $user['cluster_id'], 'video_ids' => $this->recommend_video($user['cluster_terms'], $request), 'cluster_terms' => $user['cluster_terms'], 'num_of_users' => $user['num_of_users']];
         }
         //            $response = $cluster_list[0]['video_ids'][0]->id;
         $video_list = [];
         $response = [];
         $num_of_videos = 0;
         $total_num_of_videos = count($cluster_list[0]['video_ids']);
         for ($i = 0; $i < $total_num_of_videos; $i++) {
             for ($j = 0; $j < $num_of_clusters; $j++) {
                 $video = $cluster_list[$j]['video_ids'][$i];
                 if (!in_array($video->video_id, $video_list, true)) {
                     $video_list[] = $video->video_id;
                     $response['videos'][] = $video->euscreen_id;
                     $num_of_videos += 1;
                 }
                 if ($num_of_videos == $total_num_of_videos) {
                     break;
                 }
             }
             if ($num_of_videos == $total_num_of_videos) {
                 break;
             }
         }
         return $response;
     } catch (Exception $e) {
         $statusCode = 400;
     } finally {
         return Response::json($response, $statusCode);
     }
 }