Ilia Azizi commited on
Commit
2b90e9b
1 Parent(s): 2e11edb

Update app styling

Browse files
Files changed (2) hide show
  1. app.py +120 -47
  2. requirements.txt +7 -5
app.py CHANGED
@@ -1,92 +1,165 @@
1
- # all the imports
2
  from transformers import pipeline
3
  import gradio as gr
4
  import torch
5
  import re
6
 
7
- #---------------------------------------------------------------------------------
8
- # function modified for the demo
9
- def get_native_feature_demo(language, input_description, target_feature, question, return_numbers = True):
10
  task = 'question-answering'
11
  french_model = 'AgentPublic/camembert-base-squadFR-fquad-piaf'
12
  english_model = 'deepset/roberta-base-squad2'
 
13
  if language == "French":
14
  model = pipeline(task, model=french_model, tokenizer=french_model)
15
  else:
16
  model = pipeline(task, model=english_model, tokenizer=english_model)
 
17
  answer = model({
18
  'question': question,
19
  'context': input_description
20
  })
 
21
  if target_feature == "price":
22
- # price median
23
  reference_target_value = 1650
24
  else:
25
- # living space median
26
  reference_target_value = 85
 
27
  try:
28
  if return_numbers:
29
- nums = re.findall(r"\d*\.\d+|\d+\,\d+|\d{1,3}'[\d{3}']+\d{1,3}\.?\d*|(?<!m)\d+",answer['answer'])
30
- nums = [re.sub("\,|\'", "", num) for num in nums]
31
- # turn every number into float
32
  if len(nums) > 1:
33
  nums = [float(x) for x in nums]
34
  answer_processed = min(nums, key=lambda x:abs(x-reference_target_value))
35
  elif len(nums) == 1:
36
  answer_processed = float(''.join(nums))
 
 
37
  else:
38
- answer = answer['answer']
39
- answer_processed = round(answer_processed, 2)
 
40
  answer_full = answer['answer']
41
  score = answer['score']
42
- return ('%f' % answer_processed).rstrip('0').rstrip('.'), score, answer_full
43
  except:
44
  return "No answer!", None, None
45
 
46
- #---------------------------------------------------------------------------------
47
- # define the parameters
 
 
 
 
 
 
 
 
 
 
 
48
  title = "Extract relevant features from Real Estate Descriptions!"
49
 
50
  description = """
51
- <center>
52
- <img src="https://teara.govt.nz/files/c-21363-atl.jpg" width=300px>
53
- </center>
54
- <div style="text-align: justify">
55
- Features with missing instances can negatively impact the performance of machine learning models. Information Extraction (IE) can improve the availability of tabular data by identifying relevant information from unstructured textual descriptions. This project demonstrated the application of IE on descriptions of online real estate listings, whereby the required missing values are retrieved from the text. Inspired by question-answering tasks, the aim was to recover these values by asking a set of questions. We tested two ways to achieve this goal. The first one focuses on a model specific to the language of the description (French) to perform IE, while the second translates the descriptions into English before IE. The project compared the performance of both approaches while delivering insights on how the formulation of the questions can impact the effectiveness of Q&A models.
 
 
56
  </div>
57
  """
58
- article = """
59
- <center>
60
 
61
- Created by [Ilia Azizi](https://iliaazizi.netlify.app/) 2022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
- </center>
64
- """
 
 
 
 
 
65
 
66
- # add some examples
67
- french_example = """ Venez découvrir votre futur appartement lors des portes ouvertes Quai Ouest à Renens le samedi 6 mars de 9h00 à 12h00. Afin de respecter les mesures de sécurité, merci d'inscrire une personne par tranche horaire. Merci de laisser vos coordonnées (nom, email et téléphone) afin que l'on puisse vous joindre pour confirmer le rendez-vous et l'adresse. Lorsque vous entrer votre nom pour vous inscrire, merci d'indiquer également l'appartement que vous souhaitez visiter (n° ou nombre de pièces). En cas d'intérêt, merci de venir avec un dossier complet : - 3 dernières fiches de salaire - Extrait de l'office des poursuites - Copie carte d'identité ou permis de séjour - Copie de votre police d'assurance RC (responsabilité civile) et ménage Un formulaire de location sera à disposition sur place. Pour en savoir plus: https://quai-ouest.ch/location/logements\nINSCRIPTIONS : https://doodle.com/poll/5cvrqyt2ueaah3su?utm_source=poll&utm_medium=link\nNouvelle promotion de 89 logements en location idéalement située à la Gare de Renens, Quai Ouest ouvrira ses bras aux futurs locataires avec plusieurs options de logements, commerces et bureaux.\nCe magnifique appartement de 4.5 pièces se situe au 3° étage et a été construit avec de très beaux matériaux et se compose comme suit:\nSpacieux séjour de 40m2\nSuite parentale de 23.9m2 avec salle de douche italienne attenante\nDeux chambres à coucher d'environ 13m2 chacune\nRaccordement pour colonne de lavage\nUne salle de bains/WC\nCuisine ouverte avec îlot central et entièrement agencée avec lave-vaisselle\nStores électriques\nEntrée avec armoires murales\nLoyer net : CHF 2'600 .-\nCharges: CHF 320.-\nTotal: CHF 2'920.-\nAdresse: Place de la Gare à 1020 Renens\nPlus d'informations sur www.quai-ouest.ch/location/logements ainsi que chez Omnia Immobilier"""
 
 
 
68
 
69
- english_example = """Come and discover your future apartment at the Quai Ouest open house in Renens on Saturday, March 6th, from 9:00 am to 12:00 pm. In order to respect the security measures, please register one person per hour. Please leave your contact details (name, email and telephone) so that you can be reached to confirm the appointment and address. When entering your name to register, please also indicate the apartment you wish to visit (no or number of rooms). In case of interest, please come with a complete file: - 3 last salary slips - Excerpt from the prosecution office - Copy of identity card or residence permit - Copy of your insurance policy RC (civil liability) and household A rental form will be available on site. For more information: https://quai-ouest.ch/rental/housing INSCRIPTIONS: https://doodle.com/poll/5cvrqyt2ueaah3su?utm_source=poll&utm_medium=link New promotion of 89 rental units ideally located at the Gare de Renens, several new housing options. This magnificent 4.5-room apartment is located on the 3rd floor and has been built with beautiful materials and consists as follows: Spacious living room of 40m2 Master suite of 23.9m2 with adjoining Italian shower room Two bedrooms of about 13m2 each Wash-column connection A bathroom/WC Open kitchen with central island and fully arranged with dishwasher Electric stores Entrance with wall cabinets Net rent: CHF 2'600 .- Charges: CHF 320.- Total: CHF 2'920.- Address: Place de la Gare à 1020 Renens More information on www.quai-ouest.ch/location/housing as well as at Omnia Immobilier"""
 
 
 
70
 
71
- examples = [["French", french_example, 'price', "Combien payez-vous de loyer?"],
72
- ["French", french_example, 'living_space', "Quelle est la surface en m2?"],
73
- ["English", english_example, 'price', "How much is the rent?"],
74
- ["English", english_example, 'living_space', "How large is the surface?"]]
 
75
 
76
- #---------------------------------------------------------------------------------
77
- # run the demo
78
- demo = gr.Interface(
79
- fn=get_native_feature_demo,
80
- inputs=[
81
- gr.inputs.Radio(["French", "English"], label="Language", type = "value"),
82
- gr.inputs.Textbox(lines=10, label="Real Estate Description", placeholder="Type a real estate description here."),
83
- gr.inputs.Dropdown(["price", "living_space"], label="Target Feature", type = "value"),
84
- gr.inputs.Textbox(lines=2, label="Question", placeholder="Ask to retrieve a feature.")],
85
- outputs = [gr.outputs.Textbox(label = "Extracted Feature"), gr.outputs.Textbox(label = "Probability of the prediction"), gr.outputs.Textbox(label = "Full Q&A answer")],
86
- title = title,
87
- description = description,
88
- article = article,
89
- examples=examples
90
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
- demo.launch(inline=False)
 
 
1
+ # app.py
2
  from transformers import pipeline
3
  import gradio as gr
4
  import torch
5
  import re
6
 
7
+ def get_native_feature_demo(language, input_description, target_feature, question, return_numbers=True):
 
 
8
  task = 'question-answering'
9
  french_model = 'AgentPublic/camembert-base-squadFR-fquad-piaf'
10
  english_model = 'deepset/roberta-base-squad2'
11
+
12
  if language == "French":
13
  model = pipeline(task, model=french_model, tokenizer=french_model)
14
  else:
15
  model = pipeline(task, model=english_model, tokenizer=english_model)
16
+
17
  answer = model({
18
  'question': question,
19
  'context': input_description
20
  })
21
+
22
  if target_feature == "price":
 
23
  reference_target_value = 1650
24
  else:
 
25
  reference_target_value = 85
26
+
27
  try:
28
  if return_numbers:
29
+ nums = re.findall(r"\d*\.\d+|\d+\,\d+|\d{1,3}'[\d{3}']+\d{1,3}\.?\d*|(?<!m)\d+", answer['answer'])
30
+ nums = [re.sub(r",|'", "", num) for num in nums] # Fixed escape sequence
 
31
  if len(nums) > 1:
32
  nums = [float(x) for x in nums]
33
  answer_processed = min(nums, key=lambda x:abs(x-reference_target_value))
34
  elif len(nums) == 1:
35
  answer_processed = float(''.join(nums))
36
+ else:
37
+ return "No numbers found!", None, None
38
  else:
39
+ answer_processed = answer['answer']
40
+
41
+ answer_processed = round(float(answer_processed), 2)
42
  answer_full = answer['answer']
43
  score = answer['score']
44
+ return ('%f' % answer_processed).rstrip('0').rstrip('.'), f"{score:.4f}", answer_full
45
  except:
46
  return "No answer!", None, None
47
 
48
+ # Example data
49
+ french_example = """ Venez découvrir votre futur appartement lors des portes ouvertes Quai Ouest à Renens le samedi 6 mars de 9h00 à 12h00. Afin de respecter les mesures de sécurité, merci d'inscrire une personne par tranche horaire. Merci de laisser vos coordonnées (nom, email et téléphone) afin que l'on puisse vous joindre pour confirmer le rendez-vous et l'adresse. Lorsque vous entrer votre nom pour vous inscrire, merci d'indiquer également l'appartement que vous souhaitez visiter (n° ou nombre de pièces). En cas d'intérêt, merci de venir avec un dossier complet : - 3 dernières fiches de salaire - Extrait de l'office des poursuites - Copie carte d'identité ou permis de séjour - Copie de votre police d'assurance RC (responsabilité civile) et ménage Un formulaire de location sera à disposition sur place. Pour en savoir plus: https://quai-ouest.ch/location/logements\nINSCRIPTIONS : https://doodle.com/poll/5cvrqyt2ueaah3su?utm_source=poll&utm_medium=link\nNouvelle promotion de 89 logements en location idéalement située à la Gare de Renens, Quai Ouest ouvrira ses bras aux futurs locataires avec plusieurs options de logements, commerces et bureaux.\nCe magnifique appartement de 4.5 pièces se situe au 3° étage et a été construit avec de très beaux matériaux et se compose comme suit:\nSpacieux séjour de 40m2\nSuite parentale de 23.9m2 avec salle de douche italienne attenante\nDeux chambres à coucher d'environ 13m2 chacune\nRaccordement pour colonne de lavage\nUne salle de bains/WC\nCuisine ouverte avec îlot central et entièrement agencée avec lave-vaisselle\nStores électriques\nEntrée avec armoires murales\nLoyer net : CHF 2'600 .-\nCharges: CHF 320.-\nTotal: CHF 2'920.-\nAdresse: Place de la Gare à 1020 Renens\nPlus d'informations sur www.quai-ouest.ch/location/logements ainsi que chez Omnia Immobilier"""
50
+
51
+ english_example = """Come and discover your future apartment at the Quai Ouest open house in Renens on Saturday, March 6th, from 9:00 am to 12:00 pm. In order to respect the security measures, please register one person per hour. Please leave your contact details (name, email and telephone) so that you can be reached to confirm the appointment and address. When entering your name to register, please also indicate the apartment you wish to visit (no or number of rooms). In case of interest, please come with a complete file: - 3 last salary slips - Excerpt from the prosecution office - Copy of identity card or residence permit - Copy of your insurance policy RC (civil liability) and household A rental form will be available on site. For more information: https://quai-ouest.ch/rental/housing INSCRIPTIONS: https://doodle.com/poll/5cvrqyt2ueaah3su?utm_source=poll&utm_medium=link New promotion of 89 rental units ideally located at the Gare de Renens, several new housing options. This magnificent 4.5-room apartment is located on the 3rd floor and has been built with beautiful materials and consists as follows: Spacious living room of 40m2 Master suite of 23.9m2 with adjoining Italian shower room Two bedrooms of about 13m2 each Wash-column connection A bathroom/WC Open kitchen with central island and fully arranged with dishwasher Electric stores Entrance with wall cabinets Net rent: CHF 2'600 .- Charges: CHF 320.- Total: CHF 2'920.- Address: Place de la Gare à 1020 Renens More information on www.quai-ouest.ch/location/housing as well as at Omnia Immobilier"""
52
+
53
+ examples = [
54
+ ["French", french_example, 'price', "Combien payez-vous de loyer?"],
55
+ ["French", french_example, 'living_space', "Quelle est la surface en m2?"],
56
+ ["English", english_example, 'price', "How much is the rent?"],
57
+ ["English", english_example, 'living_space', "How large is the surface?"]
58
+ ]
59
+
60
+ # Define the parameters
61
  title = "Extract relevant features from Real Estate Descriptions!"
62
 
63
  description = """
64
+ <div style="margin-bottom: 1.5rem;">
65
+ <div style="display: flex; justify-content: center; margin-bottom: 1.5rem">
66
+ <img src="https://teara.govt.nz/files/c-21363-atl.jpg" width="300px" alt="Real Estate Image" style="border-radius: 8px;"/>
67
+ </div>
68
+ <div style="text-align: justify">
69
+ Features with missing instances can negatively impact the performance of machine learning models. Information Extraction (IE) can improve the availability of tabular data by identifying relevant information from unstructured textual descriptions. This project demonstrated the application of IE on descriptions of online real estate listings, whereby the required missing values are retrieved from the text. Inspired by question-answering tasks, the aim was to recover these values by asking a set of questions. We tested two ways to achieve this goal. The first one focuses on a model specific to the language of the description (French) to perform IE, while the second translates the descriptions into English before IE. The project compared the performance of both approaches while delivering insights on how the formulation of the questions can impact the effectiveness of Q&A models.
70
+ </div>
71
  </div>
72
  """
 
 
73
 
74
+ css = """
75
+ /* Comprehensive table text alignment */
76
+ .table-wrap table td,
77
+ .table-wrap table td div,
78
+ .table-wrap table td p,
79
+ .examples-table td,
80
+ .examples-table td div,
81
+ .examples-table td p,
82
+ .prose td,
83
+ .prose td div,
84
+ .prose td p {
85
+ text-align: left !important;
86
+ white-space: pre-wrap !important;
87
+ word-break: break-word !important;
88
+ }
89
 
90
+ /* Ensure specific targeting of the real estate description column */
91
+ .table-wrap table td:nth-child(2),
92
+ .table-wrap table td:nth-child(2) div,
93
+ .table-wrap table td:nth-child(2) p {
94
+ text-align: left !important;
95
+ padding: 8px !important;
96
+ }
97
 
98
+ /* Additional styling for better readability */
99
+ .table-wrap table {
100
+ width: 100% !important;
101
+ table-layout: fixed !important;
102
+ }
103
 
104
+ .table-wrap table td {
105
+ vertical-align: top !important;
106
+ }
107
+ """
108
 
109
+ article = """
110
+ <div style="text-align: center; margin-top: 1.5rem;">
111
+ Created by <a href="https://iliaazizi.netlify.app/" target="_blank" style="color: #2563eb;">Ilia Azizi</a> 2022
112
+ </div>
113
+ """
114
 
115
+ # Create the Gradio interface
116
+ with gr.Blocks(title=title, css=css) as demo:
117
+ gr.HTML(description)
118
+
119
+ with gr.Row():
120
+ with gr.Column():
121
+ language = gr.Radio(
122
+ choices=["French", "English"],
123
+ label="Language",
124
+ value="French"
125
+ )
126
+ target_feature = gr.Dropdown(
127
+ choices=["price", "living_space"],
128
+ label="Target Feature",
129
+ value="price"
130
+ )
131
+ question = gr.Textbox(
132
+ lines=2,
133
+ label="Question",
134
+ placeholder="Ask to retrieve a feature."
135
+ )
136
+ input_description = gr.Textbox(
137
+ lines=10,
138
+ label="Real Estate Description",
139
+ placeholder="Type a real estate description here."
140
+ )
141
+ submit_btn = gr.Button("Extract Feature", variant="primary")
142
+
143
+ with gr.Column():
144
+ extracted_feature = gr.Textbox(label="Extracted Feature")
145
+ prediction_prob = gr.Textbox(label="Probability of the prediction")
146
+ full_answer = gr.Textbox(label="Full Q&A answer")
147
+
148
+ gr.Examples(
149
+ examples=examples,
150
+ inputs=[language, input_description, target_feature, question],
151
+ outputs=[extracted_feature, prediction_prob, full_answer],
152
+ fn=get_native_feature_demo,
153
+ cache_examples=True
154
+ )
155
+
156
+ gr.HTML(article)
157
+
158
+ submit_btn.click(
159
+ fn=get_native_feature_demo,
160
+ inputs=[language, input_description, target_feature, question],
161
+ outputs=[extracted_feature, prediction_prob, full_answer]
162
+ )
163
 
164
+ if __name__ == "__main__":
165
+ demo.launch()
requirements.txt CHANGED
@@ -1,5 +1,7 @@
1
- transformers
2
- torch
3
- regex
4
- gradio
5
- sentencepiece
 
 
 
1
+ gradio>=4.12.0
2
+ torch>=2.0.0
3
+ transformers>=4.36.0
4
+ protobuf>=4.25.1
5
+ sentencepiece>=0.1.99
6
+ tokenizers>=0.15.0
7
+ sacremoses>=0.1.1