def setUp(self): super().setUp() self.statistics_configuration = ClassicalStatisticsConfiguration.default() self.service_creator = CykService self.statistics = GrammarStatistics.default(self.randomizer, self.statistics_configuration) self.empty_rule_population = self.create_rules([]) self.example_rule_population = self.create_rules([ Rule(Symbol('S'), Symbol('A'), Symbol('B')), Rule(Symbol('S'), Symbol('A'), Symbol('C')), Rule(Symbol('C'), Symbol('S'), Symbol('B')), Rule(Symbol('B'), Symbol('B'), Symbol('B')) ]) self.random_rules = self.create_rules([ Rule(Symbol('S'), Symbol('NP'), Symbol('VP')), Rule(Symbol('VP'), Symbol('VP'), Symbol('PP')), Rule(Symbol('VP'), Symbol('V'), Symbol('NP')), Rule(Symbol('PP'), Symbol('P'), Symbol('NP')), Rule(Symbol('NP'), Symbol('Det'), Symbol('N')), Rule(Symbol('S'), Symbol('A'), Symbol('B')), Rule(Symbol('S'), Symbol('A'), Symbol('C')), Rule(Symbol('C'), Symbol('S'), Symbol('B')), Rule(Symbol('B'), Symbol('B'), Symbol('B')) ])
def setUp(self): super().setUp() self.statistics_configuration = None self.statistics = GrammarStatistics.sgcs_variant( self.randomizer, self.statistics_configuration) self.service_creator = StochasticCykService self.empty_rule_population = self.create_rules([]) self.example_rule_population = self.create_rules([ Rule(Symbol('S'), Symbol('A'), Symbol('B')), Rule(Symbol('S'), Symbol('A'), Symbol('C')), Rule(Symbol('C'), Symbol('S'), Symbol('B')), Rule(Symbol('B'), Symbol('B'), Symbol('B')) ]) self.random_rules = self.create_rules([ Rule(Symbol('S'), Symbol('NP'), Symbol('VP')), Rule(Symbol('VP'), Symbol('VP'), Symbol('PP')), Rule(Symbol('VP'), Symbol('V'), Symbol('NP')), Rule(Symbol('PP'), Symbol('P'), Symbol('NP')), Rule(Symbol('NP'), Symbol('Det'), Symbol('N')), Rule(Symbol('S'), Symbol('A'), Symbol('B')), Rule(Symbol('S'), Symbol('A'), Symbol('C')), Rule(Symbol('C'), Symbol('S'), Symbol('B')), Rule(Symbol('B'), Symbol('B'), Symbol('B')) ])
def create_grammar_statistics(self): configuration = ClassicalStatisticsConfiguration.default() configuration.base_fitness = 5 configuration.classical_fitness_weight = 1 configuration.fertility_weight = 1 configuration.positive_weight = 1 configuration.negative_weight = 1 self.grammar_statistics = GrammarStatistics( configuration, self.randomizer, ClassicRuleStatistics(), ClassicFitness())
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.rule_statistics_mock = create_autospec(PasiekaRuleStatistics) self.empty_statistics_visitor = [] self.fitness = create_autospec(Fitness) self.randomizer_mock = create_autospec(Randomizer) self.sut = GrammarStatistics(ClassicalStatisticsConfiguration.default(), self.randomizer_mock, self.rule_statistics_mock, self.fitness) self.sut.statistics_visitors = [] self.rule = Rule(Symbol(hash('A')), Symbol(hash('B')), Symbol(hash('C')))
class TestGrammarStatistics(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.rule_statistics_mock = create_autospec(PasiekaRuleStatistics) self.empty_statistics_visitor = [] self.fitness = create_autospec(Fitness) self.randomizer_mock = create_autospec(Randomizer) self.sut = GrammarStatistics(ClassicalStatisticsConfiguration.default(), self.randomizer_mock, self.rule_statistics_mock, self.fitness) self.sut.statistics_visitors = [] self.rule = Rule(Symbol(hash('A')), Symbol(hash('B')), Symbol(hash('C'))) def test_should_be_able_to_get_rule_statistics(self): self.rule_statistics_mock.get_rule_statistics.return_value = 44 assert_that(self.sut.get_rule_statistics(self.rule), is_(equal_to(44))) def test_should_be_able_to_add_new_rule(self): self.sut.on_added_new_rule(self.rule) self.rule_statistics_mock.added_new_rule.assert_called_once_with( self.rule, self.sut) def test_should_be_able_to_add_rule_usage(self): self.rule_statistics_mock.has_rule.return_value = True self.sut.on_rule_usage(self.rule, None) self.rule_statistics_mock.rule_used.assert_called_once_with( self.rule, None, self.sut) def test_if_rule_does_not_exist_its_usage_should_be_ignored(self): self.rule_statistics_mock.has_rule.return_value = False self.sut.on_rule_usage(self.rule, None) assert_that(not self.rule_statistics_mock.rule_used.called) def test_should_be_able_to_remove_rule(self): self.sut.on_rule_removed(self.rule) self.rule_statistics_mock.removed_rule.assert_called_once_with( self.rule, self.sut)
def create_grammar_statistics(self, randomizer, statistics_configuration): if not statistics_configuration.negative_sentence_learning: return GrammarStatistics.sgcs_variant(randomizer, statistics_configuration) else: return GrammarStatistics.default(randomizer, statistics_configuration)
class TestEvolution(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.randomizer = Randomizer(Random()) selector_configuration = [ EvolutionRandomSelectorConfiguration.create(), EvolutionRouletteSelectorConfiguration.create() ] self.configuration = EvolutionConfiguration.create( selector_configuration, inversion_chance=0, mutation_chance=0, crossover_chance=0) self.create_rule_population() self.create_grammar_statistics() self.create_rule_adding() self.sut = EvolutionService(self.randomizer) self.rules = [ Rule(Symbol('S'), Symbol('NP'), Symbol('VP')), Rule(Symbol('VP'), Symbol('VP'), Symbol('PP')), Rule(Symbol('VP'), Symbol('V'), Symbol('NP')), TerminalRule(Symbol('VP'), Symbol('eats')), Rule(Symbol('PP'), Symbol('P'), Symbol('NP')), Rule(Symbol('NP'), Symbol('Det'), Symbol('N')), TerminalRule(Symbol('NP'), Symbol('she')), TerminalRule(Symbol('V'), Symbol('eats')), TerminalRule(Symbol('P'), Symbol('with')), TerminalRule(Symbol('N'), Symbol('fish')), TerminalRule(Symbol('N'), Symbol('fork')), TerminalRule(Symbol('Det'), Symbol('a')) ] def create_rule_population(self): self.starting_symbol = Symbol('S') self.rule_population = RulePopulation(self.starting_symbol) def create_grammar_statistics(self): configuration = ClassicalStatisticsConfiguration.default() configuration.base_fitness = 5 configuration.classical_fitness_weight = 1 configuration.fertility_weight = 1 configuration.positive_weight = 1 configuration.negative_weight = 1 self.grammar_statistics = GrammarStatistics( configuration, self.randomizer, ClassicRuleStatistics(), ClassicFitness()) def create_rule_adding(self): configuration = AddingRulesConfiguration.create( crowding_factor=2, crowding_size=3, elitism_size=2, max_non_terminal_rules=19 ) adding_strategies = [SimpleAddingRuleStrategy(), AddingRuleWithCrowdingStrategy(), AddingRuleWithElitismStrategy()] self.rule_adding = AddingRuleSupervisor(self.randomizer, configuration, adding_strategies) def simulate_induction_part_work(self, rules): for rule in rules: self.rule_adding.add_rule(rule, self.rule_population, self.grammar_statistics) for rule in rules: rule_usage_info = ClassicRuleUsageInfo(True, 1) positive_usages = self.randomizer.randint(1, 4) for _ in range(positive_usages): self.grammar_statistics.on_rule_usage(rule, rule_usage_info) rule_usage_info.positive_sentence = False self.grammar_statistics.on_rule_usage(rule, rule_usage_info) self.grammar_statistics.fitness.get(self.grammar_statistics, rule) def get_symbols_from_rules(self, rules): return {y for y in chain.from_iterable( (x.parent, x.left_child, x.right_child) for x in rules)} def assert_contains_rules(self, rules, rules_pool): for rule in rules: assert_that(rules_pool, has_item(rule)) def count_rules_that_has_changed(self, old): changed_rules = 0 for rule in self.rule_population.get_all_non_terminal_rules(): changed_rules += 1 if rule not in old else 0 return changed_rules def test_given_no_operator_used_rule_population_should_remain_unchanged(self): # Given: self.simulate_induction_part_work(self.rules) old_population = copy.deepcopy(self.rule_population) # When: self.sut.run_genetic_algorithm(self.grammar_statistics, self.rule_population, self.rule_adding, self.configuration) # Then: self.assert_contains_rules(self.rule_population.get_all_non_terminal_rules(), list(old_population.get_all_non_terminal_rules())) old_symbols = self.get_symbols_from_rules(old_population.get_all_non_terminal_rules()) new_symbols = self.get_symbols_from_rules(self.rule_population.get_all_non_terminal_rules()) assert_that(old_symbols, has_items(*new_symbols)) def promote_those_rules_to_elite(self, rules): for rule in rules: rule_usage_info = ClassicRuleUsageInfo(True, 1) positive_usages = 5 for _ in range(positive_usages): self.grammar_statistics.on_rule_usage(rule, rule_usage_info) def test_given_high_operator_usage_rule_population_should_expect_some_major_change(self): # Given: self.configuration.operators.inversion.chance = 1 self.configuration.operators.mutation.chance = 1 self.configuration.operators.crossover.chance = 1 self.simulate_induction_part_work(self.rules) self.promote_those_rules_to_elite(self.rules[0:2]) elite = list(self.rules[0:2]) old_population = copy.deepcopy(self.rule_population) # When: self.sut.run_genetic_algorithm(self.grammar_statistics, self.rule_population, self.rule_adding, self.configuration) # Then: self.assert_contains_rules(elite, list(old_population.get_all_non_terminal_rules())) assert_that(self.count_rules_that_has_changed(old_population.get_all_non_terminal_rules()), is_(greater_than_or_equal_to(2))) old_symbols = self.get_symbols_from_rules(old_population.get_all_non_terminal_rules()) new_symbols = self.get_symbols_from_rules(self.rule_population.get_all_non_terminal_rules()) assert_that(old_symbols, not_(has_items(*new_symbols)))