HardWorkingStation commited on
Commit
bbc09e3
·
1 Parent(s): 44e7893

Initial commit

Browse files
Files changed (3) hide show
  1. src/test.ipynb +210 -7
  2. src/tools.py +14 -6
  3. src/web_app.py +38 -26
src/test.ipynb CHANGED
@@ -49,7 +49,7 @@
49
  },
50
  {
51
  "cell_type": "code",
52
- "execution_count": 4,
53
  "outputs": [],
54
  "source": [
55
  "def get_data() -> tuple[Any, Any, Any]:\n",
@@ -75,7 +75,7 @@
75
  },
76
  {
77
  "cell_type": "code",
78
- "execution_count": 111,
79
  "outputs": [],
80
  "source": [
81
  "data, target, treatment = get_data()"
@@ -89,11 +89,11 @@
89
  },
90
  {
91
  "cell_type": "code",
92
- "execution_count": 112,
93
  "outputs": [],
94
  "source": [
95
  "X_train, X_val, y_train, y_val, trmnt_train, trmnt_val = train_test_split(\n",
96
- " data, target, treatment, test_size=0.3, random_state=42\n",
97
  ")\n",
98
  "\n",
99
  "models_results = {\n",
@@ -108,6 +108,52 @@
108
  }
109
  }
110
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  {
112
  "cell_type": "code",
113
  "execution_count": 113,
@@ -156,6 +202,71 @@
156
  }
157
  }
158
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  {
160
  "cell_type": "markdown",
161
  "source": [
@@ -170,12 +281,12 @@
170
  },
171
  {
172
  "cell_type": "code",
173
- "execution_count": 13,
174
  "outputs": [
175
  {
176
  "data": {
177
  "text/plain": "<Figure size 1440x504 with 3 Axes>",
178
- "image/png": "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JEmSJNVlw1YHMBrbbrttTp8+vdVhSFLbWbRo0R8zc3Kr42g12wlJGpjtRMV2QpIGNlQ70dGJpOnTp7Nw4cJWhyFJbSciftfqGNqB7YQkDcx2omI7IUkDG6qdcGibJEmSJEmS6mIiSZIkSZIkSXUxkSRJkiRJkqS6dPQcSZLGvyeffJJly5bx2GOPtTqUtjRp0iSmTp3KRhtt1OpQJKku3teby3ZCkuozUdunkbQTJpIktbVly5ax+eabM336dCKi1eG0lczkvvvuY9myZXR1dbU6HEmqi/f15rGdkKT6TcT2aaTthEPbJLW1xx57jG222WbC3MyHIyLYZpttJty3JpI6m/f15rGdkKT6TcT2aaTthIkkSW1vIt3Mh8v3RlIn8t7VPL7XklS/iXjPHMk1m0iSJEmSJElSXZwjSVJHmT9/bI83c+bQ2++77z723XdfAO6++2422GADJk+eDMCNN97IxhtvPOxzLliwgI033phXvepVw9pv+vTpLFy4kG233XbY55SkdtXb2zOmx+vqWv/xIoITTzyRz3/+8wCcfvrpPPLII/T0DL7vZZddxgtf+EJe8pKXDGvbSIz0eJttthmPPPLImMQgSRNdz4KesT3ejPUfb+nSpRx44IHccssta/fr6WGzzTbjwx/+8ID7nHfeeSxcuJAvf/nLnH322Tz72c/myCOP5Ne//jWHHXYYEcEll1zCDTfcwBFHHDEm12KPJEkawjbbbMPixYtZvHgxxx57LB/84AfXrG+88casXr162MdcsGABP//5zxsQrSSpHptssgmXXnopf/zjH+ve57LLLuO2224b9raRtBNDHU+SpMEce+yxHHnkkUDVlhx88MH84he/4K677uKb3/zmmJ3HRJIkDdNRRx3Fsccey1577cVHP/pRfvvb37L//vvz8pe/nNe85jX8+te/BmD+/Pnstdde7L777rzhDW/gnnvuYenSpZx99tmcccYZ7LbbbvzkJz9h5cqVvP3tb2ePPfZgjz324Gc/+xlQ9YZ605vexM4778zf/u3fkpmtvGxJGjc23HBD5syZwxlnnPGMbUuXLmWfffZhl112Yd999+X3v/89P//5z7niiiv4yEc+wm677cZvf/vbNfUH2jZjxgxOOOEEuru7OfPMM1m0aBGve93rePnLX85+++3HihUrAPja177GHnvswa677srb3/52Hn300QGPN1g709vbyytf+Ur+6q/+ilNOOaU5b54kqSVmzJjB8ccfz2677cZLX/pSbrzxxmfU6enp4fTTT+fKK6/ki1/8Il/96ld5/etfz8knn8xPfvITdttttwHbvuFyaJskjcCyZcv4+c9/zgYbbMC+++7L2WefzU477cQNN9zA3//933P11Vez9957c/311xMRfP3rX+dzn/scn//85zn22GPX6Z56xBFH8MEPfpC9996b3//+9+y3337cfvvt/NM//RN77703//iP/8j3vvc9zjnnnBZftSSNH8cddxy77LILH/3oR9cpf//738/s2bOZPXs25557Lh/4wAe47LLLeOtb38qBBx7IwQcfvE79V73qVQNue+KJJ1i4cCFPPvkkr3vd67j88suZPHkyF110EZ/4xCc499xzedvb3sZ73vMeAE455RTOOecc3v/+9z/jeIO1M8cffzzvfe97OfLII/nKV77S4HdMktRqjz76KIsXL+baa6/l3e9+9zpD4GodcMAB63zmWLBgAaeffjrf/e53xyQOE0mSNAKHHHIIG2ywAY888gg///nPOeSQQ9Zse/zxx4Eq2fSOd7yDFStW8MQTT9DV1TXgsX70ox+tM4ThoYce4pFHHuHaa6/l0ksvBeAtb3kLW221VQOvSJImluc+97kceeSRnHXWWWy66aZryq+77ro19953vetdz0g01esd73gHAHfccQe33HILb3zjGwF46qmnmDJlCgC33HILp5xyCg888ACPPPII++233zOOM1Q787Of/Yxvf/vba2I96aSTRhSrJKk9DPYEtb7yww8/HIDXvva1PPTQQzzwwAPNCm0dJpIkaQSe85znAPD000+z5ZZbsnjx4mfUef/738+JJ57IW9/6VhYsWDDoJK5PP/00119/PZMmTWpgxJKk/k444QRe9rKXcfTRR4/5sfvaicxk55135rrrrntGnaOOOorLLruMXXfdlfPOO48FCxY8o85Q7QxMzEdVS9J4tc0227Bq1ap1yu6///41X0j3v+e3qg1wjiRJGoXnPve5dHV18V//9V9A9YHhl7/8JQAPPvggO+ywAwDz5s1bs8/mm2/Oww8/vGb9TW96E1/60pfWrPd9WHjta1+7ZlK873//+89oVCRJo7P11ltz6KGHrjN0+FWvehUXXnghABdccAGvec1rgGfeu2sNte1F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\n"
179
  },
180
  "metadata": {
181
  "needs_background": "light"
@@ -184,7 +295,7 @@
184
  }
185
  ],
186
  "source": [
187
- "sm = SoloModel(CatBoostClassifier(iterations=1000, task_type=\"GPU\", random_state=42, silent=True))\n",
188
  "sm = sm.fit(X_train, y_train, trmnt_train, estimator_fit_params={'cat_features': ['history_segment', 'zip_code', 'channel']})\n",
189
  "\n",
190
  "uplift_sm = sm.predict(X_val)\n",
@@ -209,6 +320,98 @@
209
  }
210
  }
211
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  {
213
  "cell_type": "code",
214
  "execution_count": 14,
 
49
  },
50
  {
51
  "cell_type": "code",
52
+ "execution_count": 115,
53
  "outputs": [],
54
  "source": [
55
  "def get_data() -> tuple[Any, Any, Any]:\n",
 
75
  },
76
  {
77
  "cell_type": "code",
78
+ "execution_count": 116,
79
  "outputs": [],
80
  "source": [
81
  "data, target, treatment = get_data()"
 
89
  },
90
  {
91
  "cell_type": "code",
92
+ "execution_count": 117,
93
  "outputs": [],
94
  "source": [
95
  "X_train, X_val, y_train, y_val, trmnt_train, trmnt_val = train_test_split(\n",
96
+ " data, target, treatment, test_size=0.5, random_state=42\n",
97
  ")\n",
98
  "\n",
99
  "models_results = {\n",
 
108
  }
109
  }
110
  },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": 118,
114
+ "outputs": [
115
+ {
116
+ "data": {
117
+ "text/plain": "0 0.871545\n1 0.128455\nName: visit, dtype: float64"
118
+ },
119
+ "execution_count": 118,
120
+ "metadata": {},
121
+ "output_type": "execute_result"
122
+ }
123
+ ],
124
+ "source": [
125
+ "y_train.value_counts(normalize=True)"
126
+ ],
127
+ "metadata": {
128
+ "collapsed": false,
129
+ "pycharm": {
130
+ "name": "#%%\n"
131
+ }
132
+ }
133
+ },
134
+ {
135
+ "cell_type": "code",
136
+ "execution_count": 119,
137
+ "outputs": [
138
+ {
139
+ "data": {
140
+ "text/plain": "0 0.870802\n1 0.129198\nName: visit, dtype: float64"
141
+ },
142
+ "execution_count": 119,
143
+ "metadata": {},
144
+ "output_type": "execute_result"
145
+ }
146
+ ],
147
+ "source": [
148
+ "y_val.value_counts(normalize=True)"
149
+ ],
150
+ "metadata": {
151
+ "collapsed": false,
152
+ "pycharm": {
153
+ "name": "#%%\n"
154
+ }
155
+ }
156
+ },
157
  {
158
  "cell_type": "code",
159
  "execution_count": 113,
 
202
  }
203
  }
204
  },
205
+ {
206
+ "cell_type": "code",
207
+ "execution_count": 139,
208
+ "outputs": [],
209
+ "source": [
210
+ "t = pd.DataFrame(data = [1 for _ in X_train.index],\n",
211
+ " index=X_train.index\n",
212
+ ")\n",
213
+ "# t.loc[t.index] = 10"
214
+ ],
215
+ "metadata": {
216
+ "collapsed": false,
217
+ "pycharm": {
218
+ "name": "#%%\n"
219
+ }
220
+ }
221
+ },
222
+ {
223
+ "cell_type": "code",
224
+ "execution_count": 140,
225
+ "outputs": [
226
+ {
227
+ "data": {
228
+ "text/plain": " 0\n15194 1\n23642 1\n57737 1\n33880 1\n21211 1\n... ..\n9307 1\n16819 1\n57173 1\n1282 1\n23624 1\n\n[21346 rows x 1 columns]",
229
+ "text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>15194</th>\n <td>1</td>\n </tr>\n <tr>\n <th>23642</th>\n <td>1</td>\n </tr>\n <tr>\n <th>57737</th>\n <td>1</td>\n </tr>\n <tr>\n <th>33880</th>\n <td>1</td>\n </tr>\n <tr>\n <th>21211</th>\n <td>1</td>\n </tr>\n <tr>\n <th>...</th>\n <td>...</td>\n </tr>\n <tr>\n <th>9307</th>\n <td>1</td>\n </tr>\n <tr>\n <th>16819</th>\n <td>1</td>\n </tr>\n <tr>\n <th>57173</th>\n <td>1</td>\n </tr>\n <tr>\n <th>1282</th>\n <td>1</td>\n </tr>\n <tr>\n <th>23624</th>\n <td>1</td>\n </tr>\n </tbody>\n</table>\n<p>21346 rows × 1 columns</p>\n</div>"
230
+ },
231
+ "execution_count": 140,
232
+ "metadata": {},
233
+ "output_type": "execute_result"
234
+ }
235
+ ],
236
+ "source": [
237
+ "t"
238
+ ],
239
+ "metadata": {
240
+ "collapsed": false,
241
+ "pycharm": {
242
+ "name": "#%%\n"
243
+ }
244
+ }
245
+ },
246
+ {
247
+ "cell_type": "code",
248
+ "execution_count": 152,
249
+ "outputs": [
250
+ {
251
+ "data": {
252
+ "text/plain": "0.1987362209568153"
253
+ },
254
+ "execution_count": 152,
255
+ "metadata": {},
256
+ "output_type": "execute_result"
257
+ }
258
+ ],
259
+ "source": [
260
+ "import numpy as np\n",
261
+ "np.random.random()"
262
+ ],
263
+ "metadata": {
264
+ "collapsed": false,
265
+ "pycharm": {
266
+ "name": "#%%\n"
267
+ }
268
+ }
269
+ },
270
  {
271
  "cell_type": "markdown",
272
  "source": [
 
281
  },
282
  {
283
  "cell_type": "code",
284
+ "execution_count": 120,
285
  "outputs": [
286
  {
287
  "data": {
288
  "text/plain": "<Figure size 1440x504 with 3 Axes>",
289
+ "image/png": "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DbFHkiRJkiRJkhoyqd0BjMa2226bM2bMaHcYktRxbrjhhj9k5pR2x9FuthOSNDjbiYrthCQNbqh2YlwnkmbMmMHixYvbHYYkdZyIuKvdMXQC2wlJGpztRMV2QpIGN1Q74dA2SZIkSZIkNcREkiRJkiRJkhpiIkmSJEmSJEkNGddzJEma+J566imWLVvGE0880e5QOtImm2zCtGnT2HDDDdsdiiQ1xOt6a9lOSFJjurV9Gkk7YSJJUkdbtmwZm2++OTNmzCAi2h1OR8lMVq5cybJly+jp6Wl3OJLUEK/rrWM7IUmN68b2aaTthEPbJHW0J554gsmTJ3fNxXw4IoLJkyd33bcmksY3r+utYzshSY3rxvZppO2EiSRJHa+bLubD5XsjaTzy2tU6vteS1LhuvGaO5JxNJEmSJEmSJKkhzpEkaVxZuHBsjzd79tDbV65cyaxZswC499572WCDDZgyZQoA119/PRtttNGwX3PRokVstNFGvOxlLxvWfjNmzGDx4sVsu+22w35NSepUS5f2jenxenrWf7yI4IQTTuBzn/scAKeccgqPPfYYfX31973kkkt43vOex0477TSsbSMx0uNtttlmPPbYY2MSgyR1u75FfWN7vJnrP96dd97JQQcdxC233LJmv74+NttsMz74wQ8Ous8555zD4sWL+eIXv8iZZ57JM57xDI466ih+85vfcPjhhxMRXHTRRVx33XUceeSRY3Iu9kiSpCFMnjyZm266iZtuuonjjjuO97///avXN9poI1atWjXsYy5atIif/vSnTYhWktSIjTfemIsvvpg//OEPDe9zySWX8Otf/3rY20bSTgx1PEmS6jnuuOM46qijgKotOeSQQ/j5z3/O3Xffzde+9rUxex0TSZI0TEcffTTHHXcce+65Jx/+8Ie5/fbb2X///dljjz14xStewW9+8xsAFi5cyJ577sluu+3Ga17zGu677z7uvPNOzjzzTE499VR23XVXfvSjH7FixQre+MY38uIXv5gXv/jF/OQnPwGq3lD77rsvO++8M29729vIzHaetiRNGJMmTWLevHmceuqp62y788472WeffXjRi17ErFmz+N3vfsdPf/pTLrvsMj70oQ+x6667cvvtt6+uP9i2mTNn8r73vY/e3l5OO+00brjhBl71qlexxx57sN9++3HPPfcA8OUvf5kXv/jF7LLLLrzxjW/k8ccfH/R49dqZpUuX8tKXvpS//du/5ROf+ERr3jxJUlvMnDmT9773vey666688IUv5Prrr1+nTl9fH6eccgqXX345n//85znjjDN49atfzYknnsiPfvQjdt1110HbvuFyaJskjcCyZcv46U9/ygYbbMCsWbM488wz2XHHHbnuuut45zvfyVVXXcXee+/NtddeS0Twla98hc9+9rN87nOf47jjjlure+qRRx7J+9//fvbee29+97vfsd9++3Hrrbfyj//4j+y99978wz/8A9/5znc466yz2nzWkjRxHH/88bzoRS/iwx/+8Frl7373u5k7dy5z587l7LPP5j3veQ+XXHIJBx98MAcddBCHHHLIWvVf9rKXDbrtySefZPHixTz11FO86lWv4tJLL2XKlClccMEFfPzjH+fss8/mDW94A29/+9sB+MQnPsFZZ53Fu9/97nWOV6+dee9738s73vEOjjrqKL70pS81+R2TJLXb448/zk033cTVV1/NW9/61rWGwNU68MAD1/rMsWjRIk455RS+/e1vj0kcJpIkaQQOPfRQNthgAx577DF++tOfcuihh67e9qc//Qmokk1vetObuOeee3jyySfp6ekZ9Fg/+MEP1hrC8Mgjj/DYY49x9dVXc/HFFwPwute9jq233rqJZyRJ3WWLLbbgqKOO4vTTT+fpT3/66vJrrrlm9bX3LW95yzqJpka96U1vAuC3v/0tt9xyC6997WsB+POf/8zUqVMBuOWWW/jEJz7BQw89xGOPPcZ+++23znGGamd+8pOf8M1vfnN1rB/5yEdGFKskqTPUu4Naf/kRRxwBwCtf+UoeeeQRHnrooVaFthYTSZI0AptuuikAf/nLX9hqq6246aab1qnz7ne/mxNOOIGDDz6YRYsW1Z3E9S9/+QvXXnstm2yySRMjliQN9L73vY/dd9+dY445ZsyP3d9OZCY777wz11xzzTp1jj76aC655BJ22WUXzjnnHBYtWrROnaHaGejOW1VL0kQ1efJkHnzwwbXKHnjggdVfSA+85rerDXCOJEkahS222IKenh6+8Y1vANUHhl/84hcAPPzww2y//fYALFiwYPU+m2++OY8++ujq9X333ZcvfOELq9f7Pyy88pWvXD0p3ne/+911GhVJ0uhss802HHbYYWsNHX7Zy17G+eefD8B5553HK17xCmDd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\n"
290
  },
291
  "metadata": {
292
  "needs_background": "light"
 
295
  }
296
  ],
297
  "source": [
298
+ "sm = SoloModel(CatBoostClassifier(iterations=100, task_type=\"GPU\", random_state=42, silent=True))\n",
299
  "sm = sm.fit(X_train, y_train, trmnt_train, estimator_fit_params={'cat_features': ['history_segment', 'zip_code', 'channel']})\n",
300
  "\n",
301
  "uplift_sm = sm.predict(X_val)\n",
 
320
  }
321
  }
322
  },
323
+ {
324
+ "cell_type": "code",
325
+ "execution_count": 154,
326
+ "outputs": [
327
+ {
328
+ "data": {
329
+ "text/plain": "7730 0\n17594 0\n14481 0\n20003 0\n19981 0\n ..\n20159 0\n54905 0\n22035 0\n32253 1\n18362 0\nName: visit, Length: 21347, dtype: int64"
330
+ },
331
+ "execution_count": 154,
332
+ "metadata": {},
333
+ "output_type": "execute_result"
334
+ }
335
+ ],
336
+ "source": [
337
+ "y_val"
338
+ ],
339
+ "metadata": {
340
+ "collapsed": false,
341
+ "pycharm": {
342
+ "name": "#%%\n"
343
+ }
344
+ }
345
+ },
346
+ {
347
+ "cell_type": "code",
348
+ "execution_count": 155,
349
+ "outputs": [
350
+ {
351
+ "data": {
352
+ "text/plain": "7730 0\n17594 1\n14481 1\n20003 1\n19981 0\n ..\n20159 1\n54905 0\n22035 0\n32253 1\n18362 0\nName: segment, Length: 21347, dtype: int64"
353
+ },
354
+ "execution_count": 155,
355
+ "metadata": {},
356
+ "output_type": "execute_result"
357
+ }
358
+ ],
359
+ "source": [
360
+ "trmnt_val"
361
+ ],
362
+ "metadata": {
363
+ "collapsed": false,
364
+ "pycharm": {
365
+ "name": "#%%\n"
366
+ }
367
+ }
368
+ },
369
+ {
370
+ "cell_type": "code",
371
+ "execution_count": 153,
372
+ "outputs": [
373
+ {
374
+ "data": {
375
+ "text/plain": "0.07205126328781693"
376
+ },
377
+ "execution_count": 153,
378
+ "metadata": {},
379
+ "output_type": "execute_result"
380
+ }
381
+ ],
382
+ "source": [
383
+ "sm_score"
384
+ ],
385
+ "metadata": {
386
+ "collapsed": false,
387
+ "pycharm": {
388
+ "name": "#%%\n"
389
+ }
390
+ }
391
+ },
392
+ {
393
+ "cell_type": "code",
394
+ "execution_count": 121,
395
+ "outputs": [
396
+ {
397
+ "data": {
398
+ "text/plain": "array([ 0.03210443, 0.02052168, -0.00873204, ..., 0.04017716,\n 0.03415103, 0.04917549])"
399
+ },
400
+ "execution_count": 121,
401
+ "metadata": {},
402
+ "output_type": "execute_result"
403
+ }
404
+ ],
405
+ "source": [
406
+ "uplift_sm"
407
+ ],
408
+ "metadata": {
409
+ "collapsed": false,
410
+ "pycharm": {
411
+ "name": "#%%\n"
412
+ }
413
+ }
414
+ },
415
  {
416
  "cell_type": "code",
417
  "execution_count": 14,
src/tools.py CHANGED
@@ -4,7 +4,8 @@ import pandas as pd
4
  import numpy as np
5
  from sklearn.model_selection import train_test_split
6
  from sklift.datasets import fetch_hillstrom
7
- from sklift.metrics import uplift_at_k
 
8
  from catboost import CatBoostClassifier
9
  import sklearn
10
  import streamlit as st
@@ -12,6 +13,10 @@ import plotly.express as px
12
  import plotly.graph_objects as go
13
 
14
 
 
 
 
 
15
  @st.experimental_memo
16
  def get_data() -> tuple[Any, Any, Any]:
17
  # получаем датасет
@@ -38,7 +43,7 @@ def data_split(data: pd.DataFrame, treatment: pd.DataFrame, target: pd.DataFrame
38
  treatment,
39
  target,
40
  stratify=stratify_cols,
41
- test_size=0.3,
42
  random_state=42
43
  )
44
  return X_train, X_val, trmnt_train, trmnt_val, y_train, y_val
@@ -131,10 +136,13 @@ def filter_data(data: pd.DataFrame, filters: dict) -> pd.DataFrame or None:
131
  return data
132
 
133
 
134
- def send_promo_and_get_res(data_train: pd.DataFrame, treatment: pd.DataFrame, target: pd.DataFrame):
135
- indexes = data.index
136
- target = target.loc[indexes]
137
- treatment = treatment.loc[indexes]
 
 
 
138
 
139
 
140
  def get_newbie_plot(data):
 
4
  import numpy as np
5
  from sklearn.model_selection import train_test_split
6
  from sklift.datasets import fetch_hillstrom
7
+ from sklift.metrics import uplift_at_k, uplift_by_percentile, weighted_average_uplift
8
+ from sklift.viz import plot_uplift_by_percentile
9
  from catboost import CatBoostClassifier
10
  import sklearn
11
  import streamlit as st
 
13
  import plotly.graph_objects as go
14
 
15
 
16
+ def test():
17
+ return 'Test'
18
+
19
+
20
  @st.experimental_memo
21
  def get_data() -> tuple[Any, Any, Any]:
22
  # получаем датасет
 
43
  treatment,
44
  target,
45
  stratify=stratify_cols,
46
+ test_size=0.5,
47
  random_state=42
48
  )
49
  return X_train, X_val, trmnt_train, trmnt_val, y_train, y_val
 
136
  return data
137
 
138
 
139
+ def uplift_by_percentile():
140
+ pass
141
+
142
+
143
+ def get_weighted_average_uplift(target_test: pd.DataFrame, uplift, treatment_test: pd.DataFrame):
144
+ res = weighted_average_uplift(target_test, uplift, treatment_test)
145
+ return res
146
 
147
 
148
  def get_newbie_plot(data):
src/web_app.py CHANGED
@@ -4,10 +4,13 @@ import streamlit as st
4
 
5
  import tools
6
 
7
-
8
  dataset, target, treatment = tools.get_data()
9
 
10
- data_train, data_val, treatment_train, treatment_val, target_train, target_val = tools.data_split(dataset, treatment, target)
 
 
 
 
11
 
12
  st.title('Uplift lab')
13
 
@@ -32,11 +35,11 @@ st.markdown(
32
  """
33
  )
34
  refresh = st.button('Обновить выборку')
35
- title_subsample = data_train.sample(7)
36
  if refresh:
37
- title_subsample = data_train.sample(7)
38
  st.dataframe(title_subsample, width=700)
39
- st.write(f"Всего записей: {data_train.shape[0]}")
40
 
41
  st.write('Описание данных')
42
  st.markdown(
@@ -60,34 +63,34 @@ st.write("Для того, чтобы лучше понять на какую а
60
 
61
  with st.expander('Развернуть блок анализа данных'):
62
 
63
- st.plotly_chart(tools.get_newbie_plot(data_train), use_container_width=True)
64
  st.write(f'В данных примерно одинаковое количество новых и "старых клиентов". '
65
- f'Отношение новых клиентов к старым: {(data_train["newbie"] == 1).sum() / (data_train["newbie"] == 0).sum():.2f}')
66
 
67
- st.plotly_chart(tools.get_zipcode_plot(data_train), use_container_width=True)
68
- tmp_res = data_train.zip_code.value_counts(normalize=True) * 100
69
  st.write(f'Большинство клиентов из пригорода: {tmp_res["Surburban"]:.2f}%, из города: {tmp_res["Urban"]:.2f}% и из села: {tmp_res["Rural"]:.2f}%')
70
 
71
- tmp_res = data_train.channel.value_counts(normalize=True) * 100
72
- st.plotly_chart(tools.get_channel_plot(data_train), use_container_width=True)
73
  st.write(f'В прошлом году почти одинаковое количество клиентов покупало товары через телефон и сайт, {tmp_res["Phone"]:.2f}% и {tmp_res["Web"]:.2f}% соответственно,'
74
  f' а {tmp_res["Multichannel"]:.2f}% клиентов покупали товары воспользовавшись двумя платформами.')
75
 
76
- tmp_res = data_train.history_segment.value_counts(normalize=True) * 100
77
- st.plotly_chart(tools.get_history_segment_plot(data_train), use_container_width=True)
78
  st.write(f'Как мы видим, большинство пользователей относится к сегменту \$0-\$100 ({tmp_res[0]:.2f}%), второй и '
79
  f'третий по количеству пользователей сегменты \$100-\$200 ({tmp_res[1]:.2f}%) и \$200-\$350 ({tmp_res[2]:.2f}%).')
80
  st.write(f'К сегментам \$350-\$500 и \$500-\$750 относится {tmp_res[3]:.2f}% и {tmp_res[4]:.2f}% пользователей соответственно.')
81
  st.write(f'Меньше всего пользователей в сегментах \$750-\$1.000 ({tmp_res[-2]:.2f}%) и \$1.000+ ({tmp_res[-1]:.2f}%).')
82
 
83
- tmp_res = list(data_train.recency.value_counts(normalize=True) * 100)
84
- st.plotly_chart(tools.get_recency_plot(data_train), use_container_width=True)
85
  st.write(f'Большинство клиентов являются активными клиентами платформы, и совершали покупки в течение месяца ({tmp_res[0]:.2f}%)')
86
  st.write('Также заметно, что 9 и 10 месяцев назад, много клиентов совершали покупки. Это может свидетельствовать о проведении'
87
  'рекламной кампании в это время или чего-то еще.')
88
  st.write('Также интересно понаблюдать за долями новых клиентов в данном распределении.')
89
 
90
- st.plotly_chart(tools.get_history_plot(data_train), use_container_width=True)
91
  st.markdown('_График интерактивный. Двойной клик вернет в начальное состояние._')
92
  st.write('Абсолютное большинство клиентов тратят \$25-\$35 на покупки, но есть и малая доля тех, кто тратит более \$3.000')
93
  st.write('Интересный факт: все покупки более \$500 совершают только новые клиенты')
@@ -140,7 +143,7 @@ rural = st.checkbox('Rural', value=True)
140
  if rural:
141
  filters['zip_code']['rural'] = True
142
 
143
- recency = st.slider(label='Месяцев с момента покупки', min_value=int(data_train.recency.min()), max_value=int(data_train.recency.max()), value=(int(data_train.recency.min()), int(data_train.recency.max())))
144
  filters['recency'] = recency
145
 
146
  disabled = False
@@ -151,22 +154,31 @@ elif not surburban and not urban and not rural:
151
  st.error('Необходимо выбрать хотя бы один почтовый индекс')
152
  disabled = True
153
 
154
- filter_data = st.button(label='Отфильтровать', disabled=disabled)
155
 
156
- if filter_data:
157
- filtered_dataset = tools.filter_data(data_train, filters)
158
- if filtered_dataset is None:
159
- st.error('Нет подходящих под выбранный фильтр клиентов. Попробуйте изменить фильтр.')
 
 
 
 
 
 
160
  sample_size = 7 if filtered_dataset.shape[0] >= 7 else filtered_dataset.shape[0]
161
  example = filtered_dataset.sample(sample_size)
162
  st.write('Пример пользователей, которым будет отправлена реклама')
163
  st.dataframe(example)
164
  st.info(f'Количество клиентов, которым реклама будет отправлена: _**{filtered_dataset.shape[0]}**_ ({filtered_dataset.shape[0] / data_train.shape[0] * 100 :.2f}% от всех клиентов)')
165
- else:
166
- # нельзя отправить рекламу, до фильтрации
167
- disabled = True
168
 
169
  send_promo = st.button('Отправить рекламу и посмотреть результат', disabled=disabled)
170
  if send_promo:
171
- pass
 
 
 
 
 
 
172
 
 
4
 
5
  import tools
6
 
 
7
  dataset, target, treatment = tools.get_data()
8
 
9
+ data_train, data_test, treatment_train, treatment_test, target_train, target_test = tools.data_split(dataset, treatment, target)
10
+
11
+ if 'filter_data' not in st.session_state.keys():
12
+ st.session_state.filter_data = True
13
+
14
 
15
  st.title('Uplift lab')
16
 
 
35
  """
36
  )
37
  refresh = st.button('Обновить выборку')
38
+ title_subsample = data_test.sample(7)
39
  if refresh:
40
+ title_subsample = data_test.sample(7)
41
  st.dataframe(title_subsample, width=700)
42
+ st.write(f"Всего записей: {data_test.shape[0]}")
43
 
44
  st.write('Описание данных')
45
  st.markdown(
 
63
 
64
  with st.expander('Развернуть блок анализа данных'):
65
 
66
+ st.plotly_chart(tools.get_newbie_plot(data_test), use_container_width=True)
67
  st.write(f'В данных примерно одинаковое количество новых и "старых клиентов". '
68
+ f'Отношение новых клиентов к старым: {(data_test["newbie"] == 1).sum() / (data_test["newbie"] == 0).sum():.2f}')
69
 
70
+ st.plotly_chart(tools.get_zipcode_plot(data_test), use_container_width=True)
71
+ tmp_res = data_test.zip_code.value_counts(normalize=True) * 100
72
  st.write(f'Большинство клиентов из пригорода: {tmp_res["Surburban"]:.2f}%, из города: {tmp_res["Urban"]:.2f}% и из села: {tmp_res["Rural"]:.2f}%')
73
 
74
+ tmp_res = data_test.channel.value_counts(normalize=True) * 100
75
+ st.plotly_chart(tools.get_channel_plot(data_test), use_container_width=True)
76
  st.write(f'В прошлом году почти одинаковое количество клиентов покупало товары через телефон и сайт, {tmp_res["Phone"]:.2f}% и {tmp_res["Web"]:.2f}% соответственно,'
77
  f' а {tmp_res["Multichannel"]:.2f}% клиентов покупали товары воспользовавшись двумя платформами.')
78
 
79
+ tmp_res = data_test.history_segment.value_counts(normalize=True) * 100
80
+ st.plotly_chart(tools.get_history_segment_plot(data_test), use_container_width=True)
81
  st.write(f'Как мы видим, большинство пользователей относится к сегменту \$0-\$100 ({tmp_res[0]:.2f}%), второй и '
82
  f'третий по количеству пользователей сегменты \$100-\$200 ({tmp_res[1]:.2f}%) и \$200-\$350 ({tmp_res[2]:.2f}%).')
83
  st.write(f'К сегментам \$350-\$500 и \$500-\$750 относится {tmp_res[3]:.2f}% и {tmp_res[4]:.2f}% пользователей соответственно.')
84
  st.write(f'Меньше всего пользователей в сегментах \$750-\$1.000 ({tmp_res[-2]:.2f}%) и \$1.000+ ({tmp_res[-1]:.2f}%).')
85
 
86
+ tmp_res = list(data_test.recency.value_counts(normalize=True) * 100)
87
+ st.plotly_chart(tools.get_recency_plot(data_test), use_container_width=True)
88
  st.write(f'Большинство клиентов являются активными клиентами платформы, и совершали покупки в течение месяца ({tmp_res[0]:.2f}%)')
89
  st.write('Также заметно, что 9 и 10 месяцев назад, много клиентов совершали покупки. Это может свидетельствовать о проведении'
90
  'рекламной кампании в это время или чего-то еще.')
91
  st.write('Также интересно понаблюдать за долями новых клиентов в данном распределении.')
92
 
93
+ st.plotly_chart(tools.get_history_plot(data_test), use_container_width=True)
94
  st.markdown('_График интерактивный. Двойной клик вернет в начальное состояние._')
95
  st.write('Абсолютное большинство клиентов тратят \$25-\$35 на покупки, но есть и малая доля тех, кто тратит более \$3.000')
96
  st.write('Интересный факт: все покупки более \$500 совершают только новые клиенты')
 
143
  if rural:
144
  filters['zip_code']['rural'] = True
145
 
146
+ recency = st.slider(label='Месяцев с момента покупки', min_value=int(data_test.recency.min()), max_value=int(data_test.recency.max()), value=(int(data_test.recency.min()), int(data_test.recency.max())))
147
  filters['recency'] = recency
148
 
149
  disabled = False
 
154
  st.error('Необходимо выбрать хотя бы один почтовый индекс')
155
  disabled = True
156
 
 
157
 
158
+ if not disabled:
159
+ filtered_dataset = tools.filter_data(data_test, filters)
160
+ # значение uplift для записей тех клиентов, который выбрал пользователь равен 1
161
+ import numpy as np
162
+ uplift = pd.DataFrame(
163
+ data=[np.random.random() for _ in filtered_dataset.index],
164
+ index=filtered_dataset.index
165
+ )
166
+ target_filtered =target_test.loc[filtered_dataset.index]
167
+ treatment_filtered = treatment_test.loc[filtered_dataset.index]
168
  sample_size = 7 if filtered_dataset.shape[0] >= 7 else filtered_dataset.shape[0]
169
  example = filtered_dataset.sample(sample_size)
170
  st.write('Пример пользователей, которым будет отправлена реклама')
171
  st.dataframe(example)
172
  st.info(f'Количество клиентов, которым реклама будет отправлена: _**{filtered_dataset.shape[0]}**_ ({filtered_dataset.shape[0] / data_train.shape[0] * 100 :.2f}% от всех клиентов)')
173
+
 
 
174
 
175
  send_promo = st.button('Отправить рекламу и посмотреть результат', disabled=disabled)
176
  if send_promo:
177
+ from sklift.metrics import uplift_by_percentile, uplift_at_k
178
+ st.write(uplift_by_percentile(y_true=target_filtered, uplift=uplift, treatment=treatment_filtered))
179
+ st.write(uplift_at_k(y_true=target_filtered, uplift=uplift, treatment=treatment_filtered, strategy='by_group', k=0.3))
180
+ # st.write(tools.get_weighted_average_uplift(target_filtered, uplift, treatment_filtered))
181
+
182
+ # st.write('Если известно, на какой процент пользователей необходимо воздействовать, укажите это ниже')
183
+ # st.slider(label='Процент пользователей', min_value=0, max_value=100, value=100)
184