-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit_db.py
More file actions
149 lines (124 loc) · 3.77 KB
/
Copy pathinit_db.py
File metadata and controls
149 lines (124 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env python3
import pandas as pd
from sqlalchemy import text
from pathlib import Path
import numpy as np
from core.db.models.user import User
from core.db.models.listing import Listing
from core.db.models.base import Base
from core.db.session import get_session, get_engine
INITIAL_USER_PREFERENCE = np.array(
[
0.01295045, # price range [0,1]
0.53571429, # age range [0,1]
1.0, # manual
0.0, # automatic
1.0, # petrol
0.0, # diesel
0.0, # cNG
0.0, # lPG
0.0, # electric
0.0, # brands:
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0, # Hyundai
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
]
)
def initialize_db():
with get_session() as session:
session.execute(text("CREATE EXTENSION IF NOT EXISTS vector;"))
Base.metadata.create_all(get_engine())
def populate_with_random_users(count: int):
def generate_user(user_id: int):
return {
"email": f"john{user_id}@example.com",
"first_name": f"John{user_id}",
"surname": "Doe",
"preference": INITIAL_USER_PREFERENCE,
}
with get_session() as session:
for i in range(count):
user = generate_user(i)
session.add(User(**user))
session.commit()
def __listings_to_features(listings: pd.DataFrame) -> pd.DataFrame:
"""Vectorize listing features."""
# Numerical features
year_min, year_max = 1992, 2020
norm_year = (listings["year"] - year_min) / (year_max - year_min)
price_min, price_max = (
listings["selling_price"].min(),
listings["selling_price"].max(),
)
norm_price = (listings["selling_price"] - price_min) / (
price_max - price_min
)
features = {
"price": norm_price,
"year": norm_year,
}
# Categorical features
for category in listings["transmission"].unique():
category_vector = listings["transmission"] == category
features[f"transmission_{category}"] = category_vector.astype(
np.float64
)
for category in listings["fuel"].unique():
category_vector = listings["fuel"] == category
features[f"fuel_{category}"] = category_vector.astype(np.float64)
for category in listings["brand"].unique():
category_vector = listings["brand"].apply(lambda x: category in x)
features[f"brand_{category}"] = category_vector.astype(np.float64)
return pd.DataFrame(features)
def populate_with_listings(listings_path: Path):
"""Read listings from the given csv file, enrich them with feature vectors
and insert into the Listing psql table.
"""
def add_brand(listing):
"""Extract brand from car full name."""
if "Land" in listing["name"]:
return "Land Rover"
else:
return listing["name"].split()[0]
df_listings = pd.read_csv(listings_path)
df_listings["brand"] = df_listings.apply(add_brand, axis=1)
df_features = __listings_to_features(df_listings)
df_listings["features"] = df_listings.apply(
lambda row: df_features.iloc[row.name].to_numpy(), axis=1
)
listings = df_listings.to_dict(orient="records")
with get_session() as session:
for item in listings:
session.add(Listing(**item))
session.commit()
def drop_db():
Base.metadata.drop_all(get_engine())
if __name__ == "__main__":
initialize_db()
populate_with_random_users(50)
populate_with_listings(Path("backend/assets/car_data.csv"))