orient_express 0.3.3__tar.gz → 0.3.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: orient_express
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A library to simplify model deployment to Vertex AI
5
5
  Author: Alexey Zankevich
6
6
  Author-email: alex.zankevich@shiftsmart.com
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Requires-Dist: google-cloud-aiplatform
14
14
  Requires-Dist: google-cloud-storage
15
+ Requires-Dist: jupyter (>=1.1.1,<2.0.0)
15
16
  Requires-Dist: pandas
16
17
  Description-Content-Type: text/markdown
17
18
 
@@ -1,4 +1,6 @@
1
1
  import os
2
+ from typing import Optional
3
+
2
4
  import joblib
3
5
  import logging
4
6
  import pandas as pd
@@ -9,20 +11,20 @@ from google.cloud import aiplatform
9
11
  class ModelExpress:
10
12
  def __init__(
11
13
  self,
12
- model_name,
13
- project_name,
14
- bucket_name,
15
- model_version=None,
16
- model=None,
17
- region="us-central1",
18
- serialized_model_path="model.joblib",
19
- serving_container_image_uri="us-west1-docker.pkg.dev/shiftsmart-api/orient-express/xgboost-scikit-learn:latest",
20
- serving_container_predict_route="/v1/models/orient-express-model:predict",
21
- serving_container_health_route="/v1/models/orient-express-model",
22
- endpoint_name=None,
14
+ model_name: str,
15
+ project_name: str,
16
+ bucket_name: str,
17
+ model_version: Optional[int] = None,
18
+ model: object = None,
19
+ region: str = "us-central1",
20
+ serialized_model_path: str = "model.joblib",
21
+ serving_container_image_uri: str = "us-west1-docker.pkg.dev/shiftsmart-api/orient-express/xgboost-scikit-learn:latest",
22
+ serving_container_predict_route: str = "/v1/models/orient-express-model:predict",
23
+ serving_container_health_route: str = "/v1/models/orient-express-model",
24
+ endpoint_name: Optional[str] = None,
23
25
  machine_type="n1-standard-4",
24
- min_replica_count=1,
25
- max_replica_count=1,
26
+ min_replica_count: int = 1,
27
+ max_replica_count: int = 1,
26
28
  ):
27
29
  self.model = model
28
30
  self.model_name = model_name
@@ -56,7 +58,7 @@ class ModelExpress:
56
58
  aiplatform.init(project=self.project_name, location=self.region)
57
59
  self._vertex_initialized = True
58
60
 
59
- def get_latest_vertex_model(self, model_name):
61
+ def get_latest_vertex_model(self, model_name: str):
60
62
  """If there are a few models with the same name, load the most recent one.
61
63
  It's highly recommended to keep only 1 model with the same name to avoid the confusion
62
64
  """
@@ -96,7 +98,7 @@ class ModelExpress:
96
98
 
97
99
  return self.create_model_version(new_version, last_model)
98
100
 
99
- def get_artifacts_path(self, version, file_name=None):
101
+ def get_artifacts_path(self, version: int, file_name: str = None):
100
102
  dir_name = f"models/{self.model_name}/{version}"
101
103
  if file_name:
102
104
  return f"{dir_name}/{file_name}"
@@ -159,7 +161,7 @@ class ModelExpress:
159
161
  traffic_percentage=100,
160
162
  )
161
163
 
162
- def remote_predict(self, input_df):
164
+ def remote_predict(self, input_df: pd.DataFrame):
163
165
  self._vertex_init()
164
166
 
165
167
  if not self.endpoint:
@@ -174,7 +176,7 @@ class ModelExpress:
174
176
  predictions = self.endpoint.predict(instances=instances)
175
177
  return predictions.predictions
176
178
 
177
- def local_predict(self, input_df):
179
+ def local_predict(self, input_df: pd.DataFrame):
178
180
  self._vertex_init()
179
181
 
180
182
  if not self.model:
@@ -182,7 +184,7 @@ class ModelExpress:
182
184
 
183
185
  return self.model.predict(input_df)
184
186
 
185
- def local_predict_proba(self, input_df):
187
+ def local_predict_proba(self, input_df: pd.DataFrame):
186
188
  if not self.model:
187
189
  self.load_model_from_registry()
188
190
 
@@ -207,7 +209,7 @@ class ModelExpress:
207
209
 
208
210
  self.model = joblib.load(self.serialized_model_path)
209
211
 
210
- def download_artifacts(self, artifact_uri):
212
+ def download_artifacts(self, artifact_uri: str):
211
213
  storage_client = storage.Client()
212
214
  bucket_name, artifact_path = artifact_uri.replace("gs://", "").split("/", 1)
213
215
  bucket = storage_client.bucket(bucket_name)
@@ -0,0 +1,81 @@
1
+ from sklearn.base import BaseEstimator, TransformerMixin
2
+ from sklearn.preprocessing import LabelEncoder
3
+
4
+
5
+ class LabelEncoderTransformer(BaseEstimator, TransformerMixin):
6
+ """
7
+ A wrapper class that integrates a model and a label encoder to handle
8
+ encoded predictions and their corresponding probabilities.
9
+
10
+ Attributes:
11
+ model (object): A machine learning model with `fit`, `predict`, and `predict_proba` methods.
12
+ label_encoder (object): A label encoder that maps encoded class labels to their original string labels.
13
+
14
+ Methods:
15
+ fit(X, y):
16
+ Trains the model on the provided features and labels.
17
+ predict(X):
18
+ Predicts the classes for the given features and returns the original string labels.
19
+ predict_proba(X):
20
+ Returns the probabilities for each class for the given features, along with their original class labels.
21
+ """
22
+
23
+ def __init__(self, model: BaseEstimator, label_encoder: LabelEncoder):
24
+ """
25
+ Initializes the LabelEncoderTransformer.
26
+
27
+ Args:
28
+ model (BaseEstimator): A machine learning model.
29
+ label_encoder (LabelEncoder): A label encoder with `fit` and `inverse_transform` methods.
30
+ """
31
+ self.model = model
32
+ self.label_encoder = label_encoder
33
+
34
+ def fit(self, X, y):
35
+ """
36
+ Fits the model to the training data.
37
+
38
+ Args:
39
+ X (array-like): Feature matrix.
40
+ y (array-like): Target labels.
41
+
42
+ Returns:
43
+ self: Fitted LabelEncoderTransformer instance.
44
+ """
45
+ self.model.fit(X, y)
46
+ return self
47
+
48
+ def predict(self, X):
49
+ """
50
+ Predicts the target labels and returns the original string labels.
51
+
52
+ Args:
53
+ X (array-like): Feature matrix for predictions.
54
+
55
+ Returns:
56
+ array-like: Predicted class labels in their original form.
57
+ """
58
+ encoded_predictions = self.model.predict(X)
59
+ return self.label_encoder.inverse_transform(encoded_predictions)
60
+
61
+ def predict_proba(self, X):
62
+ """
63
+ Returns class probabilities along with their original labels.
64
+
65
+ Args:
66
+ X (array-like): Feature matrix for predictions.
67
+
68
+ Returns:
69
+ list: A list of lists, where each inner list contains `[class_name, probability]` pairs.
70
+ """
71
+ # Get raw probabilities
72
+ probabilities = self.model.predict_proba(X)
73
+
74
+ # Get all class labels
75
+ class_names = self.label_encoder.classes_
76
+ # Combine class names with probabilities
77
+ combined_output = [
78
+ [[class_name, prob] for class_name, prob in zip(class_names, sample_probs)]
79
+ for sample_probs in probabilities
80
+ ]
81
+ return combined_output
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "orient_express"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "A library to simplify model deployment to Vertex AI"
5
5
  authors = ["Alexey Zankevich <alex.zankevich@shiftsmart.com>"]
6
6
  readme = "README.md"
@@ -10,6 +10,7 @@ python = ">=3.9,<3.13"
10
10
  google-cloud-aiplatform = "*"
11
11
  google-cloud-storage = "*"
12
12
  pandas = "*"
13
+ jupyter = "^1.1.1"
13
14
 
14
15
  [tool.poetry.dev-dependencies]
15
16
  black = "24.10.0"
File without changes