Repository navigation
Expand file tree
/
Copy pathClusterGrader.py
More file actions
114 lines (95 loc) · 3.4 KB
/
Copy pathClusterGrader.py
File metadata and controls
114 lines (95 loc) · 3.4 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import Orange
# ****************** CONFIGURATIONS ******************
# ending image names
obverse_coin = "o.jpg"
reverse_coin = "r.jpg"
# thresholds for quality (everything below medium is "bad")
good = 0.85
medium = 0.65
# creating a dict with Cluster number as key and image_file names (list) as value
data_dict = {}
for data in in_data:
key = str(data["Cluster"])
value = str(data["name"])
data_dict.setdefault(key, []).append(value)
# counting the amount of front-/rear-view images and putting it into a dict
cluster_view_amount_dict = {
key: {
"front": sum(img.endswith(obverse_coin) for img in cluster),
"back": sum(img.endswith(reverse_coin) for img in cluster),
}
for key, cluster in data_dict.items()
}
# debug log for the amount of front & rear-view images per cluster
# print(cluster_view_amount_dict)
# new dictionaty that applies quality function on every cluster:
# The key is the cluster label, and the value is the cluster’s quality.
# For each cluster:
# n = number of front-view images
# m = number of back-view images
# The quality is calculated as:
# quality = max(n, m) / (n + m)
# This measures how homogeneous the cluster is. A value close to 1 means the cluster
# contains mostly one type (front or back), while values near 0.5 indicate a mixed or less pure cluster.
quality_dict = {
key: (max(value["front"], value["back"]) /
sum((value["front"], value["back"])))
for key, value in cluster_view_amount_dict.items()
}
# debug log for the quality of each cluster
# print(quality_dict)
# Calculate the total clustering quality as a weighted average of all cluster qualities.
# Each cluster's quality score (quality_dict[key]) is multiplied by its size (number of images in that cluster),
# so larger clusters have more influence on the final result.
# The sum of all weighted qualities is then divided by the total number of images across all clusters.
# Mathematically: Q_global = Σ(q_i * n_i) / Σ(n_i)
# where q_i = purity of cluster i, and n_i = number of items in cluster i.
total_images = len(in_data)
global_quality = (
sum(
quality_dict[key] * (value["front"] + value["back"])
for key, value in cluster_view_amount_dict.items()
)
/ total_images
)
# debug log for the total quality of all selected clusters
# print(global_quality)
# defining columns
columns = Orange.data.Domain(
[
Orange.data.ContinuousVariable("Front"),
Orange.data.ContinuousVariable("Back"),
Orange.data.ContinuousVariable("Total"),
Orange.data.ContinuousVariable("Quality"),
Orange.data.ContinuousVariable("Total-Quality"),
],
metas=[
Orange.data.StringVariable("Cluster"),
Orange.data.StringVariable("Quality-Status"),
],
)
# funktion that takes the quality and returns a string in traffic-light style
def check_quality(quality):
if quality >= good:
return "🟢 high"
if quality < good and quality >= medium:
return "🟡 medium"
else:
return "🔴 low"
# defining rows
rows = [
[
value["front"],
value["back"],
value["front"] + value["back"],
quality_dict[key],
global_quality,
key,
check_quality(quality_dict[key]),
]
for key, value in cluster_view_amount_dict.items()
]
# debug log for the rows of the table
# print(rows)
table = Orange.data.Table(columns, rows)
out_data = table