featrixsphere 0.2.5563__py3-none-any.whl → 0.2.5978__py3-none-any.whl
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.
- featrixsphere/__init__.py +37 -18
- featrixsphere/api/__init__.py +50 -0
- featrixsphere/api/api_endpoint.py +280 -0
- featrixsphere/api/client.py +396 -0
- featrixsphere/api/foundational_model.py +658 -0
- featrixsphere/api/http_client.py +209 -0
- featrixsphere/api/notebook_helper.py +584 -0
- featrixsphere/api/prediction_result.py +231 -0
- featrixsphere/api/predictor.py +537 -0
- featrixsphere/api/reference_record.py +227 -0
- featrixsphere/api/vector_database.py +269 -0
- featrixsphere/client.py +215 -12
- {featrixsphere-0.2.5563.dist-info → featrixsphere-0.2.5978.dist-info}/METADATA +1 -1
- featrixsphere-0.2.5978.dist-info/RECORD +17 -0
- featrixsphere-0.2.5563.dist-info/RECORD +0 -7
- {featrixsphere-0.2.5563.dist-info → featrixsphere-0.2.5978.dist-info}/WHEEL +0 -0
- {featrixsphere-0.2.5563.dist-info → featrixsphere-0.2.5978.dist-info}/entry_points.txt +0 -0
- {featrixsphere-0.2.5563.dist-info → featrixsphere-0.2.5978.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PredictionResult and PredictionFeedback classes.
|
|
3
|
+
|
|
4
|
+
These classes represent prediction results and the feedback mechanism
|
|
5
|
+
for improving model accuracy.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Dict, Any, Optional, Union, TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .http_client import ClientContext
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class PredictionResult:
|
|
18
|
+
"""
|
|
19
|
+
Represents a prediction result with full metadata.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
prediction_uuid: Unique identifier for this prediction (use for feedback)
|
|
23
|
+
prediction: Raw prediction result (class probabilities or numeric value)
|
|
24
|
+
predicted_class: Predicted class name (for classification)
|
|
25
|
+
confidence: Confidence score (for classification)
|
|
26
|
+
query_record: Original input record
|
|
27
|
+
predictor_id: ID of predictor that made this prediction
|
|
28
|
+
session_id: Session ID (internal)
|
|
29
|
+
timestamp: When prediction was made
|
|
30
|
+
target_column: Target column name
|
|
31
|
+
|
|
32
|
+
Usage:
|
|
33
|
+
result = predictor.predict({"age": 35, "income": 50000})
|
|
34
|
+
print(result.predicted_class) # "churned"
|
|
35
|
+
print(result.confidence) # 0.87
|
|
36
|
+
print(result.prediction_uuid) # UUID for feedback
|
|
37
|
+
|
|
38
|
+
# Send feedback if prediction was wrong
|
|
39
|
+
if result.predicted_class != actual_label:
|
|
40
|
+
feedback = result.send_feedback(ground_truth=actual_label)
|
|
41
|
+
feedback.send()
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
prediction_uuid: Optional[str] = None
|
|
45
|
+
prediction: Optional[Union[Dict[str, float], float]] = None
|
|
46
|
+
predicted_class: Optional[str] = None
|
|
47
|
+
confidence: Optional[float] = None
|
|
48
|
+
query_record: Optional[Dict[str, Any]] = None
|
|
49
|
+
predictor_id: Optional[str] = None
|
|
50
|
+
session_id: Optional[str] = None
|
|
51
|
+
target_column: Optional[str] = None
|
|
52
|
+
timestamp: Optional[datetime] = None
|
|
53
|
+
model_version: Optional[str] = None
|
|
54
|
+
|
|
55
|
+
# Internal: client context for sending feedback
|
|
56
|
+
_ctx: Optional['ClientContext'] = field(default=None, repr=False)
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def from_response(
|
|
60
|
+
cls,
|
|
61
|
+
response: Dict[str, Any],
|
|
62
|
+
query_record: Dict[str, Any],
|
|
63
|
+
ctx: Optional['ClientContext'] = None
|
|
64
|
+
) -> 'PredictionResult':
|
|
65
|
+
"""
|
|
66
|
+
Create PredictionResult from API response.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
response: API response dictionary
|
|
70
|
+
query_record: Original query record
|
|
71
|
+
ctx: Client context for feedback
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
PredictionResult instance
|
|
75
|
+
"""
|
|
76
|
+
# Extract prediction data
|
|
77
|
+
prediction = response.get('prediction')
|
|
78
|
+
predicted_class = None
|
|
79
|
+
confidence = None
|
|
80
|
+
|
|
81
|
+
# For classification, extract class and confidence
|
|
82
|
+
if isinstance(prediction, dict):
|
|
83
|
+
# Find the class with highest probability
|
|
84
|
+
if prediction:
|
|
85
|
+
predicted_class = max(prediction.keys(), key=lambda k: prediction[k])
|
|
86
|
+
confidence = prediction[predicted_class]
|
|
87
|
+
|
|
88
|
+
return cls(
|
|
89
|
+
prediction_uuid=response.get('prediction_uuid') or response.get('prediction_id'),
|
|
90
|
+
prediction=prediction,
|
|
91
|
+
predicted_class=predicted_class,
|
|
92
|
+
confidence=confidence,
|
|
93
|
+
query_record=query_record,
|
|
94
|
+
predictor_id=response.get('predictor_id'),
|
|
95
|
+
session_id=response.get('session_id'),
|
|
96
|
+
target_column=response.get('target_column'),
|
|
97
|
+
timestamp=datetime.now(),
|
|
98
|
+
model_version=response.get('model_version'),
|
|
99
|
+
_ctx=ctx,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def send_feedback(self, ground_truth: Union[str, float]) -> 'PredictionFeedback':
|
|
103
|
+
"""
|
|
104
|
+
Create a feedback object for this prediction.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
ground_truth: The correct label/value
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
PredictionFeedback object (call .send() to submit)
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
ValueError: If prediction_uuid is not available
|
|
114
|
+
"""
|
|
115
|
+
if not self.prediction_uuid:
|
|
116
|
+
raise ValueError(
|
|
117
|
+
"Cannot send feedback: prediction_uuid not available. "
|
|
118
|
+
"The server may not have returned a prediction_uuid for this prediction."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return PredictionFeedback(
|
|
122
|
+
prediction_uuid=self.prediction_uuid,
|
|
123
|
+
ground_truth=ground_truth,
|
|
124
|
+
_ctx=self._ctx,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
128
|
+
"""Convert to dictionary representation."""
|
|
129
|
+
return {
|
|
130
|
+
'prediction_uuid': self.prediction_uuid,
|
|
131
|
+
'prediction': self.prediction,
|
|
132
|
+
'predicted_class': self.predicted_class,
|
|
133
|
+
'confidence': self.confidence,
|
|
134
|
+
'query_record': self.query_record,
|
|
135
|
+
'predictor_id': self.predictor_id,
|
|
136
|
+
'session_id': self.session_id,
|
|
137
|
+
'target_column': self.target_column,
|
|
138
|
+
'timestamp': self.timestamp.isoformat() if self.timestamp else None,
|
|
139
|
+
'model_version': self.model_version,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass
|
|
144
|
+
class PredictionFeedback:
|
|
145
|
+
"""
|
|
146
|
+
Represents feedback (ground truth) for a prediction.
|
|
147
|
+
|
|
148
|
+
Usage:
|
|
149
|
+
# Method 1: From PredictionResult
|
|
150
|
+
result = predictor.predict(record)
|
|
151
|
+
feedback = result.send_feedback(ground_truth="correct_label")
|
|
152
|
+
feedback.send()
|
|
153
|
+
|
|
154
|
+
# Method 2: Create directly
|
|
155
|
+
feedback = PredictionFeedback(
|
|
156
|
+
prediction_uuid="123e4567-e89b-12d3-a456-426614174000",
|
|
157
|
+
ground_truth="correct_label"
|
|
158
|
+
)
|
|
159
|
+
feedback.send()
|
|
160
|
+
|
|
161
|
+
# Method 3: Create and send in one call
|
|
162
|
+
PredictionFeedback.create_and_send(
|
|
163
|
+
ctx=client_context,
|
|
164
|
+
prediction_uuid="123e4567-...",
|
|
165
|
+
ground_truth="correct_label"
|
|
166
|
+
)
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
prediction_uuid: str
|
|
170
|
+
ground_truth: Union[str, float]
|
|
171
|
+
feedback_timestamp: Optional[datetime] = None
|
|
172
|
+
|
|
173
|
+
# Internal: client context for sending
|
|
174
|
+
_ctx: Optional['ClientContext'] = field(default=None, repr=False)
|
|
175
|
+
|
|
176
|
+
def send(self) -> Dict[str, Any]:
|
|
177
|
+
"""
|
|
178
|
+
Submit feedback to the server.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Server response
|
|
182
|
+
|
|
183
|
+
Raises:
|
|
184
|
+
ValueError: If no client context available
|
|
185
|
+
"""
|
|
186
|
+
if not self._ctx:
|
|
187
|
+
raise ValueError(
|
|
188
|
+
"Cannot send feedback: no client context. "
|
|
189
|
+
"Create feedback from a PredictionResult or use create_and_send()."
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
self.feedback_timestamp = datetime.now()
|
|
193
|
+
|
|
194
|
+
response = self._ctx.post_json(
|
|
195
|
+
f"/compute/prediction/{self.prediction_uuid}/update_label",
|
|
196
|
+
data={"user_label": str(self.ground_truth)}
|
|
197
|
+
)
|
|
198
|
+
return response
|
|
199
|
+
|
|
200
|
+
@classmethod
|
|
201
|
+
def create_and_send(
|
|
202
|
+
cls,
|
|
203
|
+
ctx: 'ClientContext',
|
|
204
|
+
prediction_uuid: str,
|
|
205
|
+
ground_truth: Union[str, float]
|
|
206
|
+
) -> Dict[str, Any]:
|
|
207
|
+
"""
|
|
208
|
+
Create and send feedback in one call.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
ctx: Client context
|
|
212
|
+
prediction_uuid: UUID of the prediction
|
|
213
|
+
ground_truth: Correct label/value
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
Server response
|
|
217
|
+
"""
|
|
218
|
+
feedback = cls(
|
|
219
|
+
prediction_uuid=prediction_uuid,
|
|
220
|
+
ground_truth=ground_truth,
|
|
221
|
+
_ctx=ctx,
|
|
222
|
+
)
|
|
223
|
+
return feedback.send()
|
|
224
|
+
|
|
225
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
226
|
+
"""Convert to dictionary representation."""
|
|
227
|
+
return {
|
|
228
|
+
'prediction_uuid': self.prediction_uuid,
|
|
229
|
+
'ground_truth': self.ground_truth,
|
|
230
|
+
'feedback_timestamp': self.feedback_timestamp.isoformat() if self.feedback_timestamp else None,
|
|
231
|
+
}
|