datapruning 2.1.0__tar.gz → 2.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {datapruning-2.1.0/datapruning.egg-info → datapruning-2.1.2}/PKG-INFO +5 -3
  2. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/base.py +13 -1
  3. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/el2n_scorer.py +5 -6
  4. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/fusion_pipeline.py +5 -7
  5. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/kcenter_select.py +5 -7
  6. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/margin_scorer.py +5 -6
  7. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/sliding_window.py +5 -6
  8. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/strategy_display.py +16 -16
  9. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/difficulty.py +6 -0
  10. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/pipeline.py +2 -0
  11. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/selection.py +26 -21
  12. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/sdk.py +1 -1
  13. {datapruning-2.1.0 → datapruning-2.1.2/datapruning.egg-info}/PKG-INFO +5 -3
  14. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning.egg-info/requires.txt +4 -1
  15. {datapruning-2.1.0 → datapruning-2.1.2}/pyproject.toml +6 -3
  16. {datapruning-2.1.0 → datapruning-2.1.2}/LICENSE +0 -0
  17. {datapruning-2.1.0 → datapruning-2.1.2}/MANIFEST.in +0 -0
  18. {datapruning-2.1.0 → datapruning-2.1.2}/README.md +0 -0
  19. {datapruning-2.1.0 → datapruning-2.1.2}/build_src/_core.c +0 -0
  20. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/__init__.py +0 -0
  21. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/__init__.py +0 -0
  22. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/algorithms/registry.py +0 -0
  23. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/__init__.py +0 -0
  24. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/benchmark.py +0 -0
  25. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/explainability.py +0 -0
  26. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/intelligence.py +0 -0
  27. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/optimizer.py +0 -0
  28. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/scanner.py +0 -0
  29. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/engine/strategy_selector.py +0 -0
  30. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/multimodal/__init__.py +0 -0
  31. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/multimodal/clip_encoder.py +0 -0
  32. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/pipeline.py +0 -0
  33. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/reports/__init__.py +0 -0
  34. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/reports/exporter.py +0 -0
  35. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/__init__.py +0 -0
  36. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/benchmark/__init__.py +0 -0
  37. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/benchmark/compare.py +0 -0
  38. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/benchmark/evaluation.py +0 -0
  39. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/benchmark/synthetic.py +0 -0
  40. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/embeddings/__init__.py +0 -0
  41. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/embeddings/torch_utils.py +0 -0
  42. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/fusion.py +0 -0
  43. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/noise.py +0 -0
  44. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/normalize.py +0 -0
  45. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/redundancy.py +0 -0
  46. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/__init__.py +0 -0
  47. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/aum.py +0 -0
  48. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/el2n.py +0 -0
  49. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/forgetting.py +0 -0
  50. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/grand.py +0 -0
  51. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/scores/margin.py +0 -0
  52. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/selectors/__init__.py +0 -0
  53. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/selectors/facility_location.py +0 -0
  54. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/selectors/kcenter.py +0 -0
  55. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/selectors/out_of_fold.py +0 -0
  56. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning/research_pruning/strategy.py +0 -0
  57. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning.egg-info/SOURCES.txt +0 -0
  58. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning.egg-info/dependency_links.txt +0 -0
  59. {datapruning-2.1.0 → datapruning-2.1.2}/datapruning.egg-info/top_level.txt +0 -0
  60. {datapruning-2.1.0 → datapruning-2.1.2}/setup.cfg +0 -0
  61. {datapruning-2.1.0 → datapruning-2.1.2}/setup.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datapruning
3
- Version: 2.1.0
4
- Summary: Intelligent data pruning for ML datasets
3
+ Version: 2.1.2
4
+ Summary: Intelligent dataset optimization for cleaner, smaller training data
5
5
  License: Proprietary
6
6
  Project-URL: Homepage, https://www.datapruning.com
7
7
  Classifier: Development Status :: 4 - Beta
@@ -20,8 +20,10 @@ License-File: LICENSE
20
20
  Requires-Dist: numpy>=1.24.0
21
21
  Requires-Dist: pandas>=2.0.0
22
22
  Requires-Dist: scikit-learn>=1.3.0
23
- Requires-Dist: torch>=2.0.0
23
+ Provides-Extra: torch
24
+ Requires-Dist: torch>=2.0.0; extra == "torch"
24
25
  Provides-Extra: clip
26
+ Requires-Dist: torch>=2.0.0; extra == "clip"
25
27
  Requires-Dist: transformers>=4.30.0; extra == "clip"
26
28
  Requires-Dist: pillow>=9.0.0; extra == "clip"
27
29
  Dynamic: license-file
@@ -47,7 +47,19 @@ class BaseOptimizer(ABC):
47
47
 
48
48
  def optimize(self, df: pd.DataFrame, target_col: str, keep_ratio: float = 0.5) -> OptimizationResult:
49
49
  import time
50
- X, y = df.drop(columns=[target_col]), df[target_col]
50
+ import numpy as np
51
+ from sklearn.preprocessing import LabelEncoder
52
+
53
+ X, y = df.drop(columns=[target_col]), df[target_col].copy()
54
+
55
+ for col in X.columns:
56
+ if not np.issubdtype(X[col].dtype, np.number):
57
+ X[col] = LabelEncoder().fit_transform(X[col].astype(str))
58
+
59
+ if not np.issubdtype(y.dtype, np.number):
60
+ y = pd.Series(LabelEncoder().fit_transform(y.astype(str)), index=y.index)
61
+
62
+ X = X.fillna(0).astype(np.float64)
51
63
  minority_before = int(y.value_counts().min()) if y.nunique() > 1 else None
52
64
  t0 = time.time()
53
65
  self.fit(X, y)
@@ -8,7 +8,7 @@ from datapruning.algorithms.registry import register
8
8
  @register
9
9
  class EL2NScorerOptimizer(BaseOptimizer):
10
10
  key = "el2n"
11
- display_name = "Difficulty Scoring"
11
+ display_name = "Importance Scoring"
12
12
 
13
13
  def __init__(self):
14
14
  self._scores = None
@@ -43,14 +43,13 @@ class EL2NScorerOptimizer(BaseOptimizer):
43
43
  return minority_idx.append(kept_majority_idx)
44
44
 
45
45
  def why_selected(self) -> str:
46
- return ("Difficulty Scoring uses feature-space distance analysis to identify "
47
- "samples that are far from their class centroid. These informative "
48
- "boundary samples help the model learn better decision regions. "
49
- "Works as a reliable fallback for any dataset shape.")
46
+ return ("Measures how difficult each sample is for the model to classify by analyzing "
47
+ "feature-space distances. Keeps the most informative boundary samples that "
48
+ "help the model learn better decision regions. Works reliably on any dataset.")
50
49
 
51
50
  def limitations(self) -> list[str]:
52
51
  return [
53
- "Uses feature norms as proxy less precise than real model logits.",
52
+ "Uses distance-based approximation slightly less precise than model-based methods.",
54
53
  "May select outliers on very noisy datasets.",
55
54
  ]
56
55
 
@@ -32,16 +32,14 @@ class FusionPipelineOptimizer(BaseOptimizer):
32
32
  return self._selected_indices
33
33
 
34
34
  def why_selected(self) -> str:
35
- return ("Full Pipeline runs the complete ResearchFusionEngine: "
36
- "multi-signal scoring (EL2N + Margin), normalization, "
37
- "adaptive fusion, noise detection, difficulty classification, "
38
- "redundancy removal, and diversity-aware selection. "
39
- "Maximum quality for complex datasets.")
35
+ return ("Runs the most comprehensive analysis: combines multiple quality signals, "
36
+ "detects noise, classifies sample difficulty, removes redundancy, and "
37
+ "ensures diversity. Maximum quality for complex or messy datasets.")
40
38
 
41
39
  def limitations(self) -> list[str]:
42
40
  return [
43
- "Slower than individual methods runs multiple scoring steps.",
44
- "May be overkill for simple, clean datasets.",
41
+ "Takes longer than simpler methods due to multiple analysis steps.",
42
+ "May be overkill for small, clean datasets.",
45
43
  ]
46
44
 
47
45
  @staticmethod
@@ -30,16 +30,14 @@ class KCenterSelectOptimizer(BaseOptimizer):
30
30
  return self._selected_indices
31
31
 
32
32
  def why_selected(self) -> str:
33
- return ("Diversity Selection uses K-Center Greedy to pick the most "
34
- "representative and diverse subset. It ensures broad coverage "
35
- "of the feature space, avoiding redundancy. Ideal for "
36
- "high-dimensional data or when you need maximum data variety.")
33
+ return ("Selects the most diverse and representative subset of your data by ensuring "
34
+ "broad coverage of the feature space. Eliminates redundant similar samples "
35
+ "while preserving maximum variety.")
37
36
 
38
37
  def limitations(self) -> list[str]:
39
38
  return [
40
- "Does not consider class labels directly — relies on feature diversity.",
41
- "May underperform on highly imbalanced datasets without minority preservation.",
42
- "Slower than scoring-based methods on very large datasets.",
39
+ "Focuses on diversity rather than class labels directly.",
40
+ "May be less effective on highly imbalanced datasets.",
43
41
  ]
44
42
 
45
43
  @staticmethod
@@ -49,15 +49,14 @@ class MarginScorerOptimizer(BaseOptimizer):
49
49
  return minority_idx.append(kept_majority_idx)
50
50
 
51
51
  def why_selected(self) -> str:
52
- return ("Margin Optimization uses logistic regression to measure how confidently "
53
- "each sample is classified. It keeps the most informative majority-class "
54
- "samples (high margin = clear signal) and preserves 100% of the minority class. "
55
- "Best for general tabular data with clear class boundaries.")
52
+ return ("Analyzes how confidently each data point is classified, keeping the most "
53
+ "informative samples near decision boundaries. Automatically preserves all "
54
+ "minority-class examples to maintain balanced training data.")
56
55
 
57
56
  def limitations(self) -> list[str]:
58
57
  return [
59
- "Requires fitting a quick logistic regression model.",
60
- "May underperform on very high-dimensional data without feature selection.",
58
+ "Requires a quick model fitting step during analysis.",
59
+ "May be less effective on extremely high-dimensional datasets.",
61
60
  ]
62
61
 
63
62
  @staticmethod
@@ -60,15 +60,14 @@ class SlidingWindowOptimizer(BaseOptimizer):
60
60
  return all_idx
61
61
 
62
62
  def why_selected(self) -> str:
63
- return ("Noise Filtering drops both the easiest (redundant) and hardest "
64
- "(potentially mislabeled) samples, keeping the informative middle. "
65
- "This is the sliding window method from the EL2N/GraNd paper. "
66
- "Best for datasets with suspected label noise.")
63
+ return ("Filters out both the easiest (redundant) and hardest (potentially mislabeled) "
64
+ "samples, keeping only the informative middle ground. Best for cleaning "
65
+ "datasets that may contain labeling errors or noisy data.")
67
66
 
68
67
  def limitations(self) -> list[str]:
69
68
  return [
70
- "Requires fitting a logistic regression for scoring.",
71
- "May discard genuinely hard but correct samples on complex datasets.",
69
+ "Requires a quick model fitting step during analysis.",
70
+ "May occasionally remove genuinely hard but correct samples.",
72
71
  ]
73
72
 
74
73
  @staticmethod
@@ -2,23 +2,23 @@ STRATEGY_DISPLAY = {
2
2
  "margin": {
3
3
  "display_name": "Margin Optimization",
4
4
  "icon": "\U0001F3AF",
5
- "description": "Uses logistic regression to measure classification confidence. Keeps the most informative samples near decision boundaries while preserving all minority-class examples.",
5
+ "description": "Analyzes classification confidence to keep the most informative samples near decision boundaries while preserving all minority-class examples.",
6
6
  "best_for": "General tabular data, binary and multi-class classification",
7
7
  "advantages": [
8
8
  "Best overall accuracy on benchmarks (+12% avg improvement)",
9
- "Fast execution single logistic regression fit",
9
+ "Fast execution -- single analysis step",
10
10
  "Preserves 100% of minority class",
11
11
  ],
12
12
  "tradeoffs": [
13
- "Requires fitting a quick model",
14
- "May underperform on extremely high-dimensional data",
13
+ "Requires a quick model fitting step",
14
+ "May be less effective on extremely high-dimensional data",
15
15
  ],
16
16
  "recommended_models": ["XGBoost", "LightGBM", "Random Forest", "CatBoost"],
17
17
  },
18
18
  "el2n": {
19
- "display_name": "Difficulty Scoring",
19
+ "display_name": "Importance Scoring",
20
20
  "icon": "\U0001F4CA",
21
- "description": "Analyzes feature-space distances to identify informative boundary samples. Works as a reliable fallback for any dataset shape.",
21
+ "description": "Measures how difficult each sample is to classify by analyzing feature distances. Keeps the most informative boundary samples.",
22
22
  "best_for": "Fallback method, any dataset type, quick analysis",
23
23
  "advantages": [
24
24
  "Works on any dataset without model training",
@@ -29,12 +29,12 @@ STRATEGY_DISPLAY = {
29
29
  "Less precise than model-based scoring",
30
30
  "May select outliers on very noisy datasets",
31
31
  ],
32
- "recommended_models": ["Any model general purpose"],
32
+ "recommended_models": ["Any model -- general purpose"],
33
33
  },
34
34
  "kcenter": {
35
35
  "display_name": "Diversity Selection",
36
36
  "icon": "\U0001F308",
37
- "description": "Picks the most representative and diverse subset using K-Center Greedy. Ensures broad coverage of the feature space, avoiding redundancy.",
37
+ "description": "Picks the most representative and diverse subset, ensuring broad coverage of the feature space while avoiding redundancy.",
38
38
  "best_for": "High-dimensional data, datasets with redundancy, when variety matters",
39
39
  "advantages": [
40
40
  "Maximum feature space coverage",
@@ -50,34 +50,34 @@ STRATEGY_DISPLAY = {
50
50
  "sliding_window": {
51
51
  "display_name": "Noise Filtering",
52
52
  "icon": "\U0001F9FB",
53
- "description": "Drops both the easiest (redundant) and hardest (potentially mislabeled) samples, keeping the informative middle. Based on the EL2N/GraNd research paper.",
53
+ "description": "Drops both the easiest (redundant) and hardest (potentially mislabeled) samples, keeping the informative middle ground.",
54
54
  "best_for": "Datasets with suspected label noise, corrupted data",
55
55
  "advantages": [
56
56
  "Removes both redundant and noisy samples",
57
- "Research-backed method from top ML papers",
57
+ "Proven method for cleaning real-world data",
58
58
  "Good for cleaning real-world messy data",
59
59
  ],
60
60
  "tradeoffs": [
61
- "Requires fitting a logistic regression",
62
- "May discard genuinely hard but correct samples",
61
+ "Requires a quick model fitting step",
62
+ "May occasionally discard hard but correct samples",
63
63
  ],
64
64
  "recommended_models": ["XGBoost", "LightGBM", "Any robust model"],
65
65
  },
66
66
  "fusion": {
67
67
  "display_name": "Full Pipeline",
68
68
  "icon": "\u2728",
69
- "description": "Runs the complete ResearchFusionEngine: multi-signal scoring, normalization, adaptive fusion, noise detection, difficulty classification, redundancy removal, and diversity-aware selection. Maximum quality.",
69
+ "description": "The most comprehensive analysis: combines multiple quality signals, detects noise, classifies importance, removes redundancy, and ensures diversity.",
70
70
  "best_for": "Complex datasets, when quality matters more than speed",
71
71
  "advantages": [
72
- "Most comprehensive pruning pipeline",
73
- "Combines multiple research-backed signals",
72
+ "Most comprehensive optimization pipeline",
73
+ "Combines multiple quality signals",
74
74
  "Handles noise, redundancy, and diversity",
75
75
  ],
76
76
  "tradeoffs": [
77
77
  "Slower than individual methods",
78
78
  "May be overkill for simple clean datasets",
79
79
  ],
80
- "recommended_models": ["Any maximizes data quality"],
80
+ "recommended_models": ["Any -- maximizes data quality"],
81
81
  },
82
82
  }
83
83
 
@@ -32,6 +32,12 @@ def classify_difficulty(
32
32
  thresholds : dict — the score values at each boundary.
33
33
  """
34
34
  s = np.asarray(scores, dtype=np.float64)
35
+ score_range = s.max() - s.min()
36
+
37
+ if score_range < 1e-10:
38
+ labels = np.full(len(s), "medium", dtype="U6")
39
+ return labels, {"easy_below": float(s.min()), "hard_above": float(s.max())}
40
+
35
41
  easy_val = np.percentile(s, easy_threshold)
36
42
  hard_val = np.percentile(s, hard_threshold)
37
43
 
@@ -209,12 +209,14 @@ class ResearchFusionEngine:
209
209
  adjusted_scores[noise_mask] -= np.abs(adjusted_scores[noise_mask].max()) + 1
210
210
 
211
211
  if selection_method == "sliding_window":
212
+ budget = max(1, int(n * keep_ratio))
212
213
  selected = sliding_window_select(
213
214
  adjusted_scores,
214
215
  low_percentile=10.0,
215
216
  high_percentile=90.0,
216
217
  labels=y,
217
218
  preserve_minority=minority_preserve,
219
+ budget=budget,
218
220
  )
219
221
  else:
220
222
  budget = max(1, int(n * keep_ratio))
@@ -88,40 +88,45 @@ def sliding_window_select(
88
88
  high_percentile: float = 90.0,
89
89
  labels: np.ndarray | None = None,
90
90
  preserve_minority: bool = True,
91
+ budget: int | None = None,
91
92
  ) -> np.ndarray:
92
- """Sliding window selection (from Paul et al., 2021).
93
+ """Sliding window selection keep samples within a score range.
93
94
 
94
- Keep samples within a score range, excluding both easiest and hardest.
95
- This is the method described in the EL2N/GraNd paper for balancing
96
- difficulty and coverage.
95
+ Excludes both the easiest (redundant) and hardest (potentially noisy)
96
+ samples, keeping the most informative middle band.
97
97
 
98
98
  Parameters
99
99
  ----------
100
- scores : (N,) array — difficulty scores.
101
- low_percentile : float — lower bound (drop easier samples).
100
+ scores : (N,) array — importance scores.
101
+ low_percentile : float — lower bound (drop easiest samples).
102
102
  high_percentile : float — upper bound (drop hardest/noisiest samples).
103
+ labels : (N,) array — class labels (for balance enforcement).
104
+ preserve_minority : bool — ensure minority classes aren't wiped out.
105
+ budget : int, optional — if set, cap output to this many samples.
103
106
  """
104
107
  s = np.asarray(scores, dtype=np.float64)
108
+ n = len(s)
105
109
  low_val = np.percentile(s, low_percentile)
106
110
  high_val = np.percentile(s, high_percentile)
107
111
 
108
112
  in_window = (s >= low_val) & (s <= high_val)
109
113
  window_indices = np.where(in_window)[0]
110
114
 
111
- if labels is None or not preserve_minority:
112
- return window_indices
113
-
114
- # ensure minority classes are represented in the window
115
- labels = np.asarray(labels, dtype=np.int64)
116
- classes = np.unique(labels)
117
- for cls in classes:
118
- cls_in_window = window_indices[labels[window_indices] == cls]
119
- if len(cls_in_window) == 0:
120
- # no samples of this class in window → add top-scored ones
121
- cls_mask = labels == cls
122
- cls_scores = s.copy()
123
- cls_scores[~cls_mask] = -np.inf
124
- top_cls = np.argsort(cls_scores)[-1:]
125
- window_indices = np.concatenate([window_indices, top_cls])
115
+ if labels is not None and preserve_minority:
116
+ labels = np.asarray(labels, dtype=np.int64)
117
+ classes = np.unique(labels)
118
+ for cls in classes:
119
+ cls_in_window = window_indices[labels[window_indices] == cls]
120
+ if len(cls_in_window) == 0:
121
+ cls_mask = labels == cls
122
+ cls_scores = s.copy()
123
+ cls_scores[~cls_mask] = -np.inf
124
+ top_cls = np.argsort(cls_scores)[-1:]
125
+ window_indices = np.concatenate([window_indices, top_cls])
126
+
127
+ if budget is not None and len(window_indices) > budget:
128
+ cls_in = window_indices
129
+ cls_sub = cls_in[np.argsort(s[cls_in])[-budget:][::-1]]
130
+ window_indices = cls_sub
126
131
 
127
132
  return window_indices
@@ -35,7 +35,7 @@ class DatasetEngine:
35
35
  """Create a DatasetEngine from a folder of images.
36
36
 
37
37
  Encodes all images with CLIP into feature vectors, then wraps
38
- them in a DataFrame so the existing pruning algorithms work
38
+ them in a DataFrame so the existing optimization algorithms work
39
39
  unchanged.
40
40
 
41
41
  Parameters
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datapruning
3
- Version: 2.1.0
4
- Summary: Intelligent data pruning for ML datasets
3
+ Version: 2.1.2
4
+ Summary: Intelligent dataset optimization for cleaner, smaller training data
5
5
  License: Proprietary
6
6
  Project-URL: Homepage, https://www.datapruning.com
7
7
  Classifier: Development Status :: 4 - Beta
@@ -20,8 +20,10 @@ License-File: LICENSE
20
20
  Requires-Dist: numpy>=1.24.0
21
21
  Requires-Dist: pandas>=2.0.0
22
22
  Requires-Dist: scikit-learn>=1.3.0
23
- Requires-Dist: torch>=2.0.0
23
+ Provides-Extra: torch
24
+ Requires-Dist: torch>=2.0.0; extra == "torch"
24
25
  Provides-Extra: clip
26
+ Requires-Dist: torch>=2.0.0; extra == "clip"
25
27
  Requires-Dist: transformers>=4.30.0; extra == "clip"
26
28
  Requires-Dist: pillow>=9.0.0; extra == "clip"
27
29
  Dynamic: license-file
@@ -1,8 +1,11 @@
1
1
  numpy>=1.24.0
2
2
  pandas>=2.0.0
3
3
  scikit-learn>=1.3.0
4
- torch>=2.0.0
5
4
 
6
5
  [clip]
6
+ torch>=2.0.0
7
7
  transformers>=4.30.0
8
8
  pillow>=9.0.0
9
+
10
+ [torch]
11
+ torch>=2.0.0
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "datapruning"
7
- version = "2.1.0"
8
- description = "Intelligent data pruning for ML datasets"
7
+ version = "2.1.2"
8
+ description = "Intelligent dataset optimization for cleaner, smaller training data"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = {text = "Proprietary"}
@@ -25,11 +25,14 @@ dependencies = [
25
25
  "numpy>=1.24.0",
26
26
  "pandas>=2.0.0",
27
27
  "scikit-learn>=1.3.0",
28
- "torch>=2.0.0",
29
28
  ]
30
29
 
31
30
  [project.optional-dependencies]
31
+ torch = [
32
+ "torch>=2.0.0",
33
+ ]
32
34
  clip = [
35
+ "torch>=2.0.0",
33
36
  "transformers>=4.30.0",
34
37
  "pillow>=9.0.0",
35
38
  ]
File without changes
File without changes
File without changes
File without changes
File without changes