1+ from nlp .base_core import BaseCore
2+ from transformers import pipeline
3+ from bson import ObjectId
4+
5+ class NERCore (BaseCore ):
6+ def __init__ (self ):
7+ print ("constructing NER Core instance" )
8+ super ().__init__ (
9+ task = "ner" ,
10+ model_name = "dslim/bert-base-NER" ,
11+ aggregation_strategy = "simple"
12+ )
13+
14+ def process_article (self , article_id : str ):
15+ #Retrieve article by ID
16+ article = self .collection .find_one ({"_id" : ObjectId (article_id )})
17+
18+ if not article :
19+ print (f"No article found with ID: { article_id } " )
20+ return []
21+
22+ if article .get ("processed" ) is True :
23+ print (f"Article { article_id } already processed." )
24+ return []
25+
26+ # We have a check running so only articles with full text are saved
27+ full_text = article .get ("full_text" , "" )
28+ # if not full_text:
29+ # print(f"Article {article_id} has no full text.")
30+ # return
31+
32+ # Run NER
33+ entities = self .pipeline (full_text ) # run_ner_hf(full_text)
34+
35+ # Update article in DB
36+ self .addToEntryInDB (article_id , {
37+ "ner" : entities ,
38+ "processed" : True
39+ })
40+
41+ return entities
42+
43+ def format_ner_tags (self , ner_list ):
44+ formatted = []
45+ for ent in ner_list :
46+ label = ent .get ("label" ) or ent .get ("entity" ) or ent .get ("entity_group" , "UNKNOWN" )
47+ text = ent .get ("text" ) or ent .get ("word" ) or ""
48+ formatted .append (f"{ label } : { text } " )
49+ return ", " .join (formatted )
50+
51+ def addToEntryInDB (self , entry_id , updates ):
52+ print ("Adding NER results to database\r \r \r " )
53+
54+ if "ner" in updates :
55+ for ent in updates ["ner" ]:
56+ ent ["score" ] = float (ent ["score" ]) # convert np.float32 to Python float
57+
58+ updates ["ner_pretty" ] = self .format_ner_tags (updates ["ner" ]) # so we can actually read the NER
59+
60+ id = ObjectId (entry_id )
61+ self .collection .update_one (
62+ {"_id" : id },
63+ {"$set" : updates }
64+ )
0 commit comments