Создание TfidfVectorizer поверх текстового столбца огромного информационного кадра панд - PullRequest
0 голосов
/ 13 декабря 2018

Мне нужно получить матрицу функций TF-IDF из текста, хранящегося в столбцах огромного кадра данных , загруженного из файла CSV (который не помещается в памяти).Я пытаюсь перебрать кадр данных, используя куски, но он возвращает объекты генератора, который не является ожидаемым типом переменной для метода TfidfVectorizer .Я предполагаю, что я делаю что-то не так при написании метода генератора ChunkIterator, показанного ниже.

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer


#Will work only for small Dataset
csvfilename = 'data_elements.csv'
df = pd.read_csv(csvfilename)
vectorizer = TfidfVectorizer()
corpus  = df['text_column'].values
vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())



#Trying to use a generator to parse over a huge dataframe
def ChunkIterator(filename):
    for chunk in pd.read_csv(csvfilename, chunksize=1):
       yield chunk['text_column'].values

corpus  = ChunkIterator(csvfilename)
vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())

Может кто-нибудь посоветовать, как изменить метод ChunkIterator выше или любой другой подход с использованием dataframe.Я хотел бы избежать создания отдельных текстовых файлов для каждой строки в dataframe .Ниже приведены некоторые фиктивные данные CSV-файла для воссоздания сценария.

id,text_column,tags
001, This is the first document .,['sports','entertainment']
002, This document is the second document .,"['politics', 'asia']"
003, And this is the third one .,['europe','nato']
004, Is this the first document ?,"['sports', 'soccer']"

1 Ответ

0 голосов
/ 13 декабря 2018

Метод принимает генераторы просто отлично.Но для этого требуется итерация необработанных документов , то есть строк .Ваш генератор представляет собой итерацию из numpy.ndarray объектов.Так что попробуйте что-то вроде:

def ChunkIterator(filename):
    for chunk in pd.read_csv(csvfilename, chunksize=1):
        for document in chunk['text_column'].values:
            yield document

Обратите внимание, я не очень понимаю, почему вы здесь используете панд.Просто используйте обычный модуль csv, например:

import csv
def doc_generator(filepath, textcol=0, skipheader=True):
    with open(filepath) as f:
        reader = csv.reader(f)
        if skipheader:
            next(reader, None)
        for row in reader:
            yield row[textcol]

Итак, в вашем случае, передайте 1 в textcol, например:

In [1]: from sklearn.feature_extraction.text import TfidfVectorizer

In [2]: import csv
   ...: def doc_generator(filepath, textcol=0, skipheader=True):
   ...:     with open(filepath) as f:
   ...:         reader = csv.reader(f)
   ...:         if skipheader:
   ...:             next(reader, None)
   ...:         for row in reader:
   ...:             yield row[textcol]
   ...:

In [3]: vectorizer = TfidfVectorizer()

In [4]: result = vectorizer.fit_transform(doc_generator('testing.csv', textcol=1))

In [5]: result
Out[5]:
<4x9 sparse matrix of type '<class 'numpy.float64'>'
    with 21 stored elements in Compressed Sparse Row format>

In [6]: result.todense()
Out[6]:
matrix([[ 0.        ,  0.46979139,  0.58028582,  0.38408524,  0.        ,
          0.        ,  0.38408524,  0.        ,  0.38408524],
        [ 0.        ,  0.6876236 ,  0.        ,  0.28108867,  0.        ,
          0.53864762,  0.28108867,  0.        ,  0.28108867],
        [ 0.51184851,  0.        ,  0.        ,  0.26710379,  0.51184851,
          0.        ,  0.26710379,  0.51184851,  0.26710379],
        [ 0.        ,  0.46979139,  0.58028582,  0.38408524,  0.        ,
          0.        ,  0.38408524,  0.        ,  0.38408524]])
...