jasifk commited on
Commit
681ca4d
·
verified ·
1 Parent(s): 6cc00a2

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
README.md CHANGED
@@ -1,12 +1,14 @@
1
- ---
2
- title: Dating Model
3
- emoji:
4
- colorFrom: green
5
- colorTo: gray
6
- sdk: gradio
7
- sdk_version: 5.20.1
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
+ ---
2
+ title: dating-model
3
+ emoji: 🦀
4
+ colorFrom: red
5
+ colorTo: pink
6
+ sdk: gradio
7
+ sdk_version: 5.20.1
8
+ app_file: app.py
9
+ pinned: false
10
+ license: apache-2.0
11
+ short_description: Dating App Swipe Predictor
12
+ ---
13
+
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
__pycache__/utils.cpython-312.pyc ADDED
Binary file (459 Bytes). View file
 
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import joblib
3
+ import numpy as np
4
+ import os
5
+ import pandas as pd
6
+
7
+ # Load model and scaler
8
+ model_path = os.path.join(os.path.dirname(__file__), "dating_model.joblib")
9
+ scaler_path = os.path.join(os.path.dirname(__file__), "dating_scaler.joblib")
10
+
11
+ model = joblib.load(model_path)
12
+ scaler = joblib.load(scaler_path)
13
+
14
+ def predict(
15
+ hobbies_matched,
16
+ is_job_matched,
17
+ is_edu_matched,
18
+ is_religion_match,
19
+ is_interested_in_match,
20
+ profile_completion,
21
+ no_of_photos,
22
+ miles_away,
23
+ age
24
+ ):
25
+ """
26
+ Make prediction with the model
27
+ """
28
+ # Convert inputs to appropriate format
29
+ features = np.array([[
30
+ hobbies_matched,
31
+ int(is_job_matched),
32
+ int(is_edu_matched),
33
+ int(is_religion_match),
34
+ int(is_interested_in_match),
35
+ profile_completion,
36
+ no_of_photos,
37
+ miles_away,
38
+ age
39
+ ]])
40
+
41
+ # Scale the features
42
+ scaled_features = scaler.transform(features)
43
+
44
+ # Make prediction
45
+ prediction = model.predict(scaled_features)[0]
46
+
47
+ if prediction == 1:
48
+ return "Swipe Right (Like)"
49
+ else:
50
+ return "Swipe Left (Pass)"
51
+
52
+ # Create the interface
53
+ with gr.Blocks(title="Dating App Swipe Predictor") as demo:
54
+ gr.Markdown("# Dating App Swipe Predictor")
55
+ gr.Markdown("Enter profile information to predict whether a user will swipe right (like) or left (pass).")
56
+
57
+ with gr.Row():
58
+ with gr.Column():
59
+ hobbies_matched = gr.Slider(minimum=0, maximum=10, step=1, label="Number of Matched Hobbies")
60
+ is_job_matched = gr.Checkbox(label="Jobs Match?")
61
+ is_edu_matched = gr.Checkbox(label="Education Level Matches?")
62
+ is_religion_match = gr.Checkbox(label="Religion Matches?")
63
+ is_interested_in_match = gr.Checkbox(label="Interests Match?")
64
+ profile_completion = gr.Slider(minimum=0, maximum=100, step=1, label="Profile Completion %")
65
+ no_of_photos = gr.Slider(minimum=0, maximum=10, step=1, label="Number of Photos")
66
+ miles_away = gr.Slider(minimum=0, maximum=100, step=1, label="Miles Away")
67
+ age = gr.Slider(minimum=18, maximum=80, step=1, label="Age")
68
+
69
+ predict_btn = gr.Button("Predict Swipe")
70
+
71
+ with gr.Column():
72
+ output = gr.Textbox(label="Prediction Result")
73
+
74
+ predict_btn.click(
75
+ fn=predict,
76
+ inputs=[
77
+ hobbies_matched,
78
+ is_job_matched,
79
+ is_edu_matched,
80
+ is_religion_match,
81
+ is_interested_in_match,
82
+ profile_completion,
83
+ no_of_photos,
84
+ miles_away,
85
+ age
86
+ ],
87
+ outputs=output
88
+ )
89
+
90
+ gr.Markdown("""
91
+ ## About This Model
92
+
93
+ This model predicts whether a user will swipe right (like) or left (pass) on a dating app profile based on various features. The model was trained on historical swiping data and uses logistic regression with mini-batch gradient descent.
94
+
95
+ ### Features Used:
96
+ - Number of matched hobbies
97
+ - Job match status
98
+ - Education match status
99
+ - Religion match status
100
+ - Interest match status
101
+ - Profile completion percentage
102
+ - Number of profile photos
103
+ - Distance (in miles)
104
+ - Age
105
+
106
+ ### Model Performance:
107
+ - Accuracy: 85.2%
108
+ - Precision: 83.7%
109
+ - Recall: 79.1%
110
+
111
+ Note: The model provides predictions based on patterns in historical data but individual preferences may vary.
112
+ """)
113
+
114
+ # Launch the app
115
+ if __name__ == "__main__":
116
+ demo.launch(share=True)
dating_model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7496ac00b27490ba347b11ab8aa6d3e48d26421aba833f0021b915c72cc5f26c
3
+ size 535
dating_model/__init__.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ """
2
+ Dating App Swipe Prediction Package
3
+ """
4
+
5
+ from .models import LogisticRegressionMBGD
6
+
7
+ __version__ = '0.1.0'
dating_model/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (300 Bytes). View file
 
dating_model/__pycache__/models.cpython-312.pyc ADDED
Binary file (10.8 kB). View file
 
dating_model/__pycache__/preprocessing.cpython-312.pyc ADDED
Binary file (3.28 kB). View file
 
dating_model/dating_model_package.egg-info/PKG-INFO ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.2
2
+ Name: dating_model_package
3
+ Version: 0.1.0
4
+ Summary: A package for dating app swipe prediction using logistic regression
5
+ Author: Jasif Shameem K
6
+ Author-email: jasifkolangath@gmail.com
7
+ Keywords: machine learning,dating app,prediction
8
+ Requires-Python: >=3.7
9
+ Requires-Dist: numpy>=1.26.4
10
+ Requires-Dist: pandas>=1.3.0
11
+ Requires-Dist: scikit-learn>=1.6.0
12
+ Requires-Dist: sqlalchemy>=1.4.0
13
+ Requires-Dist: joblib>=1.1.0
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: keywords
17
+ Dynamic: requires-dist
18
+ Dynamic: requires-python
19
+ Dynamic: summary
dating_model/dating_model_package.egg-info/SOURCES.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ setup.py
2
+ dating_model_package.egg-info/PKG-INFO
3
+ dating_model_package.egg-info/SOURCES.txt
4
+ dating_model_package.egg-info/dependency_links.txt
5
+ dating_model_package.egg-info/requires.txt
6
+ dating_model_package.egg-info/top_level.txt
dating_model/dating_model_package.egg-info/dependency_links.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
dating_model/dating_model_package.egg-info/requires.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ numpy>=1.26.4
2
+ pandas>=1.3.0
3
+ scikit-learn>=1.6.0
4
+ sqlalchemy>=1.4.0
5
+ joblib>=1.1.0
dating_model/dating_model_package.egg-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
dating_model/models.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import numpy as np
3
+ from sklearn.metrics import accuracy_score, precision_score, recall_score
4
+
5
+ class LogisticRegressionMBGD:
6
+ """
7
+ Logistic Regression using Gradient Descent for dating app swipe prediction
8
+ """
9
+ def __init__(self, learning_rate=0.01, n_iterations=1000, random_state=42, _reg_lambda=1):
10
+ self.learning_rate = learning_rate
11
+ self.n_iterations = n_iterations
12
+ self.random_state = random_state
13
+ self.weights = None
14
+ self.bias = None
15
+ self.cost_history = []
16
+ self._reg_lambda = _reg_lambda
17
+
18
+ def sigmoid(self, z):
19
+ """
20
+ Sigmoid activation function
21
+ """
22
+ return 1 / (1 + np.exp(-z))
23
+
24
+ def train(self, X, y):
25
+ """
26
+ Train the model using mini-batch gradient descent
27
+
28
+ Parameters:
29
+ X : numpy array of shape (m_samples, n_features)
30
+ Training data
31
+ y : numpy array of shape (m_samples,)
32
+ Target values (0 or 1)
33
+ """
34
+ self.weights = np.zeros(X.shape[1])
35
+ self.bias = 0
36
+ np.random.seed(self.random_state)
37
+ initial_w = np.random.rand(X.shape[1])-0.5
38
+ initial_b = 1.
39
+
40
+ w, b, _, _ = self.gradient_descent(X, y, initial_w, initial_b, self.compute_cost_reg, self.compute_gradient_reg, self.learning_rate, self.n_iterations, self._reg_lambda)
41
+
42
+ self.weights = w
43
+ self.bias = b
44
+
45
+ return w, b
46
+
47
+ def predict(self, X, w=None, b=None):
48
+ """
49
+ Predict whether the label is 0 or 1 using learned logistic
50
+ regression parameters w
51
+
52
+ Args:
53
+ X : (ndarray Shape (m,n)) data, m examples by n features
54
+ w : (ndarray Shape (n,)) values of parameters of the model (optional)
55
+ b : (scalar) value of bias parameter of the model (optional)
56
+
57
+ Returns:
58
+ p : (ndarray (m,)) The predictions for X using a threshold at 0.5
59
+ """
60
+ # If weights and bias are not provided, use the model's attributes
61
+ if w is None:
62
+ w = self.weights
63
+ if b is None:
64
+ b = self.bias
65
+
66
+ # number of training examples
67
+ m, n = X.shape
68
+ p = np.zeros(m)
69
+
70
+ for i in range(m):
71
+ z = np.dot(w, X[i]) + b
72
+ f_w = self.sigmoid(z)
73
+ p[i] = f_w >= 0.5
74
+
75
+ return p
76
+
77
+ def compute_cost(self, X, y, w, b):
78
+ """
79
+ Computes the cost over all examples
80
+ Args:
81
+ X : (ndarray Shape (m,n)) data, m examples by n features
82
+ y : (ndarray Shape (m,)) target value
83
+ w : (ndarray Shape (n,)) values of parameters of the model
84
+ b : (scalar) value of bias parameter of the model
85
+ *argv : unused, for compatibility with regularized version below
86
+ Returns:
87
+ total_cost : (scalar) cost
88
+ """
89
+ m, n = X.shape
90
+ total_cost = 0
91
+ for i in range(m):
92
+ z_i = np.dot(X[i], w) + b
93
+ f_wb_i = self.sigmoid(z_i)
94
+ total_cost += -y[i]*np.log(f_wb_i) - (1-y[i])*np.log(1-f_wb_i)
95
+ total_cost = total_cost / m
96
+
97
+ return total_cost
98
+
99
+ def compute_gradient(self, X, y, w, b):
100
+ """
101
+ Computes the gradient for logistic regression
102
+
103
+ Args:
104
+ X : (ndarray Shape (m,n)) data, m examples by n features
105
+ y : (ndarray Shape (m,)) target value
106
+ w : (ndarray Shape (n,)) values of parameters of the model
107
+ b : (scalar) value of bias parameter of the model
108
+ *argv : unused, for compatibility with regularized version below
109
+ Returns
110
+ dj_dw : (ndarray Shape (n,)) The gradient of the cost w.r.t. the parameters w.
111
+ dj_db : (scalar) The gradient of the cost w.r.t. the parameter b.
112
+ """
113
+ m, n = X.shape
114
+ dj_dw = np.zeros(w.shape)
115
+ dj_db = 0.
116
+
117
+ for i in range(m):
118
+ f_wb_i = self.sigmoid(np.dot(X[i],w) + b)
119
+ err_i = f_wb_i - y[i]
120
+ for j in range(n):
121
+ dj_dw[j] = dj_dw[j] + err_i * X[i,j]
122
+ dj_db = dj_db + err_i
123
+ dj_dw = dj_dw/m
124
+ dj_db = dj_db/m
125
+
126
+ return dj_db, dj_dw
127
+
128
+ def gradient_descent(self, X, y, w_in, b_in, cost_function, gradient_function, alpha, num_iters, lambda_):
129
+ """
130
+ Performs batch gradient descent to learn theta. Updates theta by taking
131
+ num_iters gradient steps with learning rate alpha
132
+
133
+ Args:
134
+ X : (ndarray Shape (m, n) data, m examples by n features
135
+ y : (ndarray Shape (m,)) target value
136
+ w_in : (ndarray Shape (n,)) Initial values of parameters of the model
137
+ b_in : (scalar) Initial value of parameter of the model
138
+ cost_function : function to compute cost
139
+ gradient_function : function to compute gradient
140
+ alpha : (float) Learning rate
141
+ num_iters : (int) number of iterations to run gradient descent
142
+ lambda_ : (scalar, float) regularization constant
143
+
144
+ Returns:
145
+ w : (ndarray Shape (n,)) Updated values of parameters of the model after
146
+ running gradient descent
147
+ b : (scalar) Updated value of parameter of the model after
148
+ running gradient descent
149
+ """
150
+ # number of training examples
151
+ m = len(X)
152
+
153
+ # An array to store cost J and w's at each iteration primarily for graphing later
154
+ J_history = []
155
+ w_history = []
156
+
157
+ for i in range(num_iters):
158
+ # Calculate the gradient and update the parameters
159
+ dj_db, dj_dw = gradient_function(X, y, w_in, b_in, lambda_)
160
+
161
+ # Update Parameters using w, b, alpha and gradient
162
+ w_in = w_in - alpha * dj_dw
163
+ b_in = b_in - alpha * dj_db
164
+
165
+ # Save cost J at each iteration
166
+ if i<100000: # prevent resource exhaustion
167
+ cost = cost_function(X, y, w_in, b_in, lambda_)
168
+ J_history.append(cost)
169
+
170
+ # Print cost every at intervals 10 times or as many iterations if < 10
171
+ if i% math.ceil(num_iters/10) == 0 or i == (num_iters-1):
172
+ w_history.append(w_in)
173
+ print(f"Iteration {i:4}: Cost {float(J_history[-1]):8.2f} ")
174
+
175
+ return w_in, b_in, J_history, w_history
176
+
177
+ def compute_cost_reg(self, X, y, w, b, lambda_ = 1):
178
+ """
179
+ Computes the cost over all examples
180
+ Args:
181
+ X : (ndarray Shape (m,n)) data, m examples by n features
182
+ y : (ndarray Shape (m,)) target value
183
+ w : (ndarray Shape (n,)) values of parameters of the model
184
+ b : (scalar) value of bias parameter of the model
185
+ lambda_ : (scalar, float) Controls amount of regularization
186
+ Returns:
187
+ total_cost : (scalar) cost
188
+ """
189
+ m, n = X.shape
190
+
191
+ # Calls the compute_cost function that you implemented above
192
+ cost_without_reg = self.compute_cost(X, y, w, b)
193
+
194
+ reg_cost = 0.
195
+
196
+ for i in range(n):
197
+ reg_cost += w[i]**2
198
+ reg_cost = (lambda_/(2*m)) * reg_cost
199
+
200
+ # Add the regularization cost to get the total cost
201
+ total_cost = cost_without_reg + reg_cost
202
+
203
+ return total_cost
204
+
205
+ def compute_gradient_reg(self, X, y, w, b, lambda_ = 1):
206
+ """
207
+ Computes the gradient for logistic regression with regularization
208
+
209
+ Args:
210
+ X : (ndarray Shape (m,n)) data, m examples by n features
211
+ y : (ndarray Shape (m,)) target value
212
+ w : (ndarray Shape (n,)) values of parameters of the model
213
+ b : (scalar) value of bias parameter of the model
214
+ lambda_ : (scalar,float) regularization constant
215
+ Returns
216
+ dj_db : (scalar) The gradient of the cost w.r.t. the parameter b.
217
+ dj_dw : (ndarray Shape (n,)) The gradient of the cost w.r.t. the parameters w.
218
+ """
219
+ m, n = X.shape
220
+
221
+ dj_db, dj_dw = self.compute_gradient(X, y, w, b)
222
+
223
+ for i in range(n):
224
+ dj_dw[i] += ((lambda_ / m ) * w[i])
225
+
226
+ return dj_db, dj_dw
227
+
228
+ def evaluate(self, X_test, y_test):
229
+ """
230
+ Evaluate the logistic regression model
231
+ """
232
+ y_pred = self.predict(X_test)
233
+
234
+ accuracy = accuracy_score(y_test, y_pred)
235
+ precision = precision_score(y_test, y_pred)
236
+ recall = recall_score(y_test, y_pred)
237
+
238
+ evaluation = {
239
+ 'accuracy': accuracy,
240
+ 'precision': precision,
241
+ 'recall': recall
242
+ }
243
+
244
+ return evaluation
dating_model/preprocessing.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from sklearn.model_selection import train_test_split
4
+ from sklearn.preprocessing import StandardScaler
5
+ from sqlalchemy import create_engine
6
+
7
+ def get_data_from_postgres(conn_string):
8
+ """
9
+ Fetch dating app data from PostgreSQL and prepare for model training
10
+ """
11
+ try:
12
+ print(f"Connecting to PostgreSQL database: {conn_string}")
13
+
14
+ engine = create_engine(conn_string)
15
+ print("Connection successful", engine)
16
+
17
+ query = """
18
+ SELECT
19
+ id,
20
+ hobies_matched,
21
+ is_job_matched,
22
+ is_edu_matched,
23
+ is_religion_match,
24
+ is_interested_in_match,
25
+ profile_completion,
26
+ no_of_photos,
27
+ miles_away,
28
+ user_id,
29
+ is_liked,
30
+ age
31
+ FROM
32
+ ml_data
33
+ """
34
+
35
+ df = pd.read_sql(query, engine)
36
+
37
+ print(f"Successfully fetched {len(df)} records from PostgreSQL")
38
+
39
+ bool_cols = ['is_job_matched', 'is_edu_matched', 'is_religion_match',
40
+ 'is_interested_in_match', 'is_liked']
41
+ for col in bool_cols:
42
+ if df[col].dtype == bool:
43
+ df[col] = df[col].astype(int)
44
+
45
+ return df
46
+
47
+ except Exception as e:
48
+ print(f"Error connecting to PostgreSQL database: {e}")
49
+ return None
50
+
51
+ def preprocess_data(df, test_size=0.20, random_state=42):
52
+ """
53
+ Preprocess the dating app data for logistic regression
54
+ """
55
+ data = df.copy()
56
+
57
+ # data['compatibility_score'] = (
58
+ # data['hobies_matched'] * 0.3 +
59
+ # data['is_job_matched'] * 0.1 +
60
+ # data['is_edu_matched'] * 0.1 +
61
+ # data['is_religion_match'] * 0.2 +
62
+ # data['is_interested_in_match'] * 0.3
63
+ # )
64
+
65
+ # data['miles_away_log'] = np.log1p(data['miles_away'])
66
+
67
+ # data['profile_quality'] = (data['profile_completion'] * 0.7 +
68
+ # data['no_of_photos'] * 30 * 0.3)
69
+
70
+ # data['interest_x_photos'] = data['is_interested_in_match'] * data['no_of_photos']
71
+ # data['hobbies_x_religion'] = data['hobies_matched'] * data['is_religion_match']
72
+
73
+ exclude_cols = ['id', 'user_id', 'is_liked']
74
+ feature_cols = [col for col in data.columns if col not in exclude_cols]
75
+ print(f"Feature columns: {feature_cols}")
76
+
77
+ X = data[feature_cols].values
78
+ y = data['is_liked'].values
79
+
80
+ X_train, X_test, y_train, y_test = train_test_split(
81
+ X, y, test_size=test_size, random_state=random_state, stratify=y
82
+ )
83
+
84
+ scaler = StandardScaler()
85
+ X_train = scaler.fit_transform(X_train)
86
+ X_test = scaler.transform(X_test)
87
+
88
+ return X_train, X_test, y_train, y_test, scaler
89
+
90
+ def transform_new_data(data, scaler):
91
+ """
92
+ Transform new data for prediction using the fitted scaler
93
+ """
94
+ # Convert to numpy array if it's a DataFrame
95
+ if isinstance(data, pd.DataFrame):
96
+ data = data.values
97
+
98
+ # Apply the same scaling used during training
99
+ scaled_data = scaler.transform(data)
100
+
101
+ return scaled_data
dating_model/setup.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="dating_model",
5
+ version="0.1.0",
6
+ packages=find_packages(),
7
+ install_requires=[
8
+ "numpy>=1.26.4",
9
+ "pandas>=1.3.0",
10
+ "scikit-learn>=1.6.0",
11
+ "sqlalchemy>=1.4.0",
12
+ "joblib>=1.1.0",
13
+ ],
14
+ author="Jasif Shameem K",
15
+ author_email="jasifkolangath@gmail.com",
16
+ description="A package for dating app swipe prediction using logistic regression",
17
+ keywords="machine learning, dating app, prediction",
18
+ python_requires=">=3.7",
19
+ )
dating_scaler.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:747889fe7e37089373a71fa93742fe88b04019a351f0cbeaecc8894765c09fe2
3
+ size 815
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio>=5.20.1
2
+ joblib>=1.4.2
3
+ scikit-learn>=1.6.1
4
+ numpy>=1.26.4
utils.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from sklearn.preprocessing import StandardScaler
2
+
3
+
4
+ def preprocess_features(features):
5
+ scaler = StandardScaler()
6
+ scaled_features = scaler.transform(features)
7
+
8
+ return scaled_features