跳转到主要内容

用于处理词-文档矩阵的Python库和工具

项目描述

termdoc

用于处理词-文档矩阵的Python库和工具

此项目刚刚开始,但已提供有用的数据结构,HTDM(层次词-文档矩阵)。

将很快实现TDM的各种计算,包括TF-IDF。

我还对标准化HTDM的交换格式感兴趣。

安装

pip install termdoc

需要Python 3.10或更高版本。

HTDM

核心数据结构是一个支持层次文档的词-文档矩阵。文档用如“1.7.5”或“Plato.Republic.5”之类的分隔字符串标记。这种层次结构可以表示作品的划分、多个作品的分组,或两者的组合。计数在层次结构的每一级(包括顶层以获取所有文档的总计)汇总。

可以使用load加载HTDM

>>> import termdoc
>>> c = termdoc.HTDM()
>>> c.load("test_data/test1.tsv")

其中文件看起来像这样

1.1	foo	7
1.1	bar	4
1.2	foo	2
1.3	bar	1
2.1	baz	5
2.1	foo	1

使用点分隔的层次地址/文档ID,词和计数,所有这些都用制表符分隔。

点和制表符只是默认值,可以通过将address_sep和/或field_sep传递给load来覆盖。

HTDM可以在文档层次结构的任何级别提供计数

>>> c.get_counts()["foo"]
10
>>> c.get_counts("1")["foo"]
9
>>> c.get_counts("1.2")["foo"]
2

注意地址/文档ID中使用的分隔符默认为点(无论在load中使用什么)但可以通过将address_sep传递给HTDM构造函数来覆盖。

HTDM也可以通过编程方式构建。

以下是一个具有单级文档(传统TDM)的示例

>>> import termdoc
>>> c = termdoc.HTDM()
>>> c.increment_count("1", "foo", 3)  # document 1 contains the term "foo" 3 times
>>> c.increment_count("1", "bar", 2)
>>> c.increment_count("2", "foo", 2)
>>> c.increment_count("2", "bar", 1)
>>> c.get_counts()["foo"]
5
>>> c.get_counts()["bar"]
3

以下是一个具有两级层次的示例

>>> import termdoc
>>> c = termdoc.HTDM()
>>> c.increment_count("1.1", "foo", 3)
>>> c.increment_count("1.2", "foo", 3)
>>> c.increment_count("1.1", "bar", 2)
>>> c.increment_count("1.2", "bar", 2)
>>> c.increment_count("2.1", "foo", 2)
>>> c.increment_count("2.2", "foo", 2)
>>> c.increment_count("2.1", "bar", 1)
>>> c.increment_count("2.2", "bar")
>>> c.get_counts()["foo"]
10
>>> c.get_counts()["bar"]
6
>>> c.get_counts("2")["foo"]
4

注意,如果计数为1,则可以省略。

可以使用add(address, term_list)一次性为特定地址添加整个令牌列表

>>> import termdoc
>>> c = termdoc.HTDM()
>>> c.add("1.1", ["foo", "bar", "bar", "baz"])
>>> c.add("1.2", ["foo", "foo"])
>>> c.get_counts()["bar"]
2
>>> c.get_counts()["foo"]
3
>>> c.get_counts("1.2")["foo"]
2

您可以使用prune(n)方法将HTDM修剪为仅n级。

您可以使用 leaf_entries() 方法遍历 HTDM 叶子节点的文档-词频(此方法返回一个生成器,产生 (document_address, term, count) 元组)。这实际上是一个传统的 TDM(文档 ID 仍将反映层次结构,但汇总计数不存在)。

您可以选择向 leaf_entries() 传递一个 prefix,在这种情况下,只有那个子树会被返回(文档 ID 中的前缀将被移除)。

您可以使用 graft(prefix, subtree) 方法将一个 HTDM 嵌套到另一个中,指定 prefix 为要添加子树的文档地址。如果您有一个为单一作者的作品创建的 HTDM,章节作为文档,并且希望将其纳入更高层次的作者多部作品的 HTDM 或不同作者的集合作品 HTDM 中,这非常有用。

或者,您可以为 load 提供一个 prefix 来在树中的特定点加载文件。这实际上将给定的 prefix(加上地址分隔符)添加到文档 ID 前面。

在加载的文件中,如果计数为 1,则可以省略第三个(计数)字段,并且文档 ID + 词可以重复,计数累加。

您可以使用 copy() 深拷贝一个 HTDM。如果您只想克隆子树,也可以向 copy() 传递一个前缀。

您可以使用 save() 将 HTDM 保存到文件,该方法接受一个 filename 以及可选的 field_sep(默认为制表符)和 prefix(如果您只想保存子树)。

计算

您可以使用 tf(term)tf(term, address) 获取词频。

>>> c = termdoc.HTDM()
>>> c.increment_count("1", "foo")
>>> c.increment_count("1", "bar", 3)
>>> c.increment_count("2", "foo", 3)
>>> c.increment_count("2", "bar")
>>> c.tf("foo")
0.5
>>> c.tf("foo", "2")
0.75

您还可以使用 df(term) 获取文档频率。

>>> c = termdoc.HTDM()
>>> c.add("1.1", ["foo", "bar"])
>>> c.add("1.2", ["bar"])
>>> c.add("2.1", ["foo"])
>>> c.add("2.2", ["foo", "bar", "baz"])
>>> c.df("foo")
0.75
>>> c.df("bar")
0.75
>>> c.df("baz")
0.25

默认情况下,这会将树的叶子视为文档,但您可以指定一个明确的层数来向下计算。例如,以下代码只会将 12 视为文档(不包括 1.11.22.12.2)。

>>> c.df("foo", level=1)
1.0
>>> c.df("bar", level=1)
1.0
>>> c.df("baz", level=1)
0.5

此外,您可以将计算范围限定在子树上,在这种情况下,就是 1 下面的文档 1.11.2

>>> c.df("foo", "1")
0.5
>>> c.df("bar", "1")
1.0
>>> c.df("baz", "1")
0.0

这种范围可以与层级限制结合使用。

您可以使用 tf_idf(term, address) 计算词和文档的 TF-IDF。

>>> c = termdoc.HTDM()
>>> c.add("1", ["this", "is", "a", "a", "sample"])
>>> c.add("2", ["this", "is", "another", "another", "example", "example", "example"])
>>> c.tf_idf("example", "1")
0.0
>>> c.tf_idf("example", "2")
0.12901285528456335

您还可以将 TF-IDF 计算的范围限定在子树上。

>>> c = termdoc.HTDM()
>>> c.add("1.1", ["foo", "bar"])
>>> c.add("1.2", ["bar"])
>>> c.add("2.1", ["foo"])
>>> c.add("2.2", ["foo", "bar", "baz"])

>>> c.tf_idf("foo", "1.1", "1")
0.1505149978319906

请注意,如果后者给出,地址必须以子树前缀开头。

重复策略

您可以选择向构造函数传递一个 duplicates 设置,指示在更新一个词-文档计数多次时您想要遵循的策略。

>>> c = termdoc.HTDM()
>>> c.increment_count("", "foo", 3)
>>> c.increment_count("", "foo", 2)
>>> c.get_counts()["foo"]
5

>>> c = termdoc.HTDM(duplicates=termdoc.Duplicates.ALLOW)
>>> c.increment_count("", "foo", 3)
>>> c.increment_count("", "foo", 2)
>>> c.get_counts()["foo"]
5

相同,但您可以指示 HTDM 忽略尝试更新现有计数的操作

>>> c = termdoc.HTDM(duplicates=termdoc.Duplicates.IGNORE)
>>> c.increment_count("", "foo", 3)
>>> c.increment_count("", "foo", 2)
>>> c.get_counts()["foo"]
3

或引发异常

>>> c = termdoc.HTDM(duplicates=termdoc.Duplicates.ERROR)
>>> c.increment_count("", "foo", 3)
>>> c.increment_count("", "foo", 2)  # this will raise a ValueError
Traceback (most recent call last):
ValueError: 'foo' already in ''

请注意,只有在文档树的叶子节点中才会检查重复项。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。

源分布

termdoc-0.3.tar.gz (5.7 kB 查看哈希值)

构建分布

termdoc-0.3-py3-none-any.whl (5.9 kB 查看哈希值)

上传于 Python 3

由以下提供支持