-
Notifications
You must be signed in to change notification settings - Fork 0
/
CandidateSolution.py
86 lines (76 loc) · 3.33 KB
/
CandidateSolution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Copyright 2014 James Strassburg
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import math
from SearchParameter import SearchParameter
from SolrRepository import SolrRepository
class CandidateSolution:
size = 8
def __init__(self, bits=None):
if bits is None:
self.name_boost = SearchParameter()
self.description_boost = SearchParameter()
else:
self.decode(bits)
def decode(self, bits):
"""
decodes a list of bits into this instance
:param bits: A list of 0/1 to be sliced into the individual parameters
"""
self.name_boost = SearchParameter(tuple(bits[0:4]))
self.description_boost = SearchParameter(tuple(bits[4:8]))
@staticmethod
def evaluate(bits):
"""
Calculates an average of the F-Measure for every query that has recorded interactions
"""
candidate = CandidateSolution(bits)
f_measures = []
#for query in SolrRepository.interactive_queries():
for query in ["red lobster"]:
results = SolrRepository.search(query, candidate.name_boost.value, candidate.description_boost.value)
precision = CandidateSolution.calculate_precision(query, results)
recall = CandidateSolution.calculate_recall(query, results)
f_measures.append(CandidateSolution.f_measure(precision, recall))
return sum(f_measures) / len(f_measures),
@staticmethod
def f_measure(precision, recall):
if (precision + recall) == 0:
return 0
return 2.0 * float(precision * recall) / float(precision + recall)
@staticmethod
def calculate_precision(query, results):
total_results = float(results.numFound)
return CandidateSolution.discounted_correct_matches(query, results) / total_results
@staticmethod
def calculate_recall(query, results):
correct_matches = CandidateSolution.discounted_correct_matches(query, results)
total_matches = float(SolrRepository.total_matches(query))
missed_matches = total_matches - correct_matches
return correct_matches / (correct_matches + missed_matches)
@staticmethod
def correct_matches(query, results):
correct_matches = 0.
for result in results:
if query in result["searchTermInteractions"]:
correct_matches += 1.
return correct_matches
@staticmethod
def discounted_correct_matches(query, results):
discounted_correct_matches = 0.
position = 2 # start at 2 because / math.log(2) will boost for the first result and discount following results
for result in results:
if query in result["searchTermInteractions"]:
discounted_correct_matches += 1. / math.log(position)
position += 1
return discounted_correct_matches