def tokenize(self, dftokenz=pd.DataFrame(), persistent=True, n_frac=1): env = Environment() enc = Word_Encoder() t_start = timer() if dftokenz.empty: dftokenz = self.tokenz() if n_frac < 1: dftokenz = dftokenz.sample(frac=n_frac) env.debug( 1, ['Transforming to tokenz: START %s words' % dftokenz.shape[0]]) gmask = dftokenz.groupby(['gram']) df_posstat = gmask.count() df_posstat.to_csv(env.filename_stat_pos_tokenz_csv(), encoding='utf-8') print('POSTagger', 'train dataset stat:\n', gmask.count()) fields = [ 's_suffix2', 's_suffix3', 's_prefix2', 's_prefix3', 'n_token', 'n_len', 'n_tokens2', 'n_tokens3', 'n_tokenp2', 'n_tokenp3' ] for field in fields: val = 0.0 if field[0] == 's': val = '' dftokenz[field] = val n_letters = 0 s_letters = env.list_rus_letters() di_letters = env.di_bgm_byletters #bgm_columns_i = env.bgm_columns_list(mode=0) bgm_columns = env.bgm_columns_list(mode=1) #print('bgm_columns', bgm_columns) for column_name in bgm_columns: dftokenz[column_name] = None t_end = timer() env.debug(1, [ 'POStagger', 'Letters bigram columns added', env.job_time(t_start, t_end) ]) #Form tokenz t_start = timer() for index, serie in dftokenz.iterrows(): # print (serie.values) a_word = enc.s2token(index, serie) i = 2 # print(a_word) for field in fields: dftokenz.at[index, field] = a_word[i] # print(field, a_word[i]) i = i + 1 # print(dftokenz.loc[index]) #Letters bigram binaries for n_l in range(0, len(a_word[0]) - 1): n_l2 = n_l + 1 di_n = di_letters.get('%s%s' % (a_word[0][n_l], a_word[0][n_l2])) if di_n is not None: #print(di_n) #print(bgm_columns[di_n]) dftokenz.at[index, bgm_columns[di_n]] = 1 t_end = timer() env.debug( 1, ['Transforming to tokenz: COMPLETE', env.job_time(t_start, t_end)]) if persistent: dftokenz.to_csv(env.filename_tokenz_csv(), encoding='utf-8') env.debug(1, ['Tokenz written to CSV:', env.filename_tokenz_csv()]) return dftokenz
def predict(self, aidtext, b_makestat=False): env = Environment() # Открываем файл со статистикой по тестовым текстам df_stat = pd.read_csv( env.filename_stat_test_csv(), index_col='idstat', encoding='utf-8') # Статистика по тстовым текстам df_texts = pd.read_csv(env.filename_predict_csv(), index_col='idtext', encoding='utf-8') # Реестр текстов mask = df_texts.index.isin(aidtext) df_texts = df_texts[mask] columns = ['idtext', 'idchunk', 'idauthor', 'author', 'name', 'file', \ 'sentences_text', 'words_text','sentence_mean', \ 'sentences_chunk', 'words_chunk', 'words_uniq_chunk','uniq_per_sent_chunk','uniq_per_words_chunk', \ 'NOUN','ADJF','ADJS','COMP','VERB','INFN','PRTF','PRTS','GRND','NUMR',\ 'ADVB','NPRO','PRED','PREP','CONJ','PRCL','INTJ', 'predict'] y_result = [] #Если необходимо подготовить статистику по тестовым текстам if b_makestat: for index, row in df_texts.iterrows( ): # Для каждого текста, который надо обработать file_txt = df_texts.at[index, 'filename'] # Read text file env.debug(1, ['Analyzer', 'predict', 'START file TXT:', file_txt]) t_start = timer() file = codecs.open(file_txt, "r", "utf_8_sig") text = file.read().strip() file.close() # Автор в тестовой выборке вообще говоря нет idauthor = df_texts.at[index, 'idauthor'] # Автор #idauthor = 0 name = df_texts.at[index, 'name'] # Название # Собственно обработка текста df_add = self.analyze_text( columns, text, index, idauthor, name, file_txt) # Analyze text, get Series #print(df_add) df_add.reset_index(drop=True, inplace=True) df_stat = df_stat.append( df_add, ignore_index=True) #Добавляем к файлу результатов df_stat.reset_index(drop=True, inplace=True) df_stat.index.name = 'idstat' t_end = timer() env.debug(1, [ 'END file TXT:', file_txt, 'time:', env.job_time(t_start, t_end) ]) #df_stat теперь содержит информацию о всех тестовых текстах, которые хотели обработать #Указываем верный тип для целочисленных колонок int_cols = [ 'idtext', 'idchunk', 'idauthor', 'sentences_text', 'words_text', 'sentences_chunk', 'words_chunk', 'words_uniq_chunk' ] for col in int_cols: df_stat[col] = df_stat[col].astype(int) # Сохраняем результат на диск df_stat.to_csv(env.filename_stat_test_csv(), encoding='utf-8') #Статистика готова # Открываем файл со статистикой по тестовым текстам df_stat = pd.read_csv( env.filename_stat_test_csv(), index_col='idstat', encoding='utf-8') # Статистика по тстовым текстам #mask = df_stat.index.isin(aidtext) #df_stat2predict = df_stat[mask] #Предсказываем авторов y_res = self.model_predict(df_stat.loc[aidtext]) #print(y_res) df_stat.loc[aidtext, 'predict'] = y_res.astype(int) #print(df_stat) #y_result.append(y_res[0]) #Сохраняем измененный файл с предсказаниями df_stat.to_csv(env.filename_stat_test_csv(), encoding='utf-8') return y_res #Возвращаем предсказания
def analyze_text(self, columns, text_to_analyze, index=0, idauthor=0, name='', file_txt='', max_words=0): env = Environment() t_start = timer() env.debug( 1, ['Analyzer', 'analyze_text', 'START file TXT: %s' % file_txt]) enc = Word_Encoder() postg = POSTagger() corpus = OpenCorpus() dfgram = corpus.grammemes() file_authors = env.filename_authors_csv() #Информация об авторах authors = pd.read_csv(file_authors, index_col='idauthor', encoding='utf-8') dfres = pd.DataFrame() #Пустой dataframe для сохранения результат #Preprocessing: выполнить прдварительную обработку текста #max_words = 6000 achunks = self.preprocessor(text_to_analyze, max_words) #print(achunks) n_chunks = len(achunks) # на сколько частей разделён текст #на выходе получили массив, каждывй элемент которого содеоржит число предложений, число слов в тексте, массив со словами env.debug(1, [ 'Analyzer', 'analyze_text', '%s sentences %s words in %s chunks' % (achunks[0][0], achunks[0][1], n_chunks) ]) #print(n_chunks) a_text_corp = [] id_chunk = 0 for chunk in achunks: t_start = timer() #prepare data n_sent_all = chunk[0] n_words_all = chunk[1] n_sent_len_mean = chunk[2] n_sent_chunk = chunk[3] n_words_chunk = chunk[4] a_text_words = chunk[5] #print(n_sent_all, n_words_all, n_sent_len_mean, n_sent_chunk, n_words_chunk, a_text_words) #print(len(a_text_words)) # Vectorize - к каждой части относимся как к индивидуальному тексту vectorizer = CountVectorizer(encoding='utf-8', token_pattern=r"(?u)\b\w+\b") #Преобразуем все слова в матрицу из одной строки (0) и множества колонок, где каждому слову соотвествует # колонка, а количество вхождений слова в документе - значение в этой колонке #print([' '.join(map(str,a_text_words))]) X = vectorizer.fit_transform([' '.join(map(str, a_text_words))]) #print(X) n_words_chunk_check = X.sum( ) #Сколько всего слов в документе, который обрабатываем #print(n_words_chunk, n_words_chunk_check) #print(vectorizer.get_stop_words()) env.debug(1, [ 'Analyzer', 'analyze_text', 'START process chunk %s/%s with %s words' % (id_chunk, n_chunks - 1, n_words_chunk) ]) word_freq = np.asarray(X.sum(axis=0)).ravel( ) #для каждого слова его суммарное число (т.к. у нас одна строка == числу в ней) #print(vectorizer.get_feature_names()) #print(X) zl = zip(vectorizer.get_feature_names(), word_freq) # words, count #print(list(zl)) data_cols = ['gram', 'gram_voc', 'gram_ml'] data = pd.DataFrame(list(zl), columns=['word', 'count']) for col in data_cols: data[col] = '' t_end = timer() env.debug( 1, ['Ready for POS:', 'time:', env.job_time(t_start, t_end)]) t_start = timer() data = postg.pos(data) #print(data) t_end = timer() env.debug(1, ['POS tagged:', 'time:', env.job_time(t_start, t_end)]) t_start = timer() grouped = data.sort_values('gram').groupby(['gram']).agg( {'count': ['sum']}) grouped.columns = ['n_POS'] grouped.reset_index(inplace=True) grouped['f_POS'] = grouped['n_POS'] / n_words_chunk #grouped.drop(columns=['n_POS'], inplace=True) #print(grouped) #print(grouped.set_index('gram').T) grouped = pd.merge( dfgram, grouped, left_on='name', right_on='gram', how='left').drop( columns=['alias', 'description', 'name', 'n_POS']).fillna( 0).set_index('gram').T #grouped = pd.merge(dfgram, grouped, left_on='name', right_on='gram', how='left').fillna(0).set_index('gram') #print(grouped) #print(grouped.values.ravel()) index_author = authors.index.get_loc(idauthor) n_uniq_words = data.shape[0] s_chunk = pd.Series({ 'idtext': index, 'idchunk': id_chunk, 'idauthor': idauthor, 'author': authors.at[index_author, 'shortname'], 'name': name, 'file': file_txt, 'sentences_text': np.int64(n_sent_all), 'words_text': np.int64(n_words_all), 'sentence_mean': n_sent_len_mean, 'sentences_chunk': np.int64(n_sent_chunk), 'words_chunk': np.int64(n_words_chunk), 'words_uniq_chunk': np.int64(n_uniq_words), 'uniq_per_sent_chunk': round(n_uniq_words / n_sent_chunk, 4), 'uniq_per_words_chunk': round(n_uniq_words / n_words_chunk, 4) }) s_chunk = pd.concat( [s_chunk, pd.Series(grouped.values.ravel())], ignore_index=True) s_chunk = pd.concat([s_chunk, pd.Series([np.nan])], ignore_index=True) #print(s_chunk) #print(grouped) t_end = timer() env.debug(1, ['Analyzed', 'time:', env.job_time(t_start, t_end)]) dfres = dfres.append(s_chunk, ignore_index=True) #dfres = env.downcast_dtypes(dfres) id_chunk = id_chunk + 1 print(dfres) print(columns) dfres.columns = columns return dfres
def process_from_texts_file(self, aidtext, mode='process', max_words=0): env = Environment() file_res = env.filename_results_csv() dfres = pd.read_csv( file_res, index_col='idstat', encoding='utf-8') #Файл для записи статистических результатов #dfres = env.downcast_dtypes(dfres) df_texts = pd.read_csv(env.filename_texts_csv(), index_col='idtext', encoding='utf-8') #Реестр текстов mask = df_texts.index.isin(aidtext) df_texts = df_texts[mask] for index, row in df_texts.iterrows( ): #Для каждого текста, который надо обработать file_txt = df_texts.at[index, 'filename'] #Read text file env.debug(1, ['START file TXT:', file_txt]) t_start = timer() #file = open(file_txt, 'r') file = codecs.open(file_txt, "r", "utf_8_sig") text = file.read().strip() file.close() # print(text) #Автор в обучающей выборке указанг idauthor = df_texts.at[index, 'idauthor'] #Автор name = df_texts.at[index, 'name'] #Название columns = dfres.columns if mode == 'process': #если необходимо собрать информацию о тексте и записать её в results #Собственно обработка текста df_add = self.analyze_text( columns, text, index, idauthor, name, file_txt, max_words) #Analyze text, get Series df_add.reset_index(drop=True, inplace=True) dfres = dfres.append( df_add, ignore_index=True) #Добавляем к файлу результатов dfres.reset_index(drop=True, inplace=True) dfres.index.name = 'idstat' #print(dfres) #return 0 if mode == 'chunk_size': # если необходимо определить размер chunk n_chunk_size = self.validate_chunk_size( columns, text, index, idauthor, name, file_txt) t_end = timer() env.debug(1, [ 'END file TXT:', file_txt, 'time:', env.job_time(t_start, t_end) ]) # print(dfres.head()) #Сохраняем результат на диск if mode == 'process': #dfres = dfres.reset_index(drop=True) int_cols = [ 'idtext', 'idchunk', 'idauthor', 'sentences_text', 'words_text', 'sentences_chunk', 'words_chunk', 'words_uniq_chunk' ] for col in int_cols: dfres[col] = dfres[col].astype(int) #dfres = env.downcast_dtypes(dfres) dfres.to_csv(file_res, encoding='utf-8')
def preprocessor(self, text, max_words=0): env = Environment() t_start = timer() text2 = text.lower() env.debug(1, ['Analyzer', 'preprocessor', 'START Preprocessing:']) tokenizer = RegexpTokenizer(self.word_tokenizers_custom()) tokens_words = tokenizer.tokenize(text2) # Слова текста tokens_sent = sent_tokenize( text2) # Предложения - пока не используются в нашем проекте n_words_count = len(tokens_words) # Количество слов в тексте n_sent_count = len(tokens_sent) # Количество предложений в тексте n_sent_len_mean = n_words_count / n_sent_count # Средняя длина предложения в словах #Делим текст на части - chunks awords = [] #Массив # Если документ большой, разделяем его на несколько частей (chunks) и считаем # статистику для каждого в отдельности. # Это нам позволит имея небольшое число объёмных документов корректно обучить модель if (max_words > 0): n_sent_chunk = int( max_words // n_sent_len_mean ) #Сколько предложение в 1 chunks содержащее max_words print('n_sent_chunk', n_sent_chunk) #подбираем, чтобы текст был разделен равномерно i_chunks = 1 tmp_sent_chunk = n_sent_count while tmp_sent_chunk > n_sent_chunk: i_chunks = i_chunks + 1 tmp_sent_chunk = int( math.ceil(n_sent_count // i_chunks) + (n_sent_count % i_chunks)) n = 0 n_sent_chunk = tmp_sent_chunk #итоговое значение сколько предложений пойдет в chunk print('tmp_sent_chunk', tmp_sent_chunk) while n < n_sent_count: #print(n, n_sent_chunk) asents = tokens_sent[ n:n + n_sent_chunk] #Предложения от n до n+chunk #print(asents) a_sent_words = [] #слова текущей группы предложений for sent in asents: words = tokenizer.tokenize(sent) a_sent_words.extend(words) #print(a_sent_words) awords.append([ n_sent_count, n_words_count, len(a_sent_words) / len(asents), len(asents), len(a_sent_words), a_sent_words ]) n = n + n_sent_chunk else: awords.append([ n_sent_count, n_words_count, n_sent_len_mean, len(tokens_sent), len(tokens_words), tokens_words ]) #print(awords) t_end = timer() env.debug(1, ['Preprocessed:', 'time:', env.job_time(t_start, t_end)]) return awords #Массив со словами и статистикой