featrixsphere 0.1.583__py3-none-any.whl → 0.2.1314__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 +3 -3
- featrixsphere/cli.py +148 -23
- featrixsphere/client.py +3432 -4284
- featrixsphere/test_client.py +311 -0
- {featrixsphere-0.1.583.dist-info → featrixsphere-0.2.1314.dist-info}/METADATA +46 -7
- featrixsphere-0.2.1314.dist-info/RECORD +9 -0
- featrixsphere/client_movie_v2.py +0 -489
- featrixsphere/prediction_grid.py +0 -629
- featrixsphere-0.1.583.dist-info/RECORD +0 -10
- {featrixsphere-0.1.583.dist-info → featrixsphere-0.2.1314.dist-info}/WHEEL +0 -0
- {featrixsphere-0.1.583.dist-info → featrixsphere-0.2.1314.dist-info}/entry_points.txt +0 -0
- {featrixsphere-0.1.583.dist-info → featrixsphere-0.2.1314.dist-info}/top_level.txt +0 -0
featrixsphere/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ The Featrix Sphere API automatically builds neural embedding spaces from your da
|
|
|
7
7
|
and trains high-accuracy predictors without requiring any ML expertise.
|
|
8
8
|
Just upload your data, specify what you want to predict, and get a production API endpoint.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
NEW: Beautiful training visualization with matplotlib plotting!
|
|
11
11
|
|
|
12
12
|
Example:
|
|
13
13
|
>>> from featrixsphere import FeatrixSphereClient
|
|
@@ -29,7 +29,7 @@ Example:
|
|
|
29
29
|
>>> result = client.predict(session.session_id, {"feature": "value"})
|
|
30
30
|
>>> print(result['prediction'])
|
|
31
31
|
>>>
|
|
32
|
-
>>> #
|
|
32
|
+
>>> # NEW: Visualize training progress with beautiful plots!
|
|
33
33
|
>>> fig = client.plot_training_loss(session.session_id, style='notebook')
|
|
34
34
|
>>> # Returns matplotlib Figure - perfect for Jupyter notebooks!
|
|
35
35
|
>>>
|
|
@@ -38,7 +38,7 @@ Example:
|
|
|
38
38
|
... labels=['Experiment A', 'Experiment B'])
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
__version__ = "0.
|
|
41
|
+
__version__ = "0.2.1314"
|
|
42
42
|
__author__ = "Featrix"
|
|
43
43
|
__email__ = "support@featrix.com"
|
|
44
44
|
__license__ = "MIT"
|
featrixsphere/cli.py
CHANGED
|
@@ -19,18 +19,23 @@ def main():
|
|
|
19
19
|
epilog="""
|
|
20
20
|
Examples:
|
|
21
21
|
# Upload data and create session
|
|
22
|
-
featrix upload data.csv --server
|
|
22
|
+
featrix upload data.csv --server YOUR_SERVER_URL
|
|
23
23
|
|
|
24
24
|
# Test predictions on CSV
|
|
25
|
-
featrix test SESSION_ID test.csv target_column --server
|
|
25
|
+
featrix test SESSION_ID test.csv target_column --server YOUR_SERVER_URL
|
|
26
26
|
|
|
27
|
-
# Make single prediction
|
|
28
|
-
featrix predict SESSION_ID '{"feature": "value"}' --server
|
|
27
|
+
# Make single prediction from JSON
|
|
28
|
+
featrix predict SESSION_ID '{"feature": "value"}' --server YOUR_SERVER_URL
|
|
29
|
+
|
|
30
|
+
# Make predictions from CSV file
|
|
31
|
+
featrix predict SESSION_ID test.csv --server YOUR_SERVER_URL --sample-size 50
|
|
29
32
|
"""
|
|
30
33
|
)
|
|
31
34
|
|
|
32
|
-
parser.add_argument("--server", default="
|
|
35
|
+
parser.add_argument("--server", default="https://sphere-api.featrix.com",
|
|
33
36
|
help="Featrix Sphere server URL")
|
|
37
|
+
parser.add_argument("--compute-cluster", type=str, default=None,
|
|
38
|
+
help="Compute cluster port for X-Sphere-Compute header")
|
|
34
39
|
parser.add_argument("--version", action="version",
|
|
35
40
|
version=f"featrixsphere {__import__('featrixsphere').__version__}")
|
|
36
41
|
|
|
@@ -53,7 +58,11 @@ Examples:
|
|
|
53
58
|
# Predict command
|
|
54
59
|
predict_parser = subparsers.add_parser("predict", help="Make single prediction")
|
|
55
60
|
predict_parser.add_argument("session_id", help="Session ID")
|
|
56
|
-
predict_parser.add_argument("
|
|
61
|
+
predict_parser.add_argument("input", help="JSON record or CSV file to predict")
|
|
62
|
+
predict_parser.add_argument("--sample-size", type=int, default=1000,
|
|
63
|
+
help="Number of records to predict from CSV (default: 1000)")
|
|
64
|
+
predict_parser.add_argument("-v", "--verbose", action="store_true",
|
|
65
|
+
help="Print full results structure")
|
|
57
66
|
|
|
58
67
|
# Status command
|
|
59
68
|
status_parser = subparsers.add_parser("status", help="Check session status")
|
|
@@ -66,7 +75,7 @@ Examples:
|
|
|
66
75
|
return 1
|
|
67
76
|
|
|
68
77
|
try:
|
|
69
|
-
client = FeatrixSphereClient(args.server)
|
|
78
|
+
client = FeatrixSphereClient(args.server, compute_cluster=args.compute_cluster)
|
|
70
79
|
|
|
71
80
|
if args.command == "upload":
|
|
72
81
|
return cmd_upload(client, args)
|
|
@@ -137,28 +146,144 @@ def cmd_test(client, args):
|
|
|
137
146
|
def cmd_predict(client, args):
|
|
138
147
|
"""Handle predict command."""
|
|
139
148
|
import json
|
|
149
|
+
import pandas as pd
|
|
150
|
+
from pathlib import Path
|
|
151
|
+
|
|
152
|
+
input_path = Path(args.input)
|
|
140
153
|
|
|
154
|
+
# Check if input is a CSV file
|
|
155
|
+
if input_path.exists() and input_path.suffix.lower() == '.csv':
|
|
156
|
+
print(f"📊 Loading CSV file: {input_path}")
|
|
157
|
+
try:
|
|
158
|
+
df = pd.read_csv(input_path)
|
|
159
|
+
print(f" Loaded {len(df)} records")
|
|
160
|
+
|
|
161
|
+
# Sample records if requested (default is 1000, so only sample if explicitly set lower)
|
|
162
|
+
if args.sample_size < len(df):
|
|
163
|
+
df = df.sample(n=args.sample_size, random_state=42)
|
|
164
|
+
print(f" Sampling {len(df)} records for prediction")
|
|
165
|
+
|
|
166
|
+
# Remove target column to avoid warnings
|
|
167
|
+
target_column = 'Cancellation Non Renewal'
|
|
168
|
+
if target_column in df.columns:
|
|
169
|
+
df = df.drop(columns=[target_column])
|
|
170
|
+
print(f" Removed target column '{target_column}' from prediction data")
|
|
171
|
+
|
|
172
|
+
print(f"\n🎯 Making predictions for {len(df)} records...")
|
|
173
|
+
|
|
174
|
+
# Make individual predictions (simpler and more reliable)
|
|
175
|
+
results = []
|
|
176
|
+
for i, (_, row) in enumerate(df.iterrows()):
|
|
177
|
+
record = row.to_dict()
|
|
178
|
+
print(f" Predicting record {i+1}/{len(df)}...", end=" ")
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
result = client.predict(args.session_id, record)
|
|
182
|
+
|
|
183
|
+
# Extract prediction from response
|
|
184
|
+
if 'results' in result:
|
|
185
|
+
prediction = result['results']
|
|
186
|
+
# Get top prediction
|
|
187
|
+
predicted_class = max(prediction, key=prediction.get)
|
|
188
|
+
confidence = prediction[predicted_class]
|
|
189
|
+
elif 'metadata' in result:
|
|
190
|
+
# Use metadata if available (server already computed highest probability)
|
|
191
|
+
predicted_class = result['metadata'].get('predicted_class', 'Unknown')
|
|
192
|
+
confidence = result['metadata'].get('confidence', 0.0)
|
|
193
|
+
prediction = {predicted_class: confidence}
|
|
194
|
+
else:
|
|
195
|
+
raise ValueError("No prediction results found in response")
|
|
196
|
+
|
|
197
|
+
results.append({
|
|
198
|
+
'record': i+1,
|
|
199
|
+
'prediction': predicted_class,
|
|
200
|
+
'confidence': confidence*100
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
if args.verbose:
|
|
204
|
+
print(f"→ {predicted_class} ({confidence*100:.6f}%)")
|
|
205
|
+
print(f" Full results: {prediction}")
|
|
206
|
+
else:
|
|
207
|
+
print(f"→ {predicted_class} ({confidence*100:.6f}%)")
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
print(f"❌ Error: {e}")
|
|
211
|
+
results.append({
|
|
212
|
+
'record': i+1,
|
|
213
|
+
'prediction': 'ERROR',
|
|
214
|
+
'confidence': 0
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
# Summary
|
|
218
|
+
print(f"\n📈 Prediction Summary:")
|
|
219
|
+
successful = [r for r in results if r['prediction'] != 'ERROR']
|
|
220
|
+
if successful:
|
|
221
|
+
avg_confidence = sum(r['confidence'] for r in successful) / len(successful)
|
|
222
|
+
print(f" ✅ {len(successful)}/{len(results)} successful predictions")
|
|
223
|
+
print(f" 📊 Average confidence: {avg_confidence:.6f}%")
|
|
224
|
+
|
|
225
|
+
# Show prediction distribution
|
|
226
|
+
from collections import Counter
|
|
227
|
+
pred_counts = Counter(r['prediction'] for r in successful)
|
|
228
|
+
print(f" 📋 Prediction distribution:")
|
|
229
|
+
for pred, count in pred_counts.most_common():
|
|
230
|
+
pct = (count / len(successful)) * 100
|
|
231
|
+
print(f" {pred}: {count} ({pct:.1f}%)")
|
|
232
|
+
|
|
233
|
+
if args.verbose:
|
|
234
|
+
print(f"\n🔍 Full Results Structure:")
|
|
235
|
+
for result in successful:
|
|
236
|
+
print(f" Record {result['record']}: {result}")
|
|
237
|
+
|
|
238
|
+
return 0
|
|
239
|
+
|
|
240
|
+
except Exception as e:
|
|
241
|
+
print(f"❌ Error loading CSV: {e}")
|
|
242
|
+
return 1
|
|
243
|
+
|
|
244
|
+
# Handle JSON record
|
|
141
245
|
try:
|
|
142
|
-
record = json.loads(args.
|
|
246
|
+
record = json.loads(args.input)
|
|
143
247
|
except json.JSONDecodeError as e:
|
|
144
|
-
print(f"Invalid JSON record: {e}")
|
|
248
|
+
print(f"❌ Invalid JSON record: {e}")
|
|
249
|
+
print("💡 Tip: Use quotes around JSON: '{\"feature\": \"value\"}'")
|
|
145
250
|
return 1
|
|
146
251
|
|
|
147
|
-
print(f"Making prediction for session {args.session_id}...")
|
|
148
|
-
|
|
149
|
-
result = client.make_prediction(args.session_id, record)
|
|
150
|
-
prediction = result['prediction']
|
|
252
|
+
print(f"🎯 Making prediction for session {args.session_id}...")
|
|
151
253
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
254
|
+
try:
|
|
255
|
+
result = client.predict(args.session_id, record)
|
|
256
|
+
|
|
257
|
+
# Extract prediction from response
|
|
258
|
+
if 'results' in result:
|
|
259
|
+
prediction = result['results']
|
|
260
|
+
|
|
261
|
+
print(f"\n🎯 Prediction:")
|
|
262
|
+
for class_name, confidence in prediction.items():
|
|
263
|
+
print(f" {class_name}: {confidence*100:.2f}%")
|
|
264
|
+
|
|
265
|
+
# Show top prediction
|
|
266
|
+
predicted_class = max(prediction, key=prediction.get)
|
|
267
|
+
confidence = prediction[predicted_class]
|
|
268
|
+
print(f"\n→ Predicted: {predicted_class} ({confidence*100:.1f}% confidence)")
|
|
269
|
+
|
|
270
|
+
elif 'metadata' in result:
|
|
271
|
+
# Use metadata if available (server already computed highest probability)
|
|
272
|
+
predicted_class = result['metadata'].get('predicted_class', 'Unknown')
|
|
273
|
+
confidence = result['metadata'].get('confidence', 0.0)
|
|
274
|
+
|
|
275
|
+
print(f"\n🎯 Prediction:")
|
|
276
|
+
print(f" {predicted_class}: {confidence*100:.2f}%")
|
|
277
|
+
print(f"\n→ Predicted: {predicted_class} ({confidence*100:.1f}% confidence)")
|
|
278
|
+
|
|
279
|
+
else:
|
|
280
|
+
raise ValueError("No prediction results found in response")
|
|
281
|
+
|
|
282
|
+
return 0
|
|
283
|
+
|
|
284
|
+
except Exception as e:
|
|
285
|
+
print(f"❌ Prediction failed: {e}")
|
|
286
|
+
return 1
|
|
162
287
|
|
|
163
288
|
|
|
164
289
|
def cmd_status(client, args):
|