Dante commited on
Commit
cd1a96b
·
1 Parent(s): 88e1074

statistic model

Browse files
Files changed (1) hide show
  1. StatisticalBaseModel.py +131 -0
StatisticalBaseModel.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Tuple, TypedDict, Optional
2
+ import datetime
3
+
4
+
5
+ class ProcessedSynapse(TypedDict):
6
+ id: Optional[str]
7
+ nextplace_id: Optional[str]
8
+ property_id: Optional[str]
9
+ listing_id: Optional[str]
10
+ address: Optional[str]
11
+ city: Optional[str]
12
+ state: Optional[str]
13
+ zip_code: Optional[str]
14
+ price: Optional[float]
15
+ beds: Optional[int]
16
+ baths: Optional[float]
17
+ sqft: Optional[int]
18
+ lot_size: Optional[int]
19
+ year_built: Optional[int]
20
+ days_on_market: Optional[int]
21
+ latitude: Optional[float]
22
+ longitude: Optional[float]
23
+ property_type: Optional[str]
24
+ last_sale_date: Optional[str]
25
+ hoa_dues: Optional[float]
26
+ query_date: Optional[str]
27
+ market: Optional[str]
28
+
29
+
30
+ class StatisticalBaseModel:
31
+
32
+ def __init__(self):
33
+ self._load_model()
34
+
35
+ def _load_model(self):
36
+ """
37
+ Perform any actions needed to load the model.
38
+ EX: Establish API connections, download an ML model for inference, etc...
39
+ """
40
+ print("Loading model...")
41
+ # Optional model loading
42
+ print("Model loaded.")
43
+
44
+ def _get_average_for_market(self, market: str) -> int:
45
+ """
46
+ Get the average days on market for a house in a given market
47
+ :param market: the housing market
48
+ :return: the average days on market
49
+ """
50
+ # You probably want to update this based on the current season. Houses sell faster in the summer.
51
+ # Add more logic for other housing markets!
52
+ if market == 'San Francisco':
53
+ return 23
54
+ elif market == 'Los Angeles':
55
+ return 68
56
+ elif market == 'Seattle':
57
+ return 27
58
+ elif market == 'Austin':
59
+ return 78
60
+ elif market == 'Houston':
61
+ return 73
62
+ elif market == 'Chicago':
63
+ return 25
64
+ elif market == 'New York':
65
+ return 20
66
+ elif market == 'Denver':
67
+ return 24
68
+ return 34
69
+
70
+
71
+ def _sale_date_predictor(self, input_data: ProcessedSynapse):
72
+ """
73
+ Calculate the expected sale date based on the national average
74
+ :param days_on_market: number of days this house has been on the market
75
+ :return: the predicted sale date, based on the national average of 34 days
76
+ """
77
+ if 'days_on_market' not in input_data:
78
+ return datetime.date.today() + datetime.timedelta(days=1)
79
+
80
+ if 'market' not in input_data:
81
+ average = 34
82
+
83
+ else:
84
+ average = self._get_average_for_market(input_data['market'])
85
+
86
+ days_on_market = input_data['days_on_market']
87
+ if days_on_market < average:
88
+ days_until_sale = average - days_on_market
89
+ sale_date = datetime.date.today() + datetime.timedelta(days=days_until_sale)
90
+ return sale_date
91
+ else:
92
+ return datetime.date.today() + datetime.timedelta(days=1)
93
+
94
+ def _get_price_multiplier(self, market: str) -> float:
95
+ """
96
+ Calculate the price multiplier based on the market
97
+ :param market: the marked the house is in
98
+ :return: the multiplier for the predicted price
99
+ """
100
+ # You may want to add more logic to check zipcode for more precise price multipliers
101
+ # Add more logic for other housing markets!
102
+ if market == 'San Francisco':
103
+ return 1.18 # 18% above listing
104
+ elif market == 'Los Angeles':
105
+ return 1.2 # 22% above listing
106
+ elif market == 'Seattle':
107
+ return 1.13 # 13% above listing
108
+ elif market == 'Austin':
109
+ return 1.11 # 11% above listing
110
+ elif market == 'Houston':
111
+ return 1.15 # 15% above listing
112
+ elif market == 'Chicago':
113
+ return 1.12 # 12% above listing
114
+ elif market == 'New York':
115
+ return 1.05 # 5% above listing
116
+ elif market == 'Denver':
117
+ return 1.11 # 11% above listing
118
+ return 1.0
119
+
120
+ def run_inference(self, input_data: ProcessedSynapse) -> Tuple[float, str]:
121
+ """
122
+ Predict the sale price and sale date for the house represented by `input_data`
123
+ :param input_data: a formatted Synapse from the validator, representing a currently listed house
124
+ :return: the predicted sale price and predicted sale date for this home
125
+ """
126
+ listing_price = float(input_data['price']) if 'price' in input_data else 1.0
127
+ sale_multiplier = self._get_price_multiplier(input_data['market']) if 'market' in input_data else 1.0
128
+ predicted_sale_price = listing_price * sale_multiplier
129
+ predicted_sale_date = self._sale_date_predictor(input_data)
130
+ predicted_sale_date = predicted_sale_date.strftime("%Y-%m-%d")
131
+ return predicted_sale_price, predicted_sale_date