m2c.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import re
  2. class Model:
  3. def __init__(self, features: "int"):
  4. assert features > 0, f"features = {self._kv['gama']} should bigger than zero."
  5. self._kv: "dict" = {
  6. "size": 0, "bias": 0, "gama": 0, "feat": features,
  7. "scales": [], "elements": [], "weights": []
  8. }
  9. self._m = {}
  10. def __dict__(self):
  11. return self._kv
  12. def __getitem__(self, key: "str"):
  13. return getattr(self._kv, key, None)
  14. def _v2s(self) -> "None":
  15. assert self._kv["size"] > 0, f"total_sv = {self._kv['size']} should bigger than zero."
  16. assert self._kv["bias"] > 0, f"rho = {self._kv['bias']} should bigger than zero."
  17. assert self._kv["gama"] > 0, f"gamma = {self._kv['gama']} should bigger than zero."
  18. assert len(self._kv["scales"]) == self._kv["size"], \
  19. f"scales_count={len(self._kv['scales'])} should equal to total_sv={self._kv['size']}."
  20. assert len(self._kv["elements"]) > 0, f"weights count = {self._kv['elements']} should bigger than zero."
  21. assert sum(self._kv["elements"]) == len(self._kv["weights"]), \
  22. f"ele_sum={sum(self._kv['elements'])} should equal to weights_count={len(self._kv['weights'])}"
  23. self._m["@{size}"] = f"{self._kv['size']}"
  24. self._m["@{feat}"] = f"{self._kv['feat']}"
  25. self._m["@{bias}"] = f"{self._kv['bias']}f"
  26. self._m["@{gama}"] = f"{self._kv['gama']}f"
  27. self._m["@{scales}"] = f"{self._kv['scales'][0]}f"
  28. for num in self._kv["scales"]:
  29. self._m["@{scales}"] += f",{num}f"
  30. self._m["@{elements}"] = f"{self._kv['elements'][0]}"
  31. for num in self._kv["elements"]:
  32. self._m["@{elements}"] += f",{num}"
  33. self._m["@{weights}"] = f"{self._kv['weights'][0]}f"
  34. for num in self._kv["weights"]:
  35. self._m["@{weights}"] += f",{num}f"
  36. def load(self, path: "str" = "test.model") -> "Model":
  37. with open(path) as fp:
  38. lines = fp.read().strip().split("\n")
  39. assert lines[0] == "svm_type one_class", "svm_type first line and one class svm only"
  40. assert lines[1] == "kernel_type rbf", "kernel_type second line and rbf only"
  41. self._kv["gama"] = float(lines[2][6:])
  42. self._kv["size"] = int(lines[4][9:])
  43. self._kv["bias"] = float(lines[5][4:])
  44. for ws in lines[7:]:
  45. nums = ws.strip().split(" ")
  46. self._kv["scales"].append(float(nums[0]))
  47. self._kv["elements"].append(len(nums) - 1)
  48. self._kv["weights"] += [float(one.split(":")[1]) for one in nums[1:]]
  49. self._v2s()
  50. return self
  51. def toc(self, file: "str" = "svm.c") -> "None":
  52. newLines = []
  53. with open("./svm.c.t") as fp:
  54. lines = fp.readlines()
  55. pattern = re.compile(r"@{\w+}")
  56. for line in lines:
  57. keys = pattern.findall(line)
  58. for key in keys:
  59. if key in self._m:
  60. line = line.replace(key, self._m[key])
  61. else:
  62. print(f"\"{key}\" not in model map")
  63. newLines.append(line)
  64. with open(file, "wt") as tp:
  65. tp.writelines(newLines)
  66. print(f"file written to {file}")
  67. if __name__ == "__main__":
  68. model = Model(23)
  69. model.load("real.model").toc()