theDavidGuy commited on
Commit
560ed18
·
verified ·
1 Parent(s): 7914417

Update valuation

Browse files
Files changed (1) hide show
  1. valuation +68 -0
valuation CHANGED
@@ -66,3 +66,71 @@ def deal_score(predicted_resale: float, ask: float, fee_rate: float=0.13, ship:
66
  elif profit >= 5: label = "Meh"
67
  else: label = "Pass"
68
  return round(fees,2), round(net,2), round(profit,2), round(margin,2), label
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  elif profit >= 5: label = "Meh"
67
  else: label = "Pass"
68
  return round(fees,2), round(net,2), round(profit,2), round(margin,2), label
69
+ import pandas as pd
70
+ from sklearn.feature_extraction.text import TfidfVectorizer
71
+ from sklearn.pipeline import Pipeline
72
+ from sklearn.compose import ColumnTransformer
73
+ from sklearn.preprocessing import OneHotEncoder
74
+ from sklearn.linear_model import Ridge
75
+
76
+ # Tiny seed comps to learn rough resale from titles/brands
77
+ SEED = [
78
+ ("Nintendo Wii Console with controllers","Electronics","Nintendo","Used-Good",85),
79
+ ("Vintage Pyrex mixing bowl set","Home & Kitchen","Pyrex","Used-Good",120),
80
+ ("Levi's 501 jeans men's 34x32","Clothing","Levi's","Used-Good",28),
81
+ ("Patagonia Synchilla fleece pullover M","Clothing","Patagonia","Used-Good",45),
82
+ ("KitchenAid Artisan stand mixer","Home & Kitchen","KitchenAid","Used-Good",220),
83
+ ("Bose QuietComfort 35 headphones","Electronics","Bose","Used-Good",140),
84
+ ("Apple iPhone 11 128GB unlocked","Electronics","Apple","Used-Good",240),
85
+ ("Herman Miller Aeron chair size B","Furniture","Herman Miller","Used-Good",500),
86
+ ("Sony PlayStation 2 console slim","Electronics","Sony","Used-Good",75),
87
+ ("Le Creuset dutch oven 5.5 qt","Home & Kitchen","Le Creuset","Used-Good",240),
88
+ ("Sony Walkman cassette player","Electronics","Sony","Used-Good",95),
89
+ ("All-Clad stainless pan 10 inch","Home & Kitchen","All-Clad","Used-Good",55),
90
+ ("Coach leather handbag crossbody","Accessories","Coach","Used-Good",65),
91
+ ("Seiko 5 automatic watch SNK809","Accessories","Seiko","Used-Good",95),
92
+ ]
93
+
94
+ def _seed_df():
95
+ return pd.DataFrame(SEED, columns=["title","category","brand","condition","price"])
96
+
97
+ class DealValuator:
98
+ def __init__(self, df: pd.DataFrame | None = None):
99
+ self.df = df if df is not None else _seed_df()
100
+ self.model = self._train(self.df)
101
+
102
+ def _train(self, df: pd.DataFrame):
103
+ text_features = 'title'
104
+ cat_features = ['category','brand','condition']
105
+ pre = ColumnTransformer([
106
+ ('t', TfidfVectorizer(ngram_range=(1,2), min_df=1), text_features),
107
+ ('c', OneHotEncoder(handle_unknown='ignore'), cat_features),
108
+ ])
109
+ model = Pipeline([('pre', pre), ('reg', Ridge(alpha=1.0))])
110
+ X = df[['title','category','brand','condition']]
111
+ y = df['price']
112
+ model.fit(X, y)
113
+ return model
114
+
115
+ def predict_resale(self, title: str, category: str | None = None,
116
+ brand: str | None = None, condition: str = 'Used-Good') -> float:
117
+ X = pd.DataFrame([{
118
+ 'title': title or '',
119
+ 'category': category or 'Unknown',
120
+ 'brand': brand or 'Unknown',
121
+ 'condition': condition or 'Used-Good'
122
+ }])
123
+ pred = float(self.model.predict(X)[0])
124
+ return max(5.0, round(pred, 2))
125
+
126
+ def deal_score(predicted_resale: float, ask: float, fee_rate: float = 0.13, ship: float = 12.0):
127
+ fees = predicted_resale * fee_rate
128
+ net = predicted_resale - fees - ship
129
+ profit = net - ask
130
+ margin = (profit / ask) if ask > 0 else 0.0
131
+ if profit >= 50 and margin >= 0.8: label = "Home Run"
132
+ elif profit >= 25 and margin >= 0.5: label = "Great"
133
+ elif profit >= 10 and margin >= 0.3: label = "Good"
134
+ elif profit >= 5: label = "Meh"
135
+ else: label = "Pass"
136
+ return round(fees,2), round(net,2), round(profit,2), round(margin,2), label