Beispiel #1
0
    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
Beispiel #2
0
    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  #Возвращаем предсказания
Beispiel #3
0
    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
Beispiel #4
0
    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')
Beispiel #5
0
    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  #Массив со словами и статистикой