用于处理词-文档矩阵的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
默认情况下,这会将树的叶子视为文档,但您可以指定一个明确的层数来向下计算。例如,以下代码只会将 1
和 2
视为文档(不包括 1.1
、1.2
、2.1
、2.2
)。
>>> c.df("foo", level=1)
1.0
>>> c.df("bar", level=1)
1.0
>>> c.df("baz", level=1)
0.5
此外,您可以将计算范围限定在子树上,在这种情况下,就是 1
下面的文档 1.1
和 1.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 ''
请注意,只有在文档树的叶子节点中才会检查重复项。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。