MI calculations based on C extension for python and Pandas.
Project description
Description
C library for python with custom mutual information calculations. Originally was part of https://github.com/volkoshkursk/NB.
There are two approach to calculate the MI: based on the Pandas framework and based on the custom C library. Pandas-based approach is faster, however you need to construct a DataFrame with columns doc_id target token where token is the column with only one token in the row. If you have a much data it can be memory-expensive operation.
From the other hand, the custom library - based approach does not need in some special dataframe. It needs only two iterables with same lengthes: the targets and the textes. However, it is slower than the pandas-based approach.
Requirements
If you want to build by make you need to have make and python-dev packages installed.
It is recommended to have a poetry library.
Installation
There is several different ways to install this library:
Installation with poetry.
This is a simpliest and recommended way to install the library. Just run
poetry install
åto install the library. Then you can run your code in poetry's virtual environment with
poetry run script.py
where script.py is your script.
Building from sources.
This way is useful if you don't have a poetry by some reason. However, it is strongly recommended to use the poetry installation.
You need create libmi.so to run this project. For this purpose you need installed python3-dev on your system. For building on library *nix system run
make clean && make
Default Python version is 3.8. If you need build for another version run
make clean && make VER=<ver>
where instead <ver> should be your version.
Also, you need to install Python dependencies with
pip install -r requirements.txt
Theory
MI is a non-negative value. It is equal to 0 when random variables are independent.
The main formula, using for calculating MI was found in book Manning K.D., Raghavan P., Schütze H. Introduction to information search.
$$ \begin{align} I(U,C) = {N_{11} \over N} \log_2\bigl({N_{11}N \over{(N_{10} + N_{11}) (N_{11} + N_{01})}}\bigr) + \ {N_{01} \over N} \log_2({{N_{01} N} \over {(N_{00} + N_{01}) (N_{11} + N_{01})}}) + \ {N_{10} \over N} \log_2({{N_{10} N} \over {(N_{10} + N_{11}) (N_{10} + N_{00})}}) + \ {N_{00} \over N} \log_2({{N_{00} N} \over {(N_{00} + N_{01}) (N_{10} + N_{00})}}), \end{align} $$
where
- $U$ is the random variable, shows presence of the word W.
- $C$ is the random variable, shows presence of the theme T.
- $N$ is the number of all docs in dataset,
- $N_{11}$ is the number of documents which have word W and theme T,
- $N_{10}$ is the number of documents which have word W and haven't theme T,
- $N_{01}$ is the number of documents which haven't word W and have theme T,
- $N_{00}$ is the number of documents which haven't word W and theme T.
As we can see, the formula above can be calculated only if $N_{11}N_{00}N_{01}N_{11} > 0$. When we have lots of themes and less of documents this becomes a problem: for large number of word we can not calculate MI.
This problem can be solved by going to the limit in each summand in formaula above. However, the result will be different with precise formula even if the formula can be calculated.
Differences between approaches
As it was told upper, there is two approaches to mutual information calculation. First of them is based on custom C extension. It is slower than another one, but require less memory for running. Second of them based on Pandas framework. It is faster than the C-based approach, but requires a lot of memory.
The another difference between the approaches is in handling division-by-zero exception.
In Pandas-based approach if $N_{11}N_{00}N_{01}N_{11} = 0$ the result is equal to $0$. In C-extension based approach if $N_{11}N_{00}N_{01} = 0$ the result is calulated as a sum of the summand, where logarithm can be calculated.
Using
C-based approach
There are two function you can use: mi and multi_mi. The first one calculate MI for one word and one theme. The second one uses mi for build a dictionary for all words and all themes.
mi
Args:
- txts (Iterable[str]): Iterable of texts.
- tgts (Iterable[str]): Iterable of targets corresponding to texts from txts. All targets corresponding to one text should be separated by "|".
- word (str): Word for building Mutual Information for.
- tgt (str): Target for building mutual information for.
Result (float): Mutual Information between word and tgt.
multi_mi
Args:
- txts (Iterable[str]): Iterable of texts.
- tgts (Iterable[str]): Iterable of targets corresponding to texts from txts. All targets corresponding to one text should be separated by "|".
- targets_ (Iterable[str]): Iterable of targets.
- vocabulary (Iterable[str]): list of words.
- workers (int, optional): The number of parallel processes. Defaults to 16.
Result (dict[dict[float]]): dictionary of dictionaries with MI as values.
Example of result:
{
'quick': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'brown': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'fox': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'jumps': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'over': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'the': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'lazy': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
'dog': {
'target_1': 0.1,
'target_2': 0.2,
'target_3': 0.3
},
}
Pandas-based approach
For using Pandas-based approach you should call the function mutual_info_pipeline, which generate a function in which you should send a Pandas.Dataframe, which has follow structure: it has some item identifyer (for example id of document), word and target. This DataFrame can content some other column, but this three is necessary.
The result will contain follow columns:
- target - name of target,
- tokens - the word,
- N11 - the number of documents which have both the word and the theme,
- NT - the number of documents which have the theme,
- N1 - the number of documents which have the word,
- N - the number of all docs in dataset, which haven't the theme,
- N10 - the number of documents which have the word and haven't the theme,
- N01 - the number of documents which haven't the word and have the theme,
- N00 - the number of documents which haven't both the word and the theme,
- N0 - the number of documents which haven't the word,
- mutual_information - MI for the word and the theme.
mutual_info_pipeline
Args:
- target (str): target columne name.
- tokens (str): tokens column name.
- doc_id (str): item id column name.
- docs_number (int): number of docs.
Result (Callable[[DataFrame[TokenFrame]], DataFrame[TokensMIFrame]]): compute pipeline.
Example of using:
from mi import mutual_info_pipeline
mutual_info_pipeline(
'target',
'word',
'item_id',
docs_number,
)(df)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file text_mi-0.1.0.tar.gz.
File metadata
- Download URL: text_mi-0.1.0.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.11.2 Darwin/18.7.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
777ab67e280112067e2438d855faa67074cf66cafaac6e0d54d8c4384df00502
|
|
| MD5 |
f0582cfe3219cca7e7756b5ec9a96e8a
|
|
| BLAKE2b-256 |
ca65a052d930a69ad4b4b4680d774a2b2b2fbcb4d03cc0ba9ca98207bc23f5ad
|
File details
Details for the file text_mi-0.1.0-cp311-cp311-macosx_10_14_x86_64.whl.
File metadata
- Download URL: text_mi-0.1.0-cp311-cp311-macosx_10_14_x86_64.whl
- Upload date:
- Size: 13.4 kB
- Tags: CPython 3.11, macOS 10.14+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.11.2 Darwin/18.7.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64aa2a49b29152508e54b77154296367561e189cf6324140f45e7340b37f7789
|
|
| MD5 |
f1d3d94c08e4f9d2880636eb9c4bf698
|
|
| BLAKE2b-256 |
2d707be0e7caa6c092ecf2ffd5fab85f1507a310f97ad6eadc8fa826be3faef9
|