Skip to content
Merged
Show file tree
Hide file tree
Changes from 121 commits
Commits
Show all changes
145 commits
Select commit Hold shift + click to select a range
5fe1519
Add new module for features extraction.
Ivan-Veselov Jul 16, 2018
ba2e10b
Add MethodInfo and MethodInfoRepository classes.
Ivan-Veselov Jul 16, 2018
b2e3c91
Modify getMethods method of MethodInfoRepository class so that it now…
Ivan-Veselov Jul 16, 2018
9593f0a
Change read interface of MethodInfo object. Now it doesn't return inn…
Ivan-Veselov Jul 16, 2018
e101cb6
Change description of MethodInfoRepository class.
Ivan-Veselov Jul 16, 2018
f7cc867
Merge branch 'master' of github.com:ml-in-programming/ArchitectureRel…
Ivan-Veselov Jul 16, 2018
320d336
Fix typo in build.gradle.
Ivan-Veselov Jul 16, 2018
ef1c2de
Add InfoCollector class.
Ivan-Veselov Jul 16, 2018
6fbaac2
Extract ScopeAbstractTest.
Ivan-Veselov Jul 16, 2018
353e9ff
Move ScopeAbstractTest to utils module.
Ivan-Veselov Jul 16, 2018
793fe42
Remove redundant semicolon.
Ivan-Veselov Jul 16, 2018
da484fe
Make getInstance method static.
Ivan-Veselov Jul 16, 2018
8c2a993
Add ability to load all test file at once to ScopeAbstractTest.
Ivan-Veselov Jul 16, 2018
b31f4ae
Create a small testing framework for InfoCollector class.
Ivan-Veselov Jul 16, 2018
b3d6a14
Change MethodInfo structure. Now it stores only different methods wit…
Ivan-Veselov Jul 17, 2018
3bd2c2b
Add accesses fields to MethodInfo class.
Ivan-Veselov Jul 17, 2018
d3c14fe
Add a few simple InfoCollector tests.
Ivan-Veselov Jul 17, 2018
a50c007
Fixes #71
RamSaw Jul 17, 2018
be0f7d8
Move Info classes to info package.
Ivan-Veselov Jul 17, 2018
db0a98d
Add a few classes for features.
Ivan-Veselov Jul 17, 2018
d2d2cb9
Rename MethodInfo methods to make them clearer.
Ivan-Veselov Jul 17, 2018
b4d9b61
Add extractor for existing feature.
Ivan-Veselov Jul 17, 2018
bcb3398
Add FeatureVector class and an extractor for feature vectors.
Ivan-Veselov Jul 17, 2018
1ae75fc
Add MoveMethodFeaturesExtractor singleton.
Ivan-Veselov Jul 17, 2018
654ff1a
Change interface of extract method of MoveMethodFeaturesExtractor cla…
Ivan-Veselov Jul 17, 2018
051a965
Implement extract method of MoveMethodFeaturesExtractor.
Ivan-Veselov Jul 17, 2018
ed58734
Rename MoveMethodFeatureExtractor to MoveMethodSingleFeatureExtractor…
Ivan-Veselov Jul 17, 2018
cc083a6
Fix bug in SameInstancePublicCallTargetsExtractor.
Ivan-Veselov Jul 17, 2018
05964f9
Add SameInstanceNotPublicCallTargets feature.
Ivan-Veselov Jul 17, 2018
a11282e
Extend MethodInfo class interface with methods that create stream of …
Ivan-Veselov Jul 17, 2018
453f90b
Reimplement existing feature extractors through new interface of Meth…
Ivan-Veselov Jul 17, 2018
3b0bef3
Add SameClassStaticPublicCallTargets feature.
Ivan-Veselov Jul 18, 2018
87e3a81
Add features and their extractors.
Ivan-Veselov Jul 18, 2018
1ef88c4
Replace int value of Feature by double.
Ivan-Veselov Jul 18, 2018
c611ec0
Make FeatureVector Serializable.
Ivan-Veselov Jul 18, 2018
a1c249b
Add VectorSerializer class which can serialize and deserialize Featur…
Ivan-Veselov Jul 18, 2018
413200d
Implemented first version of refactorings loader. Added test for parser.
RamSaw Jul 18, 2018
2faf99f
IDEA's automatic reformat code has done bad formatting. Fixed.
RamSaw Jul 18, 2018
0d8adb0
Extracted to methods of TextFormRefactoring class code that was used …
RamSaw Jul 19, 2018
8d2adba
Add VectorSerializer class which can serialize and deserialize Featur…
Ivan-Veselov Jul 19, 2018
77cf829
Change try-catch block in main method so that it now catches all poss…
Ivan-Veselov Jul 19, 2018
db38aad
Improve exception message format.
Ivan-Veselov Jul 19, 2018
f57dc0b
Improve exception message format v2.
Ivan-Veselov Jul 19, 2018
215065a
Merge pull request #98 from ml-in-programming/implement_invocation_of…
Ivan-Veselov Jul 19, 2018
5a5447b
Merge pull request #99 from ml-in-programming/features-creation
Ivan-Veselov Jul 19, 2018
a6ec3f1
Add serialization to feature-extaction utility.
Ivan-Veselov Jul 20, 2018
a4d695f
Add creation of non-existing directories.
Ivan-Veselov Jul 20, 2018
3419b24
Improve "Failed to resolve method call" exception message.
Ivan-Veselov Jul 20, 2018
2af519e
Add a handy bash script to launch extract-features utility.
Ivan-Veselov Jul 20, 2018
2a36f7d
Replaced list of refactorings to set of refactorings because refactor…
RamSaw Jul 20, 2018
ec1c81a
Modify logging of found refactorings. Now it shows declaration of met…
Ivan-Veselov Jul 20, 2018
f0df794
Added support for method parameters.
RamSaw Jul 20, 2018
d2aed84
Merge branch 'features-extraction' into goldset_ambigous_error_fix
RamSaw Jul 20, 2018
6b99371
Added convert from set to list to fit method params. But it seems to …
RamSaw Jul 20, 2018
423a11a
Modify implementation of extractors. Now it doesnt rely on MethodInfo…
Ivan-Veselov Jul 23, 2018
c3c9982
Add simple tests for AnotherInstanceCallersExtractor.
Ivan-Veselov Jul 23, 2018
48e7702
Merge pull request #100 from ml-in-programming/goldset_ambigous_error…
Ivan-Veselov Jul 23, 2018
47a6727
Add more test for AnotherInstanceCallersExtractor.
Ivan-Veselov Jul 23, 2018
268e090
Removed excessive output.
RamSaw Jul 23, 2018
5ba6598
Add tests for AnotherInstanceNotPublicCallTargetsExtractor.
Ivan-Veselov Jul 23, 2018
6f5b626
Add tests for all features extractors.
Ivan-Veselov Jul 23, 2018
8661440
Raw version of refactoring generation system.
RamSaw Jul 23, 2018
8229ab6
Removed field support, added exception handling and print output.
RamSaw Jul 23, 2018
724ee1b
Changed sets on lists.
RamSaw Jul 23, 2018
5bbf626
Implemented constraint for relevant properties.
RamSaw Jul 24, 2018
7b88ba0
Now classes from method usage scope are added only for methods whose …
RamSaw Jul 24, 2018
cea5052
Deleted redundant checking.
RamSaw Jul 24, 2018
d5cad38
added qualified name of class
RamSaw Jul 24, 2018
0810b1d
Add new argument for output file. Also add handy launching script.
Ivan-Veselov Jul 24, 2018
d8cdd4a
Merge branch 'refactorings-generation' of github.com:ml-in-programmin…
Ivan-Veselov Jul 24, 2018
04a829b
Removed test sources from scope.
RamSaw Jul 24, 2018
0611f3d
Merge remote-tracking branch 'origin/refactorings-generation' into re…
RamSaw Jul 24, 2018
c727b94
Fix extract-features.sh script.
Ivan-Veselov Jul 24, 2018
0a99b0f
Added print stack trace.
RamSaw Jul 24, 2018
9bc0613
Merge pull request #102 from ml-in-programming/refactorings-generation
Ivan-Veselov Jul 24, 2018
9aea382
Added conversion to JMove dataset string representation type of refac…
RamSaw Jul 24, 2018
a70bf7d
Fixed generation output, Test heuristic exclusion.
RamSaw Jul 24, 2018
31ce03d
Test checking added.
RamSaw Jul 24, 2018
a3868d3
Added support for several refactorings for one method.
RamSaw Jul 24, 2018
f6b24aa
Fixed parser.
RamSaw Jul 24, 2018
9fbe141
added private checking.
RamSaw Jul 24, 2018
7a4a2be
added only public support.
RamSaw Jul 24, 2018
41d8b60
added void support.
RamSaw Jul 24, 2018
6c9bd52
Added calculation of number of java files in project and 3% now are t…
RamSaw Jul 25, 2018
d4c3cf7
Raw version of migration.
RamSaw Jul 30, 2018
cef5cec
Checked new format. Full migration to this format.
RamSaw Jul 31, 2018
042686e
Merge to resolve conflicts.
RamSaw Jul 31, 2018
02885c9
Merge pull request #109 from ml-in-programming/migrate_dataset_to_JB_…
RamSaw Jul 31, 2018
ac9938b
Initial commit. Created new module for algorithms evaluation.
RamSaw Jul 31, 2018
05ca143
Merge branches 'algorithms-evaluation' and 'features-extraction' of h…
RamSaw Jul 31, 2018
b9e4793
Merge branches 'algorithms-evaluation' and 'create_algorithm_reposito…
RamSaw Jul 31, 2018
bba1668
Merge branches 'algorithms-evaluation' and 'features-extraction' of h…
RamSaw Jul 31, 2018
5bb84ef
Added algorithm evaluator class.
RamSaw Aug 1, 2018
9afbc11
Implement ProjectLoader and naive ApplicationStarter.
RamSaw Aug 1, 2018
a3c8f83
Extract new module with algorithms and ui for plugin.
RamSaw Aug 1, 2018
00159d2
Merge branches 'algorithms-evaluation' and 'master' of https://github…
RamSaw Aug 1, 2018
bbe72f7
Added build.gradle for algorithms module.
RamSaw Aug 1, 2018
67beee3
Preparation for format converter implementation.
RamSaw Aug 1, 2018
3cc81b9
Implemented formatter.
RamSaw Aug 2, 2018
c8b9159
Created evaluation utility.
RamSaw Aug 2, 2018
6d3a601
Removed Refactoring class from extraction module. Added some tests in…
RamSaw Aug 3, 2018
68a1dad
Added MSE evaluation.
RamSaw Aug 3, 2018
c719c1a
Added support to run all algorithms, also added test for combined res…
RamSaw Aug 3, 2018
d1f8e7f
Added support to run all algorithms, also added test for combined res…
RamSaw Aug 6, 2018
010b8b6
Added right highlighting for MSE and ME - min result is the best.
RamSaw Aug 6, 2018
128932f
Changed to ParallelStream in evaluation of each algorithm and loadPro…
RamSaw Aug 7, 2018
b3b8c70
Merged with old algorithms adaptation branch. Now evaluation is faste…
RamSaw Aug 8, 2018
4e31a3e
Uncommited changes.
RamSaw Aug 8, 2018
5451fc2
MSE corrected: now it considers not found elements too. Also added di…
RamSaw Aug 8, 2018
1667a56
Added more memory for evaluation.
RamSaw Aug 8, 2018
6657310
Added tests for ProjectEvaluationResult.
RamSaw Aug 9, 2018
71c852b
Added logging during projects iterations.
RamSaw Aug 9, 2018
4ba4260
Merge branches 'master' and 'smartPsiElementPointer_integration' of h…
RamSaw Aug 10, 2018
76a76e8
Migrated getWarnings to smart pointers.
RamSaw Aug 13, 2018
80ee1ba
filter migrated to smart pointers.
RamSaw Aug 13, 2018
1da47ca
openDefinition migrated to smart pointers.
RamSaw Aug 13, 2018
a1c034c
getHumanReadableName moved to PSIUtil.
RamSaw Aug 13, 2018
6e28936
Merge pull request #101 from ml-in-programming/features-tests
Ivan-Veselov Aug 13, 2018
29f5891
Erased getEntityName and getTargetName.
RamSaw Aug 13, 2018
5ead406
Fixes tests.
RamSaw Aug 13, 2018
74edb92
Fixes #127
RamSaw Aug 14, 2018
16a82d0
Fixes #134. Solution: table model has a method to indicate whether an…
RamSaw Aug 14, 2018
f562e18
Merge branch 'algorithms-evaluation' of github.com:ml-in-programming/…
Ivan-Veselov Aug 14, 2018
65fb38c
Merge branch 'features-extraction' of github.com:ml-in-programming/Ar…
Ivan-Veselov Aug 14, 2018
870d58b
Remove algorithms from RefactoringExecutionContext.
Ivan-Veselov Aug 14, 2018
3eeafea
Merge with master. Ready to merge PR.
RamSaw Aug 14, 2018
a5e0572
Merge with master. Ready to merge PR.
RamSaw Aug 14, 2018
83999a9
Remove hamcrest jar.
Ivan-Veselov Aug 14, 2018
dc0da69
Added important todo.
RamSaw Aug 15, 2018
7388196
Add shebang to sh files.
Ivan-Veselov Aug 15, 2018
ecc5371
fix refacroting list initialization
ujohnny Aug 15, 2018
3111b1f
Replace System out by log messages in FormatterApplicationStarter class.
Ivan-Veselov Aug 15, 2018
70ba0c7
Merge branch 'integration2' of github.com:ml-in-programming/Architect…
Ivan-Veselov Aug 15, 2018
0b0e5b9
Move IDEA extensions to separate plugins.
Ivan-Veselov Aug 15, 2018
0d57bcd
Rename refactoring generation plugin.
Ivan-Veselov Aug 15, 2018
720d04a
Merge branch 'integration2' of https://github.com/ml-in-programming/A…
RamSaw Aug 15, 2018
03d8bbe
Merge branch 'integration2' of https://github.com/ml-in-programming/A…
RamSaw Aug 15, 2018
312030e
Updated idea extensions on new design.
RamSaw Aug 15, 2018
8d8fff4
Fixes compilation errors.
RamSaw Aug 15, 2018
e13c02d
Merge pull request #125 from ml-in-programming/smartPsiElementPointer…
ujohnny Aug 15, 2018
c251852
Improve logging by splitting refactorings on three groups and calcula…
Ivan-Veselov Aug 15, 2018
f22a07c
Adapt validator to new log format.
Ivan-Veselov Aug 15, 2018
30ba99f
Replace getEntity call of MoveToClassRefactoring by getEntityOrThrow …
Ivan-Veselov Aug 15, 2018
2db2e25
Replace getMethod and getField calls as well. Also rename methods.
Ivan-Veselov Aug 15, 2018
9ce94f6
gray out refactor button after refactoring applied
ujohnny Aug 15, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ArchitectureReloaded.iml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public void onCancel() {

public void calculateMetrics(MetricsProfile profile, final MetricsResultsHolder resultsHolder) {
final ProgressIndicator indicator;
if (ApplicationManager.getApplication().isUnitTestMode()) {

if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment()) {
indicator = new EmptyProgressIndicator();
} else {
indicator = ProgressManager.getInstance().getProgressIndicator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.regex.Pattern;

public final class MethodUtils {

Expand Down Expand Up @@ -64,6 +65,14 @@ public static boolean isStatic(PsiModifierListOwner unit) {
return unit.hasModifierProperty(PsiModifier.STATIC);
}

public static boolean isSynchronized(PsiModifierListOwner unit) {
return unit.hasModifierProperty(PsiModifier.SYNCHRONIZED);
}

public static boolean isOverriding(PsiMethod method) {
return method.findSuperMethods().length != 0;
}

public static boolean isPrivate(PsiModifierListOwner unit) {
return unit.hasModifierProperty(PsiModifier.PRIVATE);
}
Expand Down Expand Up @@ -223,8 +232,24 @@ private static boolean hasField(@NotNull final PsiClass aClass,
return false;
}

public static boolean isOverriding(PsiMethod method) {
return method.findSuperMethods().length != 0;
public static boolean isPublic(PsiMethod method) {
if (method.hasModifierProperty(PsiModifier.PUBLIC)) {
return true;
}

PsiClass containingClass = method.getContainingClass();

return containingClass != null && containingClass.isInterface();
}

public static String extractMethodDeclaration(final @NotNull PsiMethod method) {
String code = method.getText();

code = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL).matcher(code).replaceAll("");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

можно тут хотя бы комменты добавить про эти регэкспы?

code = Pattern.compile("//.*?$", Pattern.DOTALL | Pattern.MULTILINE).matcher(code).replaceAll("");

code = Pattern.compile("\\{.*}", Pattern.DOTALL).matcher(code).replaceAll("");
return code.trim();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.sixrr.metrics.utils;

import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;

public class ProjectUtils {
private ProjectUtils() {
}

@Nullable
public static Project loadProjectWithAllDependencies(Path projectPath) {
for (Project openedProject : ProjectManager.getInstance().getOpenProjects()) {
if (!ProjectManager.getInstance().closeProject(openedProject)) {
throw new IllegalStateException("Cannot close previous project");
}
Disposer.dispose(openedProject);
if (!openedProject.isDisposed()) {
throw new IllegalStateException("Cannot dispose project");
}
}
final Project project = ProjectUtil.openOrImport(projectPath.toAbsolutePath().toString(),
null, false);
return project == null ||
ProjectRootManager.getInstance(project).getProjectSdk() == null ||
!project.isInitialized() ?
null : project;
}
}
12 changes: 12 additions & 0 deletions algorithms-evaluation/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
repositories {
mavenCentral()
}

dependencies {
compile project(':core')
compile project(':features-extraction')
// compile project(':utils')

// testCompile project(':utils').sourceSets.test.output
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.1'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.jetbrains.research.groups.ml_methods.evaluation;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.research.groups.ml_methods.algorithm.Algorithm;

import java.util.EnumMap;
import java.util.function.Supplier;

import static java.lang.Math.pow;

public abstract class AbstractEvaluationResult implements EvaluationResult {
private final @NotNull EnumMap<Evaluation, Supplier<Double>> evaluationFunctions =
new EnumMap<>(Evaluation.class);
private final @NotNull Algorithm evaluatingAlgorithm;

{
evaluationFunctions.put(Evaluation.GOOD_PRECISION, this::getGoodPrecision);
evaluationFunctions.put(Evaluation.GOOD_RECALL, this::getGoodRecall);
evaluationFunctions.put(Evaluation.BAD_PRECISION, this::getBadPrecision);
evaluationFunctions.put(Evaluation.BAD_RECALL, this::getBadRecall);
evaluationFunctions.put(Evaluation.MSE, this::getMSE);
evaluationFunctions.put(Evaluation.ME, this::getME);
}

AbstractEvaluationResult(@NotNull Algorithm evaluatingAlgorithm) {
this.evaluatingAlgorithm = evaluatingAlgorithm;
}

@Override
public Algorithm getAlgorithm() {
return evaluatingAlgorithm;
}

@Override
public double getGoodPrecision() {
return (double) getNumberOfFoundGood() / getNumberOfFoundBadAndGood();
}

@Override
public double getGoodRecall() {
return (double) getNumberOfFoundGood() / getNumberOfGood();
}

@Override
public double getBadPrecision() {
return (double) (getNumberOfBad() - getNumberOfFoundBad()) / (getNumberOfBadAndGood() - getNumberOfFoundBadAndGood());
}

@Override
public double getBadRecall() {
return (double) (getNumberOfBad() - getNumberOfFoundBad()) / getNumberOfBad();
}

@Override
public double getMSE() {
return getErrors().stream().mapToDouble(Double::doubleValue).map(operand -> pow(operand, 2)).sum() / getErrors().size();
}

@Override
public double getME() {
return getErrors().stream().mapToDouble(Double::doubleValue).sum() / getErrors().size();
}

private int getNumberOfBadAndGood() {
return getNumberOfBad() + getNumberOfGood();
}

private int getNumberOfFoundBadAndGood() {
return getNumberOfFoundBad() + getNumberOfFoundGood();
}

@Override
public Supplier<Double> getEvaluation(Evaluation evaluation) {
return evaluationFunctions.get(evaluation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.jetbrains.research.groups.ml_methods.evaluation;

import com.intellij.analysis.AnalysisScope;
import com.intellij.openapi.project.Project;
import com.sixrr.metrics.profile.MetricsProfile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.research.groups.ml_methods.algorithm.Algorithm;
import org.jetbrains.research.groups.ml_methods.refactoring.CalculatedRefactoring;
import org.jetbrains.research.groups.ml_methods.refactoring.MoveToClassRefactoring;
import org.jetbrains.research.groups.ml_methods.algorithm.RefactoringExecutionContext;
import org.jetbrains.research.groups.ml_methods.utils.MetricsProfilesUtil;

import java.util.Collections;
import java.util.List;

public class AlgorithmEvaluator {
@NotNull
static EvaluationResult evaluate(@NotNull AnalysisScope scope, @NotNull Algorithm algorithm,
@NotNull List<MoveToClassRefactoring> good, @NotNull List<MoveToClassRefactoring> bad) {
MetricsProfile profile =
MetricsProfilesUtil.createProfile("evaluation_profile", algorithm.requiredMetrics());
RefactoringExecutionContext context = new RefactoringExecutionContext(scope.getProject(), scope, profile,
Collections.singletonList(algorithm), false, null);

context.executeSynchronously();

List<CalculatedRefactoring> foundRefactorings = context.getAlgorithmResults().get(0).getRefactorings();
return new ProjectEvaluationResult(foundRefactorings, good, bad, algorithm);
}

@NotNull
static EvaluationResult evaluate(@NotNull Project project, @NotNull Algorithm algorithm,
@NotNull List<MoveToClassRefactoring> good, @NotNull List<MoveToClassRefactoring> bad) {
return evaluate(new AnalysisScope(project), algorithm, good, bad);
}

@NotNull
static EvaluationResult evaluate(@NotNull ProjectToEvaluate projectToEvaluate,
@NotNull Algorithm algorithm) {
return evaluate(projectToEvaluate.getProject(),
algorithm,
projectToEvaluate.getGoodRefactorings(),
projectToEvaluate.getBadRefactorings());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.jetbrains.research.groups.ml_methods.evaluation;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationStarter;
import com.intellij.openapi.application.ex.ApplicationEx;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.research.groups.ml_methods.algorithm.Algorithm;
import org.jetbrains.research.groups.ml_methods.algorithm.AlgorithmsRepository;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


public class AlgorithmsEvaluationApplicationStarter implements ApplicationStarter {
private static final ApplicationEx APPLICATION = (ApplicationEx) ApplicationManager.getApplication();
private static final int NUMBER_OF_ARGUMENTS = 4;
private static final @NotNull Logger LOGGER =
Logger.getLogger(AlgorithmsEvaluationApplicationStarter.class);

static {
LOGGER.setLevel(Level.INFO);
LOGGER.addAppender(new ConsoleAppender(new PatternLayout("%p %m%n")));
}

private static void checkCommandLineArguments(@NotNull String[] args) {
if (args.length != NUMBER_OF_ARGUMENTS) {
printUsage();
APPLICATION.exit(true, true);
}
}

private static void printUsage() {
System.out.println("Usage: algorithms-evaluation <path to dataset folder> <algorithms names> <pathToSaveResults>");
}

@Override
public String getCommandName() {
return "algorithms-evaluation";
}

@Override
public void premain(String[] args) {
}

public void main(String[] args) {
try {
checkCommandLineArguments(args);
Path datasetPath = Paths.get(args[1]);
List<String> algorithmsNames = Arrays.asList(args[2].split(","));
Path pathToSaveResults = Paths.get(args[3]);
List<Algorithm> algorithmsToEvaluate;
if (algorithmsNames.get(0).equals("")) {
algorithmsToEvaluate = AlgorithmsRepository.getAvailableAlgorithms();
} else {
algorithmsToEvaluate = algorithmsNames.stream()
.map(algorithmName -> AlgorithmsRepository.getAlgorithmByName(algorithmName)
.orElseThrow(() -> new IllegalArgumentException("No such algorithm")))
.collect(Collectors.toList());
}
List<EvaluationResult> evaluationResults = new ArrayList<>();
for (Algorithm algorithm : algorithmsToEvaluate) {
evaluationResults.add(JBAlgorithmEvaluator.evaluateDataset(datasetPath, algorithm));
}
evaluationResults.forEach(this::printEvaluationResult);
if (!pathToSaveResults.toString().equals("")) {
EvaluationResultsWriter.writeTable(evaluationResults, pathToSaveResults);
}
} catch (Throwable throwable) {
System.out.println(throwable.getClass().getSimpleName() + ": " + throwable.getMessage());
throwable.printStackTrace();
} finally {
APPLICATION.exit(true, true);
}
}

private void printEvaluationResult(EvaluationResult evaluationResult) {
System.out.println("==================");
System.out.println("EVALUATION RESULT FOR " + evaluationResult.getAlgorithm().getDescriptionString());
System.out.println("Number of good: " + evaluationResult.getNumberOfGood());
System.out.println("Number of found good: " + evaluationResult.getNumberOfFoundGood());
System.out.println("Number of bad: " + evaluationResult.getNumberOfBad());
System.out.println("Number of found bad: " + evaluationResult.getNumberOfFoundBad());
System.out.println("Number of found others: " + evaluationResult.getNumberOfFoundOthers());
System.out.println("Good precision: " + evaluationResult.getGoodPrecision());
System.out.println("Bad precision: " + evaluationResult.getBadPrecision());
System.out.println("Good recall: " + evaluationResult.getGoodRecall());
System.out.println("Bad recall: " + evaluationResult.getBadRecall());
System.out.println("Mean squared error (MSE): " + evaluationResult.getMSE());
System.out.println("Mean error (ME): " + evaluationResult.getME());
}
}
Loading