Spaces:
Build error
Build error
Commit ·
581a861
1
Parent(s): a7fdc57
Update helper.py
Browse files
helper.py
CHANGED
|
@@ -116,6 +116,7 @@ def validate_locations(locations):
|
|
| 116 |
return validated_loc
|
| 117 |
|
| 118 |
|
|
|
|
| 119 |
def identify_loc_ner(sentence):
|
| 120 |
"""
|
| 121 |
Identify all the geopolitical and location entities with the spacy tool
|
|
@@ -140,6 +141,7 @@ def identify_loc_ner(sentence):
|
|
| 140 |
return ner_locations
|
| 141 |
|
| 142 |
|
|
|
|
| 143 |
def identify_loc_geoparselibs(sentence):
|
| 144 |
"""
|
| 145 |
Identify cities and countries with 3 different geoparsing libraries
|
|
@@ -189,6 +191,7 @@ def identify_loc_geoparselibs(sentence):
|
|
| 189 |
return (geoparse_locations, countries, cities)
|
| 190 |
|
| 191 |
|
|
|
|
| 192 |
def identify_loc_regex(sentence):
|
| 193 |
"""
|
| 194 |
Identify cities and countries with regular expression matching
|
|
@@ -206,6 +209,7 @@ def identify_loc_regex(sentence):
|
|
| 206 |
return regex_locations
|
| 207 |
|
| 208 |
|
|
|
|
| 209 |
def identify_loc_embeddings(sentence, countries, cities):
|
| 210 |
"""
|
| 211 |
Identify cities and countries with the BERT pre-trained embeddings matching
|
|
@@ -248,6 +252,120 @@ def identify_loc_embeddings(sentence, countries, cities):
|
|
| 248 |
return embd_locations
|
| 249 |
|
| 250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
def identify_locations(sentence):
|
| 252 |
"""
|
| 253 |
Identify all the possible Country and City references in the given sentence, using different approaches in a hybrid manner
|
|
@@ -257,6 +375,9 @@ def identify_locations(sentence):
|
|
| 257 |
|
| 258 |
try:
|
| 259 |
|
|
|
|
|
|
|
|
|
|
| 260 |
# ner
|
| 261 |
locations.append(identify_loc_ner(sentence))
|
| 262 |
|
|
@@ -290,12 +411,17 @@ def identify_locations(sentence):
|
|
| 290 |
validated_locations = validate_locations(loc_capitalization)
|
| 291 |
|
| 292 |
# create a proper dictionary with country/city tags and the relevant entries as a result
|
| 293 |
-
|
| 294 |
for location, loc_type in validated_locations:
|
| 295 |
-
if loc_type not in
|
| 296 |
-
|
| 297 |
-
|
|
|
|
|
|
|
|
|
|
| 298 |
|
|
|
|
|
|
|
| 299 |
|
| 300 |
# conditions for multiple references
|
| 301 |
# it is mandatory that a country will exist
|
|
|
|
| 116 |
return validated_loc
|
| 117 |
|
| 118 |
|
| 119 |
+
|
| 120 |
def identify_loc_ner(sentence):
|
| 121 |
"""
|
| 122 |
Identify all the geopolitical and location entities with the spacy tool
|
|
|
|
| 141 |
return ner_locations
|
| 142 |
|
| 143 |
|
| 144 |
+
|
| 145 |
def identify_loc_geoparselibs(sentence):
|
| 146 |
"""
|
| 147 |
Identify cities and countries with 3 different geoparsing libraries
|
|
|
|
| 191 |
return (geoparse_locations, countries, cities)
|
| 192 |
|
| 193 |
|
| 194 |
+
|
| 195 |
def identify_loc_regex(sentence):
|
| 196 |
"""
|
| 197 |
Identify cities and countries with regular expression matching
|
|
|
|
| 209 |
return regex_locations
|
| 210 |
|
| 211 |
|
| 212 |
+
|
| 213 |
def identify_loc_embeddings(sentence, countries, cities):
|
| 214 |
"""
|
| 215 |
Identify cities and countries with the BERT pre-trained embeddings matching
|
|
|
|
| 252 |
return embd_locations
|
| 253 |
|
| 254 |
|
| 255 |
+
|
| 256 |
+
def multiple_country_city_identifications_solve(country_city_dict):
|
| 257 |
+
"""
|
| 258 |
+
This is a function to solve the appearance of multiple identification of countries and cities.
|
| 259 |
+
It checks all the elements of the input dictionary and if any smaller length element exists as a substring inside
|
| 260 |
+
a bigger length element of it, it deletes the smaller size one. In that sense, a dictionary of the sort
|
| 261 |
+
{'city': ['Port moresby', 'Port'], 'country': ['Guinea', 'Papua new guinea']} will be converted into
|
| 262 |
+
{'city': ['Port moresby'], 'country': ['Papua new guinea']}.
|
| 263 |
+
|
| 264 |
+
The reason for that function, is because such type of incosistencies were identified during country/city identification,
|
| 265 |
+
propably relevant to the geoparsing libraries in use
|
| 266 |
+
"""
|
| 267 |
+
|
| 268 |
+
try:
|
| 269 |
+
|
| 270 |
+
country_flag = False
|
| 271 |
+
city_flag = False
|
| 272 |
+
|
| 273 |
+
# to avoid examining any element in any case, we validate that both a country and a city exist
|
| 274 |
+
# on the input dictionary and that they are of length more than one (which is the target case for us)
|
| 275 |
+
if 'country' in country_city_dict:
|
| 276 |
+
if len(country_city_dict['country']) > 1:
|
| 277 |
+
country_flag = True
|
| 278 |
+
|
| 279 |
+
if 'city' in country_city_dict:
|
| 280 |
+
if len(country_city_dict['city']) > 1:
|
| 281 |
+
city_flag = True
|
| 282 |
+
|
| 283 |
+
|
| 284 |
+
# at first cope with country multiple iterative references
|
| 285 |
+
if country_flag:
|
| 286 |
+
|
| 287 |
+
# Sort the countries by length, longest first
|
| 288 |
+
country_city_dict['country'].sort(key=lambda x: len(x), reverse=True)
|
| 289 |
+
|
| 290 |
+
# Create a new list of countries that don't contain any substrings
|
| 291 |
+
cleaned_countries = []
|
| 292 |
+
for i in range(len(country_city_dict['country'])):
|
| 293 |
+
is_substring = False
|
| 294 |
+
for j in range(len(cleaned_countries)):
|
| 295 |
+
if country_city_dict['country'][i].lower().find(cleaned_countries[j].lower()) != -1:
|
| 296 |
+
# If the i-th country is a substring of an already-cleaned country, skip it
|
| 297 |
+
is_substring = True
|
| 298 |
+
break
|
| 299 |
+
if not is_substring:
|
| 300 |
+
cleaned_countries.append(country_city_dict['country'][i])
|
| 301 |
+
|
| 302 |
+
# Replace the original list of countries with the cleaned one
|
| 303 |
+
country_city_dict['country'] = cleaned_countries
|
| 304 |
+
|
| 305 |
+
# Create a new list of countries that are not substrings of other countries
|
| 306 |
+
final_countries = []
|
| 307 |
+
for i in range(len(country_city_dict['country'])):
|
| 308 |
+
is_superstring = False
|
| 309 |
+
for j in range(len(country_city_dict['country'])):
|
| 310 |
+
if i == j:
|
| 311 |
+
continue
|
| 312 |
+
if country_city_dict['country'][j].lower().find(country_city_dict['country'][i].lower()) != -1:
|
| 313 |
+
# If the i-th country is a substring of a different country, skip it
|
| 314 |
+
is_superstring = True
|
| 315 |
+
break
|
| 316 |
+
if not is_superstring:
|
| 317 |
+
final_countries.append(country_city_dict['country'][i])
|
| 318 |
+
|
| 319 |
+
# Replace the original list of countries with the final one
|
| 320 |
+
country_city_dict['country'] = final_countries
|
| 321 |
+
|
| 322 |
+
# then cope with city multiple iterative references
|
| 323 |
+
if city_flag:
|
| 324 |
+
|
| 325 |
+
# Sort the cities by length, longest first
|
| 326 |
+
country_city_dict['city'].sort(key=lambda x: len(x), reverse=True)
|
| 327 |
+
|
| 328 |
+
# Create a new list of cities that don't contain any substrings
|
| 329 |
+
cleaned_cities = []
|
| 330 |
+
for i in range(len(country_city_dict['city'])):
|
| 331 |
+
is_substring = False
|
| 332 |
+
for j in range(len(cleaned_cities)):
|
| 333 |
+
if country_city_dict['city'][i].lower().find(cleaned_cities[j].lower()) != -1:
|
| 334 |
+
# If the i-th city is a substring of an already-cleaned city, skip it
|
| 335 |
+
is_substring = True
|
| 336 |
+
break
|
| 337 |
+
if not is_substring:
|
| 338 |
+
cleaned_cities.append(country_city_dict['city'][i])
|
| 339 |
+
|
| 340 |
+
# Replace the original list of cities with the cleaned one
|
| 341 |
+
country_city_dict['city'] = cleaned_cities
|
| 342 |
+
|
| 343 |
+
# Create a new list of cities that are not substrings of other cities
|
| 344 |
+
final_cities = []
|
| 345 |
+
for i in range(len(country_city_dict['city'])):
|
| 346 |
+
is_superstring = False
|
| 347 |
+
for j in range(len(country_city_dict['city'])):
|
| 348 |
+
if i == j:
|
| 349 |
+
continue
|
| 350 |
+
if country_city_dict['city'][j].lower().find(country_city_dict['city'][i].lower()) != -1:
|
| 351 |
+
# If the i-th city is a substring of a different city, skip it
|
| 352 |
+
is_superstring = True
|
| 353 |
+
break
|
| 354 |
+
if not is_superstring:
|
| 355 |
+
final_cities.append(country_city_dict['city'][i])
|
| 356 |
+
|
| 357 |
+
# Replace the original list of cities with the final one
|
| 358 |
+
country_city_dict['city'] = final_cities
|
| 359 |
+
|
| 360 |
+
# return the final dictionary
|
| 361 |
+
if country_city_dict:
|
| 362 |
+
return country_city_dict
|
| 363 |
+
|
| 364 |
+
except:
|
| 365 |
+
return (0, "LOCATION", "unknown_error")
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
|
| 369 |
def identify_locations(sentence):
|
| 370 |
"""
|
| 371 |
Identify all the possible Country and City references in the given sentence, using different approaches in a hybrid manner
|
|
|
|
| 375 |
|
| 376 |
try:
|
| 377 |
|
| 378 |
+
# # # this is because there were cases were a city followed by comma was not understood by the system
|
| 379 |
+
sentence = sentence.replace(",", " x$x ")
|
| 380 |
+
|
| 381 |
# ner
|
| 382 |
locations.append(identify_loc_ner(sentence))
|
| 383 |
|
|
|
|
| 411 |
validated_locations = validate_locations(loc_capitalization)
|
| 412 |
|
| 413 |
# create a proper dictionary with country/city tags and the relevant entries as a result
|
| 414 |
+
loc_dict = {}
|
| 415 |
for location, loc_type in validated_locations:
|
| 416 |
+
if loc_type not in loc_dict:
|
| 417 |
+
loc_dict[loc_type] = []
|
| 418 |
+
loc_dict[loc_type].append(location)
|
| 419 |
+
|
| 420 |
+
# bring sentence on previous form
|
| 421 |
+
sentence = sentence.replace(" x$x ",",")
|
| 422 |
|
| 423 |
+
# cope with cases of iterative country or city reference due to geoparse lib issues
|
| 424 |
+
locations_dict = multiple_country_city_identifications_solve(loc_dict)
|
| 425 |
|
| 426 |
# conditions for multiple references
|
| 427 |
# it is mandatory that a country will exist
|