scikit-extensions 0.1.0__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.
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 sh99-git
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: scikit-extensions
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: "A collection of Scikit-learn-compatible transformers for feature engineering, preprocessing, and pipeline utilities."
|
|
5
|
+
Home-page: https://github.com/your-username/scikit-extensions
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: scikit-learn,transformers,preprocessing,pipeline
|
|
8
|
+
Author: sh99
|
|
9
|
+
Author-email: shriramh99@gmail.com
|
|
10
|
+
Requires-Python: >=3.10,<3.14
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Dist: pandas (>=2.3.2,<3.0.0)
|
|
19
|
+
Requires-Dist: scikit-learn (>=1.7.2,<2.0.0)
|
|
20
|
+
Project-URL: Repository, https://github.com/your-username/scikit-extensions
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# scikit-extensions
|
|
24
|
+
A collection of Scikit-learn-compatible transformers for feature engineering, preprocessing, and pipeline utilities.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
- 🧰 Clean, extensible API compatible with Scikit-learn
|
|
28
|
+
- 🧪 Fully testable, with support for Pandas, NumPy, and SciPy
|
|
29
|
+
- 📦 Easy to integrate in production ML pipelines
|
|
30
|
+
|
|
31
|
+
## 📦 Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install scikit-extensions
|
|
35
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# scikit-extensions
|
|
2
|
+
A collection of Scikit-learn-compatible transformers for feature engineering, preprocessing, and pipeline utilities.
|
|
3
|
+
|
|
4
|
+
## Features
|
|
5
|
+
- 🧰 Clean, extensible API compatible with Scikit-learn
|
|
6
|
+
- 🧪 Fully testable, with support for Pandas, NumPy, and SciPy
|
|
7
|
+
- 📦 Easy to integrate in production ML pipelines
|
|
8
|
+
|
|
9
|
+
## 📦 Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install scikit-extensions
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "scikit-extensions"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "\"A collection of Scikit-learn-compatible transformers for feature engineering, preprocessing, and pipeline utilities.\""
|
|
5
|
+
authors = ["sh99 <shriramh99@gmail.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
packages = [{ include = "skext" }]
|
|
9
|
+
homepage = "https://github.com/your-username/scikit-extensions"
|
|
10
|
+
repository = "https://github.com/your-username/scikit-extensions"
|
|
11
|
+
keywords = ["scikit-learn", "transformers", "preprocessing", "pipeline"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence"
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.poetry.dependencies]
|
|
20
|
+
python = ">=3.10,<3.14"
|
|
21
|
+
scikit-learn = "^1.7.2"
|
|
22
|
+
pandas = "^2.3.2"
|
|
23
|
+
|
|
24
|
+
[tool.poetry.dev-dependencies]
|
|
25
|
+
pytest = "^7.0"
|
|
26
|
+
black = "^23.0"
|
|
27
|
+
ruff = "^0.1.0"
|
|
28
|
+
mypy = "^1.7"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["poetry-core"]
|
|
32
|
+
build-backend = "poetry.core.masonry.api"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import numpy as np
|
|
3
|
+
from scipy.sparse import issparse, hstack
|
|
4
|
+
from sklearn.base import BaseEstimator, TransformerMixin
|
|
5
|
+
from sklearn.preprocessing import MultiLabelBinarizer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MultiLabelBinarizerTransformer(BaseEstimator, TransformerMixin):
|
|
9
|
+
"""
|
|
10
|
+
A custom transformer that wraps sklearn's MultiLabelBinarizer to integrate seamlessly into scikit-learn pipelines.
|
|
11
|
+
|
|
12
|
+
This transformer converts a collection of label sets (iterables of iterables) into a binary indicator matrix.
|
|
13
|
+
It is particularly useful for multi-label classification tasks where each sample can belong to multiple classes.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
sparse_output : bool, default=False
|
|
18
|
+
If True, the output will be a sparse matrix in Compressed Sparse Row (CSR) format. Otherwise, a dense NumPy array is returned.
|
|
19
|
+
|
|
20
|
+
Attributes
|
|
21
|
+
----------
|
|
22
|
+
mlbs : dict
|
|
23
|
+
A dictionary mapping column names to fitted MultiLabelBinarizer instances.
|
|
24
|
+
feature_names_in_ : list
|
|
25
|
+
List of input feature names (column names) during fitting.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, sparse_output=False):
|
|
29
|
+
"""
|
|
30
|
+
Initializes the transformer with the specified parameters.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
sparse_output : bool, default=False
|
|
35
|
+
If True, the output will be a sparse matrix in Compressed Sparse Row (CSR) format. Otherwise, a dense NumPy array is returned.
|
|
36
|
+
"""
|
|
37
|
+
self.sparse_output = sparse_output
|
|
38
|
+
self.mlbs = {}
|
|
39
|
+
self.feature_names_in_ = None
|
|
40
|
+
|
|
41
|
+
def fit(self, X, y=None):
|
|
42
|
+
"""
|
|
43
|
+
Fits the transformer to the provided label sets.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
X : pandas DataFrame of shape (n_samples, n_features)
|
|
48
|
+
A collection of label sets, where each set contains the labels for a single sample.
|
|
49
|
+
|
|
50
|
+
y : None
|
|
51
|
+
Ignored. This parameter exists for compatibility with scikit-learn pipelines.
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
self : object
|
|
56
|
+
The fitted transformer.
|
|
57
|
+
"""
|
|
58
|
+
if not isinstance(X, pd.DataFrame):
|
|
59
|
+
raise ValueError("Input must be a pandas DataFrame")
|
|
60
|
+
self.feature_names_in_ = X.columns.tolist()
|
|
61
|
+
self.mlbs = {
|
|
62
|
+
col: MultiLabelBinarizer(sparse_output=self.sparse_output).fit(X[col])
|
|
63
|
+
for col in self.feature_names_in_
|
|
64
|
+
}
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
def transform(self, X):
|
|
68
|
+
"""
|
|
69
|
+
Transforms the provided label sets into a binary indicator matrix.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
X : pandas DataFrame of shape (n_samples, n_features)
|
|
74
|
+
A collection of label sets to transform.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
transformed : pandas DataFrame or sparse matrix of shape (n_samples, n_classes)
|
|
79
|
+
A binary matrix indicating the presence of each class label in each sample.
|
|
80
|
+
"""
|
|
81
|
+
if not isinstance(X, pd.DataFrame):
|
|
82
|
+
raise ValueError("Input must be a pandas DataFrame")
|
|
83
|
+
transformed_parts = []
|
|
84
|
+
for col in self.feature_names_in_:
|
|
85
|
+
mlb = self.mlbs[col]
|
|
86
|
+
part = mlb.transform(X[col])
|
|
87
|
+
if not self.sparse_output:
|
|
88
|
+
part = pd.DataFrame(
|
|
89
|
+
part,
|
|
90
|
+
columns=[f"{col}__{cls}" for cls in mlb.classes_],
|
|
91
|
+
index=X.index
|
|
92
|
+
)
|
|
93
|
+
transformed_parts.append(part)
|
|
94
|
+
return hstack(transformed_parts) if self.sparse_output else pd.concat(transformed_parts, axis=1)
|
|
95
|
+
|
|
96
|
+
def inverse_transform(self, X):
|
|
97
|
+
"""
|
|
98
|
+
Converts a binary indicator matrix back into label sets.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
X : pandas DataFrame or sparse matrix of shape (n_samples, n_classes)
|
|
103
|
+
A binary matrix indicating the presence of each class label in each sample.
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
inverse_transformed : pandas DataFrame of shape (n_samples, n_features)
|
|
108
|
+
A DataFrame where each column contains the original label sets for each sample.
|
|
109
|
+
"""
|
|
110
|
+
if self.sparse_output and not issparse(X):
|
|
111
|
+
raise ValueError("Expected sparse input for inverse_transform but got dense.")
|
|
112
|
+
if not self.sparse_output and isinstance(X, np.ndarray):
|
|
113
|
+
X = pd.DataFrame(X, columns=self.get_feature_names_out())
|
|
114
|
+
result = {}
|
|
115
|
+
if self.sparse_output:
|
|
116
|
+
current_col = 0
|
|
117
|
+
for col in self.feature_names_in_:
|
|
118
|
+
mlb = self.mlbs[col]
|
|
119
|
+
n_classes = len(mlb.classes_)
|
|
120
|
+
col_slice = X[:, current_col:current_col + n_classes]
|
|
121
|
+
result[col] = mlb.inverse_transform(col_slice)
|
|
122
|
+
current_col += n_classes
|
|
123
|
+
else:
|
|
124
|
+
for col in self.feature_names_in_:
|
|
125
|
+
mlb = self.mlbs[col]
|
|
126
|
+
col_data = X[[f"{col}__{cls}" for cls in mlb.classes_]]
|
|
127
|
+
result[col] = mlb.inverse_transform(col_data.values)
|
|
128
|
+
return pd.DataFrame(result)
|
|
129
|
+
|
|
130
|
+
def get_feature_names_out(self, input_features=None):
|
|
131
|
+
"""
|
|
132
|
+
Returns the output feature names for transformation.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
input_features : list of str, default=None
|
|
137
|
+
Input feature names. If None, uses the feature names seen during fitting.
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
feature_names_out : list of str
|
|
142
|
+
The output feature names.
|
|
143
|
+
"""
|
|
144
|
+
if input_features is None:
|
|
145
|
+
input_features = self.feature_names_in_
|
|
146
|
+
out = []
|
|
147
|
+
for col in input_features:
|
|
148
|
+
mlb = self.mlbs.get(col)
|
|
149
|
+
if mlb:
|
|
150
|
+
out.extend([f"{col}__{cls}" for cls in mlb.classes_])
|
|
151
|
+
return out
|