Python and tfidf algorithm, make it faster?

2024/12/9 20:55:55

I am implementing the tf-idf algorithm in a web application using Python, however it runs extremely slow. What I basically do is:

1) Create 2 dictionaries:

  • First dictionary: key (document id), value (list of all found words (incl. repeated) in doc)
  • Second dictionary; key (document id), value (set containing unique words of the doc)

Now, there is a petition of a user to get tfidf results of document d. What I do is:

2) Loop over the unique words of the second dictionary for the document d, and for each unique word w get:

2.1) tf score (how many times w appears in d: loop over the the list of words of the first dictionary for the document)

2.2) df score (how many docs contain w: looping over the set of words of all documents (second dictionary) and check if w is contained). I am using a set since it seems to be faster for checking if a set contains a word compared to a list.

Step 2.2 is terribly slow. For example, having 1000 documents, and for a document with 2313 unique words, it takes around 5 minutes to output the results.

Is there any other way to make step 2.2 faster? Are dictionaries that slow for iterating?

Answer

Well, you have to re-think and re-design somehow the way you hold your data, or in other words, implement an "orthodox" version of your "inverted index".

Your bottleneck is the "on-the-fly" calculation of the document frequency (DF) for the terms. It would be a clever idea for this to be dynamic, so every time you update your corpus (collection of documents), do some processing and update the DFs for every term in a document (and of course, save the results in a persistent way, aka a database etc..) .

The only structure you need is a nested dictionary like that

{ "term1" : { "DF" : x, "some_doc_id" : tf , "some_other_doc_id" : tf, etc  } ,"term2" : ...etc..
}

properly updated every time you "feed" your corpus.

And of course, keep somewhere your corpus cardinality...

As a hobby and part of my work, I am implementing a python - redis backed small search engine. You might get some other ideas as well. Take a look here.

https://en.xdnf.cn/q/72944.html

Related Q&A

How to use Python to find all isbn in a text file?

I have a text file text_isbn with loads of ISBN in it. I want to write a script to parse it and write it to a new text file with each ISBN number in a new line.Thus far I could write the regular expres…

AWS Batch Job Execution Results in Step Function

Im newbie to AWS Step Functions and AWS Batch. Im trying to integrate AWS Batch Job with Step Function. AWS Batch Job executes simple python scripts which output string value (High level simplified req…

Simplify Django test set up with mock objects

Often when Im writing tests for my Django project, I have to write a lot more code to set up database records than I do to actually test the object under test. Currently, I try to use test fixtures to …

How to use tf.data.Dataset.padded_batch with a nested shape?

I am building a dataset with two tensors of shape [batch,width,heigh,3] and [batch,class] for each element. For simplicity lets say class = 5.What shape do you feed to dataset.padded_batch(1000,shape)…

Python, thread and gobject

I am writing a program by a framework using pygtk. The main program doing the following things:Create a watchdog thread to monitor some resource Create a client to receive data from socket call gobjec…

How to type annotate overrided methods in a subclass?

Say I already have a method with type annotations:class Shape:def area(self) -> float:raise NotImplementedErrorWhich I will then subclass multiple times:class Circle:def area(self) -> float:retur…

Import Error: No module named pytz after using easy_install

Today is my first day at Python and have been going through problems. One that I was working on was, "Write a short program which extracts the current date and time from the operating system and p…

Python catch exception pandas.errors.ParserError: Error tokenizing data. C error

I am facing problem with my malfunction csv input file whole reading and which i can deal with by adding "error_bad_lines=False" in my read_csv func to remove those.But i need to report these…

Nested tags in BeautifulSoup - Python

Ive looked at many examples on websites and on stackoverflow but I couldnt find a universal solution to my question. Im dealing with a really messy website and Id like to scrape some data. The markup l…

How do I check if a string is a negative number before passing it through int()?

Im trying to write something that checks if a string is a number or a negative. If its a number (positive or negative) it will passed through int(). Unfortunately isdigit() wont recognize it as a numbe…