Example #1
0
    def buildDataset(cls, all_results: Dataset, testie: Testie) -> List[tuple]:
        dtype = testie.variables.dtype()
        y = OrderedDict()
        dataset = []
        for i, (run, results_types) in enumerate(all_results.items()):
            vars = list(run.variables.values())
            if not results_types is None and len(results_types) > 0:
                dataset.append(vars)
                for result_type, results in results_types.items():
                    r = np.mean(results)
                    y.setdefault(result_type, []).append(r)

        dtype['values'] = [None] * len(dtype['formats'])
        for i, f in enumerate(dtype['formats']):
            if f is str:
                dtype['formats'][i] = int
                values = OrderedSet()
                for row in dataset:
                    values.add(row[i])
                    row[i] = values.index(row[i])
                dtype['values'][i] = list(values)
        X = np.array(dataset, ndmin=2)

        lset = []
        for result_type, v in y.items():
            lset.append((result_type, X, np.array(v),dtype))
        return lset
Example #2
0
    def writeversion(self,
                     testie,
                     all_results: Dataset,
                     allow_overwrite: bool = False,
                     kind=False,
                     reload=True):
        if not reload and all_results:
            prev = self.load_results(testie=testie, kind=kind, cache=True)
            if prev and len(all_results) < len(prev):
                print(
                    "ERROR ! Have less results than before. Forcing update write !"
                )
                reload = True
                return
        if reload:
            results = self.load_results(testie=testie, kind=kind, cache=False)
            if results:
                results.update(all_results)
                all_results = results

        if kind:
            for kind, kresult in all_results.items():
                filename = self.__resultFilename(testie) + '-' + kind
                self._writeversion(filename, kresult, allow_overwrite)
        else:
            filename = self.__resultFilename(testie)
            self._writeversion(filename, all_results, allow_overwrite)
Example #3
0
 def writeversion(self, script, all_results: Dataset):
     filename = self.__resultFilename(script)
     try:
         if not os.path.exists(os.path.dirname(filename)):
             os.makedirs(os.path.dirname(filename))
     except OSError:
         print("Error : could not create %s" % os.path.dirname(filename))
     f = open(filename, 'w+')
     f.seek(0)
     for run, results in all_results.items():
         v = []
         for key, val in sorted(run.variables.items()):
             if type(val) is tuple:
                 val = val[1]
             v.append(key + ":" + str(val).replace(':','\:'))
         type_results = []
         for t,r in results.items():
             str_results = []
             if r is None:
                 pass
             else:
                 for val in r:
                     str_results.append(str(val))
             type_results.append(t+':'+(','.join(str_results)))
         f.write(','.join(v) + "={" + '},{'.join(type_results) + "}\n")
     f.close()
Example #4
0
    def buildDataset(cls, all_results: Dataset, testie: Testie):
        dtype = testie.variables.dtype()
        y = []
        dataset = []
        for i, (run, results) in enumerate(all_results.items()):
            vars = list(run.variables.values())
            if not results is None:
                dataset.append(vars)
                y.append(np.mean(results))
        dtype['formats'] = dtype['formats']
        dtype['names'] = dtype['names']

        for i, f in enumerate(dtype['formats']):
            if f is str:
                dtype['formats'][i] = int
                values = OrderedSet()
                for row in dataset:
                    values.add(row[i])
                    row[i] = values.index(row[i])
        X = np.array(dataset, ndmin=2)
        return X, np.array(y, dtype=[('result', float)])
Example #5
0
    def compare(self,
                testie: Testie,
                variable_list,
                all_results: Dataset,
                build,
                old_all_results,
                last_build,
                allow_supplementary=True,
                init_done=False) -> Tuple[int, int]:
        """
        Compare two sets of results for the given list of variables and returns the amount of failing test
        :param init_done: True if initialization for current testie is already done (init sections for the testie and its import)
        :param testie: One testie to get the config from
        :param variable_list:
        :param all_results:
        :param build:
        :param old_all_results:
        :param last_build:
        :param allow_supplementary:
        :return: the amount of failed tests (0 means all passed)
        """

        if not old_all_results:
            return 0, 0

        tests_passed = 0
        tests_total = 0
        supp_done = False
        tot_runs = testie.config["n_runs"] + testie.config[
            "n_supplementary_runs"]
        for v in variable_list:
            tests_total += 1
            run = Run(v)
            results_types = all_results.get(run)
            # TODO : some config could implement acceptable range no matter the old value
            if results_types is None or len(results_types) == 0:
                continue

            need_supp = False
            for result_type, result in results_types.items():
                if run in old_all_results and not old_all_results[run] is None:
                    old_result = old_all_results[run].get(result_type, None)
                    if old_result is None:
                        continue

                    ok, diff = self.accept_diff(testie, result, old_result)
                    if not ok and len(
                            result) < tot_runs and allow_supplementary:
                        need_supp = True
                        break
                elif last_build:
                    if not testie.options.quiet_regression:
                        print("No old values for %s for version %s." %
                              (run, last_build.version))
                    if old_all_results:
                        old_all_results[run] = {}

            if need_supp:
                if not testie.options.quiet_regression:
                    print(
                        "Difference of %.2f%% is outside acceptable margin for %s. Running supplementary tests..."
                        % (diff * 100, run.format_variables()))

                if not init_done:
                    testie.do_init_all(build=build,
                                       options=testie.options,
                                       do_test=testie.options.do_test)
                    init_done = True
                if hasattr(testie, 'late_variables'):
                    v = testie.late_variables.execute(v, testie)
                new_results_types, output, err = testie.execute(
                    build,
                    run,
                    v,
                    n_runs=testie.config["n_supplementary_runs"],
                    allowed_types={SectionScript.TYPE_SCRIPT})

                for result_type, results in new_results_types.items():
                    results_types[result_type] += results

                if not testie.options.quiet_regression:
                    print("Result after supplementary tests done :",
                          results_types)

                if new_results_types is not None:
                    supp_done = True
                    all_results[run] = results_types
                    for result_type, result in results_types.items():
                        old_result = old_all_results[run].get(
                            result_type, None)
                        if old_result is None:
                            continue
                        ok, diff = self.accept_diff(testie, result, old_result)
                        if ok is False:
                            break
                else:
                    ok = True

            if len(results_types) > 0:
                if not ok:
                    print(
                        "ERROR: Test %s is outside acceptable margin between %s and %s : difference of %.2f%% !"
                        % (testie.filename, build.version, last_build.version,
                           diff * 100))
                else:
                    tests_passed += 1
                    if not testie.options.quiet_regression:
                        print("Acceptable difference of %.2f%% for %s" %
                              ((diff * 100), run.format_variables()))

        if supp_done:
            build.writeversion(testie, all_results)
        return tests_passed, tests_total
Example #6
0
    def run(build: Build,
            all_results: Dataset,
            testie: Testie,
            max_depth=3,
            filename=None):
        print("Building dataset...")
        X, y = Statistics.buildDataset(all_results, testie)
        print("Learning dataset built with %d samples and %d features..." %
              (X.shape[0], X.shape[1]))
        clf = tree.DecisionTreeRegressor(max_depth=max_depth)
        clf = clf.fit(X, y)

        if max_depth is None or max_depth > 8:
            print("No tree graph when maxdepth is > 8")
        else:
            dot_data = tree.export_graphviz(
                clf,
                out_file=None,
                filled=True,
                rounded=True,
                special_characters=True,
                feature_names=testie.variables.dtype()['names'])
            graph = pydotplus.graph_from_dot_data(dot_data)
            if filename:
                f = filename
            else:
                f = build.result_path(testie.filename, 'pdf', suffix='_clf')
            graph.write(f, format=os.path.splitext(f)[1][1:])
            print("Decision tree visualization written to %s" % f)

        print("")
        print("Feature importances :")
        # noinspection PyUnresolvedReferences
        for key, f in zip(testie.variables.dtype()['names'],
                          clf.feature_importances_):
            print("  %s : %0.2f" % (key, f))

        vars_values = {}
        for run, results in all_results.items():
            for k, v in run.variables.items():
                vars_values.setdefault(k, set()).add(v)

        print('')
        print("Better :")
        best = X[y['result'].argmax()]
        print("  ", end='')
        f = next(iter(all_results.items()))
        for i, (k, v) in enumerate(f[0].variables.items()):
            print("%s = %s, " % (k, best[i]), end='')
        print(' : %.02f' % y['result'].max())

        print('')
        print("Means and std/mean per variables :")
        for k, vals in vars_values.items():
            if len(vals) is 1:
                continue
            print("%s :" % k)
            for v in sorted(vals):
                tot = 0
                std = 0
                n = 0
                for run, results in all_results.items():
                    if run.variables[k] == v:
                        if not results is None:
                            tot += np.mean(results)
                            std += np.std(results)
                            n += 1
                if n == 0:
                    print("  %s : None" % v)
                else:
                    print("  %s : (%.02f,%.02f), " % (v, tot / n, std / n /
                                                      (tot / n)))
            print("")
Example #7
0
    def execute_all(
            self,
            build,
            options,
            prev_results: Dataset = None,
            do_test=True,
            allowed_types=SectionScript.ALL_TYPES_SET) -> Tuple[Dataset, bool]:
        """Execute script for all variables combinations. All tools reliy on this function for execution of the testie
        :param allowed_types:Tyeps of scripts allowed to run. Set with either init, scripts or both
        :param do_test: Actually run the tests
        :param options: NPF options object
        :param build: A build object
        :param prev_results: Previous set of result for the same build to update or retrieve
        :return: Dataset(Dict of variables as key and arrays of results as value)
        """

        init_done = False

        if not SectionScript.TYPE_SCRIPT in allowed_types:
            # If scripts is not in allowed_types, we have to run the init by force now
            self.do_init_all(build,
                             options,
                             do_test=do_test,
                             allowed_types=allowed_types)
            return {}, True

        all_results = {}
        for variables in self.variables:
            run = Run(variables)
            if hasattr(self, 'late_variables'):
                variables = self.late_variables.execute(variables, self)
            r_status, r_out, r_err = self.test_require(variables, build)
            if not r_status:
                if not self.options.quiet:
                    print("Requirement not met for %s" %
                          run.format_variables(self.config["var_hide"]))
                    if r_out.strip():
                        print(output.strip())
                    if r_err.strip():
                        print(err.strip())

                continue

            if prev_results and prev_results is not None and not options.force_test:
                run_results = prev_results.get(run, {})
                if run_results is None:
                    run_results = {}
            else:
                run_results = {}

            if not run_results and options.use_last:
                for version in build.repo.method.get_history(build.version):
                    oldb = Build(build.repo, version)
                    r = oldb.load_results(self)
                    if r and run in r:
                        run_results = r[run]
                        break

            for result_type in self.config['results_expect']:
                if result_type not in run_results:
                    run_results = {}

            have_new_results = False

            n_runs = self.config["n_runs"] - (
                0 if options.force_test or len(run_results) == 0 else min([
                    len(results)
                    for result_type, results in run_results.items()
                ]))
            if n_runs > 0 and do_test:
                if not init_done:
                    self.do_init_all(build,
                                     options,
                                     do_test,
                                     allowed_types=allowed_types)
                    init_done = True
                if not self.options.quiet:
                    print(run.format_variables(self.config["var_hide"]))

                new_results, output, err = self.execute(
                    build,
                    run,
                    variables,
                    n_runs,
                    n_retry=self.config["n_retry"],
                    allowed_types={SectionScript.TYPE_SCRIPT})
                if new_results:
                    if self.options.show_full:
                        print("stdout:")
                        print(output)
                        print("stderr:")
                        print(err)
                    for k, v in new_results.items():
                        run_results.setdefault(k, []).extend(v)
                        have_new_results = True
            else:
                if not self.options.quiet:
                    print(run.format_variables(self.config["var_hide"]))

            if len(run_results) > 0:
                if not self.options.quiet:
                    if len(run_results) == 1:
                        print(list(run_results.values())[0])
                    else:
                        print(run_results)
                all_results[run] = run_results
            else:
                all_results[run] = {}

            # Save results
            if all_results and have_new_results:
                if prev_results:
                    prev_results[run] = all_results[run]
                    build.writeversion(self, prev_results)
                else:
                    build.writeversion(self, all_results)

        return all_results, init_done