def perform_sentence_segmentation(data_dict): from parsivar import Tokenizer my_tokenizer = Tokenizer() return_value = {} for folder_name in data_dict.keys(): return_value[folder_name] = {} for file_name in data_dict[folder_name].keys(): tmp_text = data_dict[folder_name][file_name] token_text = my_tokenizer.tokenize_sentences(tmp_text) return_value[folder_name][file_name] = token_text return return_value
def perform_word_tokenization(data_dict): from parsivar import Tokenizer my_tokenizer = Tokenizer() return_value = {} for folder_name in data_dict.keys(): return_value[folder_name] = {} for file_name in data_dict[folder_name].keys(): this_sentences_words = [] for sent_text in data_dict[folder_name][file_name]: token_text = my_tokenizer.tokenize_words(sent_text) this_sentences_words.append(token_text) return_value[folder_name][file_name] = this_sentences_words return return_value
return text # Persian Stopwords Load persian_stopwords = pd.read_csv("./persian_stopwords.txt", delimiter='\t', names=["ستون"]) # Add Custom Persian Stopwords my_data = [] my_persian_stopwords = pd.DataFrame(my_data, columns=["ستون"]) # Main my_tokenizer = Tokenizer() def preprocessing_parsivar(readData): #### Clean text sentence = CleanText(readData) #### Tokenize morphs = my_tokenizer.tokenize_words(sentence) # Remove Stopwords morphs[:] = (morph for morph in morphs if morph not in persian_stopwords["ستون"].tolist()) morphs[:] = (morph for morph in morphs if morph not in my_persian_stopwords["ستون"].tolist())
temp_precision + temp_recall) except: pass precision.append(temp_precision) recall.append(temp_recall) fmeasure.append(temp_fmeasure) precision, recall, fmeasure = np.mean(precision), np.mean(recall), np.mean( fmeasure) print(f'Precision: {precision}, Recall: {recall}, F-measure: {fmeasure}') ################################# Performance ##################################### berttokenizer = BertTokenizer.from_pretrained( 'HooshvareLab/bert-fa-base-uncased', do_lower_case=False) parsivarTokenizer = Tokenizer() df = pd.read_excel('Tokenizer.xlsx', header=None) df = df.iloc[:156, :2] df.columns = ['text', 'label'] token_evaluation(df['label'], df['text'], hazm_tokenizer) token_evaluation(df['label'], df['text'], parsivar_tokenizer) token_evaluation(df['label'], df['text'], nltk_tokenizer) token_evaluation(df['label'], df['text'], transformers_tokenizer) #evaluation compounds token_evaluation_compounds(df['label'], df['text'], hazm_tokenizer)
from parsivar import Tokenizer my_tokenizer = Tokenizer() f = open("Sentence.txt", "r", encoding='utf-8-sig') _sentences = f.readlines() sentences = [] for _sentence in _sentences: sents = my_tokenizer.tokenize_sentences(_sentence)
class PreParation(): _tokenizer = Tokenizer() sw = None # Stop Words correction = None # Correction Collection ازتمیخوام -> ازت میخوام _normalizer = None # Normilizer ي --> ی _normalizer1 = None # Normilizer _tokenizer1 = None # Hazm Tokenizer _tokenizer2 = None # Hazm Tokenizer _stemmer = None # Stemmer گفت --> گو extraChar1 = ["؛", "؟", ",", ";", "!", "?", ".", ":", "،"] extraChar2 = [ "'", '"', "+", "{", "}", "-", "(", ")", "$", "#", '/', "\\", "@", "*", "٪", "÷", "¿", "[", "]", "«", "»", "^", "`", "|", "¡", "˘", "¤", "£", "<", ">", "¯", "°", "٭", "٫" ] _emojiList = None # Regular Experssion persianmixRE = None numRE = None removeIrritateRE = None emojiRE = None # Embedding w2vModel = None # این کلاس برای مقدار دهی اولیه مورد استفاده قرار میگیرد def __init__(self): self.sw = pd.read_csv("data/stop_words/stpwrd.csv") # از فایل مربوطه ستون واژه های ایست را انتخاب میکنیم و به صورت لیست رشته ای باز میگردانیم self.sw = self.sw["StopWord"].astype(str).values.tolist() self.correction = pd.read_csv("data/Vocab_dataset_1.csv", index_col=0, header=None, squeeze=True).to_dict() self._normalizer = Normalizer(statistical_space_correction=True, date_normalizing_needed=True) self._normalizer1 = HazmNormal() self._tokenizer1 = HazmTokenizer(join_verb_parts=False, replace_hashtags=True, replace_numbers=True, separate_emoji=True) self._tokenizer2 = HazmTokenizer(join_verb_parts=False, replace_hashtags=True, replace_numbers=False, separate_emoji=True) self._stemmer = FindStems() # region Regular Experssion # عبارتی که کلمات و اعداد به هم چسبیده را از هم جدا میکند self.persianmixRE = re.compile( "(([\u0600-\u06FF]+)([0-9]+)|([0-9]+)([\u0600-\u06FF]+)|([a-zA-Z]+)([0-9]+)|([0-9]+)([a-zA-Z]+))" ) # برای اینکه متوجه شویم در متن عدد وجود دارد از این عبارت استفاده میکنیم self.numRE = re.compile('\d') self.removeIrritateRE = re.compile(r'(.)\1{2,}', re.IGNORECASE) # Emoji self.emojiRE = re.compile( pattern="[" u"\U0001F600-\U0001F64F" # emoticons u"\U0001F300-\U0001F5FF" # symbols & pictographs u"\U0001F680-\U0001F6FF" # transport & map symbols u"\U0001F1E0-\U0001F1FF" # flags (iOS) "]+", flags=re.UNICODE) # endregion self._emojiList = list(emoji.UNICODE_EMOJI.keys()) #self.w2vModel = Word2Vec.load('P:/pkl/newSentence.bin') print("\n ** Persian Text PreParation by Naghme Jamali ** \n") # Remove Multiple Space - "Salam khobi?" -> "Salam Khobi?" def RemoveMultipleSpace(self, txt): return re.sub(' +', ' ', txt) # Remove Emoji def RemoveEmoji(self, txt): for emoji in self._emojiList: txt = txt.replace(emoji, ' EMOJI ') return txt # return self.RemoveMultipleSpace(self.emojiRE.sub(r' ', txt)) def RemoveExtraChar1(self, txt): for i in self.extraChar1: txt = txt.replace(i, " ") return txt def RemoveExtraChar2(self, txt): for i in self.extraChar2: txt = txt.replace(i, " ") return txt # تبدیل شماره ها به انگلیسی def NumberEN(self, input): return input.replace("۰", "0").replace("۱", "1").replace( "۲", "2").replace("۳", "3").replace("۴", "4").replace("۵", "5").replace( "٥", "5").replace("۶", "6").replace("v", "7").replace( "۷", "7").replace("۸", "8").replace("۹", "9") # حذف ایست واژه در زبان فارسی def stop_word(self, data): text = self.RemoveMultipleSpace(data) text = self.RemoveMultipleSpace(' '.join( [word for word in data.split() if word not in self.sw])) return text.strip() # if text != " " and text != "": # return ' '.join([word for word in text.split() if word not in self.sw]).strip() # else: # return '' # جداسازی اعداد و متن از یکدیگر def splitnumber(self, txt): if self.numRE.search(txt) != None: res = self.persianmixRE.match(txt).groups() return (" ".join([word for word in res[1:] if word != None])) return txt # ریشه کلمات را باز میگرداند # در صورتی که چند ریشه داشته باشد ما اولی را برمیداریم # در صورتی که در این ابزار ریشه برای کلمه پیدا نشد # همان کلمه را باز میگرداند def Stem(self, txt): _txt = self._stemmer.convert_to_stem(txt).split('&') return _txt[0] # حروف تکراری موجود در متن را حذف مینماید # برای مثال خوووووبی میشود خوبی def removeIrritate(self, txt): return self.removeIrritateRE.sub(r'\1', txt) def CorrectionText(self, texts): _texts = [] for _text in self.wordToken(texts): if _text in self.correction: _texts.append(self.correction[_text]) else: _texts.append(_text) return ' '.join(_texts) # تمیز کردن متون: # نرمال سازی داده ها # حذف حروف و نشانه های اضافه # در ورود یک فلگ میزاریم برای مواقعی که میخواهیم از حذف ایست واژه ها استفاده کنیم def cleanText(self, txt, stopword=False, isSplitNumber=True): #txt = txt.replace("\u200c", " ") txt = txt.replace("آ", "ا") if stopword: # آیا ایست واژه حذف شوند؟ txt = self.stop_word(txt) txt = self.removeIrritate(txt) # حذف کاراکترهای تکراری txt = self.RemoveEmoji(txt) txt = self._normalizer1.normalize(txt) txt = self.RemoveExtraChar2(txt) txt = self.RemoveMultipleSpace(txt) txt = self.NumberEN(txt) txt1 = [] for t in self.wordToken(txt): if isSplitNumber: try: t = self.splitnumber(t) # جداسازی اعداد از متن در یک کلمه except: pass for _t in t.split(): w1 = self.Stem(_t) txt1.append(w1) if stopword: return self.stop_word(' '.join(txt1)).strip() return (' '.join(txt1)).strip() # مرحله دوم از حذف علائم و نشانه ها # و چرا این همه جایگزینی کلمات و نشانه ها، بدلیل اینکه # کتابخانه های موجود عکس العملی به این علامت و نگارش های غلط # نشان نمیدهد و برای اینکه بتوان آن ها را تصحیح کرد از روش استفاده میکنیم # تا کلمات تصحیح شوند و به شکل درست خود بازگردند def cleanText2(self, txt, stopword=False, isTokenize=False): _txt = txt if stopword: _txt = self.stop_word(txt) # در این خط، نیم فاصله ای که ابزارهای پارسی وار و هضم ایجاد کرده اند را به فاصله تبدیل میکنیم #_txt = _txt.replace("\u200c", " ") _txt = ' '.join(self.wordToken(_txt, replaceNumber=True)) _txt = self.CorrectionText(_txt) _txt = self._normalizer1.normalize(_txt) _txt = self.NumberEN(_txt) if stopword: _txt = self.stop_word(_txt).strip() return _txt # توکنایز در سطح جمله def token(self, txt): _sents = self._tokenizer.tokenize_sentences(txt) sents = [] for _txt in _sents: _txt = self.RemoveExtraChar1(_txt) _txt = self.RemoveMultipleSpace(_txt).strip() sents.append(_txt) return sents # جایگزینی اعداد Exmaple: 5 عدد --> NUM1 عدد # هضم نمیتواند بعضی از اعداد را تشحیص دهد # برای همین این تابع را نوشتیم تا آن را پوشش دهد def ReplaceNumber(self, input1): if input1.isnumeric(): return "NUM" + str(len(input1)) else: return input1 def wordToken(self, txt, replaceNumber=False, removeExtra=False, stopword=False): if removeExtra: txt = self.RemoveExtraChar1(txt) txt = self.RemoveMultipleSpace(txt).strip() _words = [] if replaceNumber: _words.extend( self.ReplaceNumber(x) for x in self._tokenizer1.tokenize(txt)) else: _words.extend(self._tokenizer2.tokenize(txt)) if stopword: return [word for word in _words if word not in self.sw] else: return _words
def get_unique_words(text_path): ''' This function get text corpus path as input and give set of unique words as output. Parameters ---------- text_path : str Path to where our corpus exist (must in .txt format). Raises If spell check package of parsivar won't found.' ------ Returns ------- words_set : set Set of unique words from corpus. ''' # Create a list from all text text_names = glob(join_path(text_path, '*.txt')) sentences = [] for name in text_names: with open(name, 'r') as text: text_sentences = tuple(text.readlines()) for sentence in text_sentences: sentence = sentence.strip('\n') sentences.append(sentence[sentence.find('|') + 1:]) # Specify Signs and Numbers in order to avoid words contain them enter in our final Set signs = [ '،', '«', '»', '.', ')', '(', '"', ':', ';', '%', '-', '?', ',', '؛', "'", '_' ] numbers = [f'{i}' for i in range(10)] # Create Set of all words in corpus try: spell = SpellCheck() except: raise Exception( 'Please download spell.zip from https://www.dropbox.com/s/tlyvnzv1ha9y1kl/spell.zip?dl=0 and extract to path to parsivar/resource.' ) normal = Normalizer() token = Tokenizer() stemm = FindStems() words_set = set() print('\n Start to extract and clean words from sentences! \n') with progressbar.ProgressBar(max_value=len(sentences), redirect_stdout=True) as bar: for sentence, i in zip(sentences, range(len(sentences))): sentence = normal.normalize(spell.spell_corrector(sentence)) sentence = sentence.replace(u'\u200c', ' ') words = token.tokenize_words(sentence) for word in words: word = stemm.convert_to_stem(word) if '&' in word: #This pattern found manually in text word = word[:word.find('&')] if word in signs: # Ignore signs bar.update(i) continue for let in word: # Ignore words contain numbers if let in numbers: bar.update(i) continue if len(word) <= 1: # ignore one (or less)letter strings bar.update(i) continue words_set.add(word) bar.update(i) return words_set
from parsivar import Normalizer from parsivar import Tokenizer from parsivar import FindStems from parsivar import POSTagger my_normalizer = Normalizer() my_tokenizer = Tokenizer() my_stemmer = FindStems() my_tagger = POSTagger( tagging_model="stanford") # tagging_model = "wapiti" or "stanford" tokens = [] ignore = ['،', '؟'] f = open("zaban-e_atash.txt", "r") for line in f: tmp_txt = line words = my_tokenizer.tokenize_words(my_normalizer.normalize(tmp_txt)) for word in words: if word not in tokens: if word not in ignore: tokens.append(word) f.close() print("<table>") print("<td>Stem</td><td>Token & POS</td>") for token in tokens: stem = my_stemmer.convert_to_stem(token) token_pos = my_tagger.parse(my_tokenizer.tokenize_words(token))