comprehensive_score.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import json
  2. from fuzzywuzzy import fuzz
  3. class Comprehensive_Score():
  4. def __init__(self, dev_mode):
  5. with open("model_data/keyword_mapping.json", 'r', encoding="utf8") as f:
  6. keyword_mapping = json.load(f)
  7. # 根据ksy和fxb判断值的次方
  8. self.power = 2 if dev_mode == "ksy" else 1
  9. self.knowledge2id = keyword_mapping["knowledge2id"]
  10. self.quantity2id = keyword_mapping["quantity2id"]
  11. self.init_id2max_id = keyword_mapping["init_id2max_id"]
  12. def __call__(self, query, refer, scale):
  13. score_dict = dict()
  14. quesType = self.compute_quesType(query["quesType"], refer["quesType"]["quesType"])
  15. knowledge = self.compute_knowledge(query["knowledge"], refer["knowledge"])
  16. solving_type = self.compute_solving_type(query["solving_type"], refer["solving_type"])
  17. difficulty = self.compute_difficulty(query["difficulty"], refer["difficulty"])
  18. physical_quantity = self.compute_physical_quantity(query["physical_quantity"], refer["physical_quantity"])
  19. # image_semantics = self.compute_image_semantics(query["image_semantics"], refer["image_semantics"])
  20. sum_score = quesType * scale["quesType"] + knowledge * scale["knowledge"] + \
  21. solving_type * scale["solving_type"] + difficulty * scale["difficulty"] + \
  22. physical_quantity * scale["physical_quantity"]
  23. sum_score = int(sum_score * 100) / 100
  24. sum_score = min(sum_score, 1.0)
  25. score_dict["quesType"] = quesType
  26. score_dict["knowledge"] = knowledge
  27. score_dict["solving_type"] = solving_type
  28. score_dict["difficulty"] = difficulty
  29. score_dict["physical_quantity"] = physical_quantity
  30. # score_dict["image_semantics"] = image_semantics
  31. return sum_score, score_dict
  32. # 知识点/物理场景/物理量相互关联得分计算
  33. def compute_relate_score(self, query_list, refer_list, keyword2id, mode):
  34. query_set, refer_set = set(query_list), set(refer_list)
  35. if query_set == refer_set:
  36. return 1.0
  37. if len(query_set) > len(refer_set):
  38. query_set, refer_set = refer_set, query_set
  39. accumulate_score = 0
  40. max_length = len(refer_set)
  41. # 双层循环计算知识点之间关联得分
  42. for query in query_set:
  43. query_score = 0
  44. query_id = keyword2id.get(query, 0)
  45. for refer in refer_set:
  46. refer_id = keyword2id.get(refer, 0)
  47. if query_id == refer_id:
  48. query_score += 1
  49. continue
  50. # 知识点
  51. if mode == 1:
  52. if abs(query_id - refer_id) < 10 ** self.power: query_score += 0.3
  53. elif abs(query_id - refer_id) < 100 ** self.power: query_score += 0.2
  54. else: continue
  55. elif mode == 2:
  56. if abs(query_id - refer_id) < 100: query_score += 0.2
  57. else: continue
  58. fuzz_score = fuzz.ratio(query, refer)
  59. if fuzz_score >= 0.4:
  60. query_score += 0.1
  61. # refer长度为1特殊处理
  62. if max_length == 1:
  63. return query_score
  64. # 限定关联得分上限
  65. max_score = 1 / max_length + 1 if query in refer_set else (max_length - 1) / max_length
  66. if query_score > max_score:
  67. accumulate_score += max_score
  68. else:
  69. accumulate_score += query_score
  70. return min(accumulate_score / max_length, 0.85)
  71. # 题型相似度评分
  72. def compute_quesType(self, query, refer):
  73. score = 0.0
  74. if query == refer:
  75. score = 1.0
  76. return score
  77. # 知识点相似度评分
  78. def compute_knowledge(self, query_list, refer_list):
  79. score = self.compute_relate_score(query_list, refer_list, self.knowledge2id, mode=1)
  80. return int(score * 100) / 100
  81. # 试题求解类型相似度评分
  82. def compute_solving_type(self, query_list, refer_list):
  83. query_set, refer_set = set(query_list), set(refer_list)
  84. if len(query_set) > len(refer_set):
  85. query_set, refer_set = refer_set, query_set
  86. same_count = sum([1 for ele in query_set if ele in refer_set])
  87. score = same_count / len(refer_set)
  88. return int(score * 100) / 100
  89. # 难度相似度评分
  90. def compute_difficulty(self, query, refer):
  91. score = 1 - abs(float(query) - float(refer))
  92. return int(score * 100) / 100
  93. # 物理量相似度评分
  94. def compute_physical_quantity(self, query_list, refer_list):
  95. score = self.compute_relate_score(query_list, refer_list, self.quantity2id, mode=2)
  96. return int(score * 100) / 100
  97. # # 图片语义相似度评分
  98. # def compute_image_semantics(self, query_list, refer_list):
  99. # query_set, refer_set = set(query_list), set(refer_list)
  100. # if len(query_set) == 0 and len(refer_set) == 0:
  101. # return 1
  102. # elif len(query_set) == 0 or len(refer_set) == 0:
  103. # return 0
  104. # elif len(query_set) > len(refer_set):
  105. # query_set, refer_set = refer_set, query_set
  106. # same_count = sum([1 for ele in query_set if ele in refer_set])
  107. # score = same_count / len(refer_set)
  108. # return int(score * 100) / 100