File size: 30,235 Bytes
cda78c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "import json\n",
    "import pandas as pd\n",
    "from numpy import mean, percentile, array\n",
    "from numpy.random import permutation as perm\n",
    "from pathlib import Path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "base_dir = Path()\n",
    "data_dir = base_dir / \"data\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_jsonl(file_path):\n",
    "    data = []\n",
    "    with open(file_path, \"r\") as file:\n",
    "        for i,line in enumerate(file):\n",
    "            data.append(json.loads(line))\n",
    "    return data\n",
    "\n",
    "reviews = read_jsonl(data_dir / \"cmu\" / \"raw\" / \"review.txt\")\n",
    "offering = read_jsonl(data_dir / \"cmu\" / \"raw\" / \"offering.txt\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(data_dir / \"cmu\" / \"processed\" / \"cities.json\", \"w\") as f:\n",
    "    json.dump(list(cities), f)\n",
    "    \n",
    "with open(data_dir / \"cmu\" / \"processed\" / \"score_threshold_per_city.json\", \"w\") as f:\n",
    "    json.dump(score_threshold_per_city, f)\n",
    "\n",
    "with open(data_dir / \"cmu\" / \"processed\" / \"city_to_hotel_id_map.json\", \"w\") as f:\n",
    "    json.dump(city_to_hotel_id_map, f)\n",
    "\n",
    "with open(data_dir / \"cmu\" / \"processed\" / \"hotel_id_to_name_map.json\", \"w\") as f:\n",
    "    json.dump(hotel_id_to_name_map, f)\n",
    "\n",
    "with open(data_dir / \"cmu\" / \"processed\" / \"hotel_id_to_review_map.json\", \"w\") as f:\n",
    "    json.dump(hotel_id_to_review_map, f)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "cities = set([hotel['address']['locality'] for hotel in offering])\n",
    "city_to_hotel_id_map = {city: [hotel['id'] for hotel in offering \n",
    "                               if hotel['address']['locality'] == city] for city in cities}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "hotel_id_to_review_map = {}\n",
    "for review in reviews:\n",
    "    review_info = {'text': review['text'], 'score': review['ratings']['overall'], 'num_helpful': review['num_helpful_votes']}\n",
    "    hotel_id_to_review_map.setdefault(review['offering_id'], []).append(review_info)\n",
    "\n",
    "for hotel_id, review_info in hotel_id_to_review_map.items():\n",
    "    average_score = mean([rev['score'] for rev in review_info])\n",
    "    hotel_id_to_review_map[hotel_id] = {'average_score': average_score, 'reviews': review_info}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "hotel_id_to_name_map = {hotel[\"id\"]: hotel[\"name\"] for hotel in offering}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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tlb//d//ralTp2rjxo3B7labU1FRofvvv18FBQWKiYkJdnfatHHjxjn/Hjx4sFJTU9WrVy/97ne/U2xsbBB71rYxQxQE3bp1U7t27c5Y9V9ZWamEhIQg9Sr0NY3N941bQkKCqqqqAtpPnjyp6urqgJqzfcapx7hUZGdna926dXrvvffUs2dPZ39CQoLq6+tVU1MTUH/6WP6tcfqumri4uEvmP+aoqChdccUVGj58uHJzczVkyBA999xzjOF5KikpUVVVlYYNG6aIiAhFRERo48aNWrx4sSIiIuTxeBjPZnK73fr7v/97ffbZZ/xdXgACURBERUVp+PDhKiwsdPb5/X4VFhYqLS0tiD0Lbb1791ZCQkLAuPl8PhUXFzvjlpaWppqaGpWUlDg1GzZskN/vV2pqqlOzadMmNTQ0ODUFBQXq06ePOnfu3Epnc3EZY5Sdna0333xTGzZsUO/evQPahw8frsjIyICxLCsrU3l5ecBY7tq1KyBgFhQUKC4uTv3793dqTv2MpppL+e/Y7/errq6OMTxPo0eP1q5du1RaWupsI0aMUGZmpvNvxrN5jh49qv/93/9Vjx49+Lu8EMFe1W2r1atXm+joaLNixQqzd+9eM2PGDON2uwNW/dvoyJEj5uOPPzYff/yxkWQWLlxoPv74Y/P5558bY7697d7tdps//OEPZufOnWbixIlnve3+qquuMsXFxebDDz80V155ZcBt9zU1Ncbj8Zi77rrL7N6926xevdq0b9/+krrt/t577zUul8u8//77AbfmfvPNN07NPffcY5KTk82GDRvM9u3bTVpamklLS3Pam27NHTNmjCktLTX5+fmme/fuZ701d86cOWbfvn0mLy/vkro19+GHHzYbN240Bw4cMDt37jQPP/ywCQsLM++8844xhjG8UKfeZWYM43mufvazn5n333/fHDhwwHz00UcmPT3ddOvWzVRVVRljGMfmIhAF0ZIlS0xycrKJiooyo0aNMlu2bAl2l4LuvffeM5LO2KZOnWqM+fbW+7lz5xqPx2Oio6PN6NGjTVlZWcBn/PWvfzV33HGH6dixo4mLizM/+tGPzJEjRwJqPvnkE3PdddeZ6Ohoc9lll5knn3yytU6xVZxtDCWZ5cuXOzXHjx839913n+ncubNp3769+ad/+ifz1VdfBXzOwYMHzbhx40xsbKzp1q2b+dnPfmYaGhoCat577z0zdOhQExUVZS6//PKAY7R1P/7xj02vXr1MVFSU6d69uxk9erQThoxhDC/U6YGI8Tw3t99+u+nRo4eJiooyl112mbn99tvNZ5995rQzjs0TZowxwZmbAgAACA2sIQIAANYjEAEAAOsRiAAAgPUIRAAAwHoEIgAAYD0CEQAAsB6BCAAAWI9ABAAArEcgAgAA1iMQAQAA6xGIAACA9QhEAADAev8HxkUzO8HI8v4AAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.histplot([len(hotel['reviews']) for hotel in hotel_id_to_review_map.values()]);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calc_score_threshold_per_city(p):\n",
    "    res = {}\n",
    "    for city, idxs in city_to_hotel_id_map.items():\n",
    "        res[city] = percentile([hotel_id_to_review_map.get(idx, {'average_score': 0})['average_score'] for idx in idxs], p)  \n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "score_threshold_per_city=calc_score_threshold_per_city(80)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "reviews_per_hotel_per_city = {}\n",
    "for city in city_to_hotel_id_map:\n",
    "    for hotel_id in city_to_hotel_id_map[city]:\n",
    "        n_reviews = len(hotel_id_to_review_map.get(hotel_id, {'reviews': []})['reviews'])\n",
    "        reviews_per_hotel_per_city.setdefault(city, []).append(n_reviews)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Boston: 73 hotels with more than 100 reviews\n",
      "Seattle: 86 hotels with more than 100 reviews\n",
      "San Jose: 24 hotels with more than 100 reviews\n",
      "Charlotte: 49 hotels with more than 100 reviews\n",
      "Chicago: 106 hotels with more than 100 reviews\n",
      "Washington DC: 106 hotels with more than 100 reviews\n",
      "Fort Worth: 15 hotels with more than 100 reviews\n",
      "Jacksonville: 39 hotels with more than 100 reviews\n",
      "Denver: 70 hotels with more than 100 reviews\n",
      "Los Angeles: 142 hotels with more than 100 reviews\n",
      "New York City: 327 hotels with more than 100 reviews\n",
      "Dallas: 61 hotels with more than 100 reviews\n",
      "Memphis: 42 hotels with more than 100 reviews\n",
      "Phoenix: 62 hotels with more than 100 reviews\n",
      "San Diego: 148 hotels with more than 100 reviews\n",
      "Austin: 63 hotels with more than 100 reviews\n",
      "Baltimore: 41 hotels with more than 100 reviews\n",
      "San Antonio: 89 hotels with more than 100 reviews\n",
      "Detroit: 17 hotels with more than 100 reviews\n",
      "Indianapolis: 44 hotels with more than 100 reviews\n",
      "San Francisco: 177 hotels with more than 100 reviews\n",
      "Houston: 70 hotels with more than 100 reviews\n",
      "Columbus: 38 hotels with more than 100 reviews\n",
      "Philadelphia: 61 hotels with more than 100 reviews\n",
      "El Paso: 11 hotels with more than 100 reviews\n"
     ]
    }
   ],
   "source": [
    "for city, num_reviews in reviews_per_hotel_per_city.items():\n",
    "    score_threshold = score_threshold_per_city[city]\n",
    "    for idx in city_to_hotel_id_map[city]:\n",
    "        hotel_id_to_review_map.get(idx, {'average_score': 0})['average_score']\n",
    "    print(f\"{city}: {(array(num_reviews) > 70).sum()} hotels with more than 100 reviews\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "offering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "memory in gradio space\n",
    "\n",
    "Steps:\n",
    "* Embed space in site\n",
    "* Save preprocessed files\n",
    "* Load from interface\n",
    "* Return recommendation for boston irrespective of text input\n",
    "    * Return context for llm as output\n",
    "    * Set up open ai, return raw output with basic prompt\n",
    "* Scroll menu for city\n",
    "* Check box for kid friendly\n",
    "* At the end - understand free text input\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "hotel_id_to_review_map = {\n",
    "    hotel_id: {\n",
    "        \"reviews\": [\n",
    "            review for review in hotel_data[\"reviews\"] if review[\"num_helpful\"] > 10\n",
    "        ]\n",
    "    }\n",
    "    for hotel_id, hotel_data in hotel_id_to_review_map.items()\n",
    "    if len(hotel_id_to_review_map[hotel_id]['reviews']) > 100\n",
    "    and hotel_id_to_review_map[hotel_id]['average_score'] >= score_threshold_per_city[hotel_id_to_city_map[hotel_id]]\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "hotel_id_to_city_map = {vi:k for k,v in city_to_hotel_id_map.items() for vi in v}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'hotel_name': 'Four Seasons Hotel Boston', 'positive': [{'text': \"FSHB is one of the best hotels in the country. Its employees are pleasant, professional, and well trained. They always have the guests' best interests in mind. The hotel is beautiful, the rooms spacious, clean, andextremely comfortable. The restaurant, Aujourd'hui, is among the best in the city. The food is exquisite. Room service and brunch are also wonderful. This is the best Boston has to offer!\", 'score': 5.0, 'num_helpful': 11}, {'text': 'I had the opportunity to stay at the 4 seasons for the Boston Marathon. It was my first time to Boston (where I had wanted to go since my early twenties, (48 now)!. I have to say the 4 seasons made this the best experience of my life. From the pickup at the airport to the drop off I was simply amazed! Everyone was so nice, Daniel the concierge helped me get a tour of the city prior to other relatives arriving and referred me to 5th Avenue Limo Service. Use them please, they are great! The driver was so knowledgeable and darn I cant remember his name! The service, the room, the ammenities were all above par. I have to admit the only thing i did not like was the darn curtain in the shower. seriously, all hotels that r 4 or 5 star even 3, need to have shower enclosures! the bedding was excellent, the executive suite overlooking boston gardens and boston common - oh my - the view and listening to the people out on the street was great. you can open a window from these rooms and feel the ambiance of the city. I will stay at the 4 seasons probably every time i return to boston!!! kudos to the hotel management!', 'score': 5.0, 'num_helpful': 11}, {'text': 'Just returned from a visit to Four Seasons Boston and the service was excellent. We arrived early in the AM from a red-eye flight and the terrific woman at the front desk (Eliva?)not only let us check in early but upgraded us to a newly renovated room. The doormen,bellman,concierge and staff at the health club all were first rate. Health club facilities were great, enjoyed the newly renovated steam room and sauna. Of course, as is typical of the Four Seasons the bed was sublime. We have stayed at this property in the past and never been disappointed. Last year due to some of the negative reviews about Four Seasons Boston we stayed at Beacon XV- what a mistake! The service at Beacon XV is truly awful, does not even compare.', 'score': 5.0, 'num_helpful': 11}], 'negative': [{'text': \"After staying at the hotel for a wedding, my room was broken into and a significant amount of Jewelry stolen. The Boston Police Department has since found the thief and has a video of the gentlemen leaving my hotel room. Through this terrible ordeal the 4 Seasons has been unbelievable. They have claimed that it is not their responsibility and refuse to insure my belongings. On top of everything, I was shocked when they didn't even bother to comp my room after I had to deal with a police report all day. Do not stay here unless you want to deal with a rude and terrible staff at a 2-3 star hotel. Try the Taj\", 'score': 1.0, 'num_helpful': 14}]}\n"
     ]
    }
   ],
   "source": [
    "city = \"Boston\"\n",
    "score_threshold = score_threshold_per_city[city]\n",
    "for hotel_id in perm(city_to_hotel_id_map[city]):\n",
    "    try:\n",
    "        hotel_reviews = hotel_id_to_review_map[hotel_id]['reviews']\n",
    "    except KeyError:\n",
    "        continue\n",
    "    res = {\"hotel_name\": hotel_id_to_name_map[hotel_id], 'positive': [], 'negative': []}    \n",
    "    hotel_reviews = hotel_id_to_review_map[hotel_id]['reviews']\n",
    "    for review in perm(hotel_reviews):\n",
    "        if review['num_helpful'] > 10:\n",
    "            if (review['score'] == 5) & (len(res['positive']) < 3):\n",
    "                res['positive'].append(review)\n",
    "            if (review['score'] <= 2) & (len(res['negative']) < 1):\n",
    "                res['negative'].append(review)\n",
    "    if (len(res['positive']) >= 3) & (len(res['negative']) >= 1):\n",
    "        break\n",
    "\n",
    "print(res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "adults",
   "language": "python",
   "name": "adults"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}