toponymy 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
toponymy-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Tutte Institute for Mathematics and Computing
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,242 @@
1
+ Metadata-Version: 2.1
2
+ Name: toponymy
3
+ Version: 0.2.0
4
+ Summary: A library for using large language models to name topics
5
+ Home-page: https://github.com/TutteInstitute/toponymy
6
+ Author: John Healy, Leland McInnes
7
+ Author-email: jchealy@gmail.com, leland.mcinnes@gmail.com
8
+ Maintainer: John Healy, Leland McInnes
9
+ Maintainer-email: jchealy@gmail.com, leland.mcinnes@gmail.com
10
+ License: MIT License
11
+ Keywords: topic modeing,representation,cluster,clustering,large language models,LLM,topic naming
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Operating System :: OS Independent
17
+ Requires-Python: >=3.9
18
+ Provides-Extra: dev
19
+ License-File: LICENSE
20
+
21
+ ===========
22
+ Toponymy
23
+ ===========
24
+
25
+ .. image:: doc/toponymy_text_horizontal.png
26
+ :width: 600
27
+ :align: center
28
+ :alt: Toponymy
29
+
30
+ The package name Toponymy is derived from the Greek topos ‘place’ + onuma ‘name’. Thus, the naming of places.
31
+ The goal of Toponymy is to put names to places in the space of information. This could be a corpus of documents,
32
+ in which case Toponymy can be viewed as a topic naming library. It could also be a collection of images, in which case
33
+ Toponymy could be used to name the themes of the images. The goal is to provide a names that can allow a user to
34
+ navigate through the space of information in a meaningful way.
35
+
36
+ Toponymy is designed to scale to very large corpora and collections, providing meaningful names on multiple scales,
37
+ from broad themes to fine-grained topics. We make use a custom clustering methods, information extraction,
38
+ and large language models to power this. The library is designed to be flexible and easy to use.
39
+
40
+ As of now this is an beta version of the library. Things can and will break right now.
41
+ We welcome feedback, use cases and feature suggestions.
42
+
43
+ ------------------
44
+ Basic Installation
45
+ ------------------
46
+
47
+ For now install the latest version of Toponymy from source you can do so by cloning the repository and running:
48
+
49
+ .. code-block:: bash
50
+
51
+ git clone https://github.com/TutteInstitute/toponymy
52
+ cd toponymy
53
+ pip install .
54
+
55
+ -----------
56
+ Basic Usage
57
+ -----------
58
+
59
+ We will need documents, document vectors and a low dimensional representation of these document vector to construct
60
+ a representation. This can be very expensive without a GPU so we recommend storing and reloading these vectors as
61
+ needed. For ease of experimentation we have precomputed and stored such vectors for the `20-Newsgroups dataset <http://qwone.com/~jason/20Newsgroups/>`_
62
+ on hugging face. Code to retrieve these vectors is below.
63
+
64
+ .. code-block:: python
65
+
66
+ pip install pandas
67
+
68
+ import numpy as np
69
+ import pandas as pd
70
+ newsgroups_df = pd.read_parquet("hf://datasets/lmcinnes/20newsgroups_embedded/data/train-00000-of-00001.parquet")
71
+ text = newsgroups_df["post"].str.strip().values
72
+ document_vectors = np.stack(newsgroups_df["embedding"].values)
73
+ document_map = np.stack(newsgroups_df["map"].values)
74
+
75
+ Toponymy also requires an embedding model for determining which of the documents will be most relevant to each
76
+ of our clusters. This doesn't have to be the embedding model that our documents were embedded with but it
77
+ should be similar.
78
+
79
+ .. code-block:: python
80
+
81
+ pip install sentence_transformers
82
+
83
+ from sentence_transformers import SentenceTransformer
84
+ embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
85
+
86
+
87
+ Once the low-dimensional representation is available (``document_map`` in this case), we can do the topic naming.
88
+ Toponymy will make use of a clusterer (such as ``ToponymyClusterer``) to create a balanced hierarchical layered
89
+ clustering of our documents. It will then use a variety of sampling and summarization techniques to construct prompts
90
+ describing each cluster to pass to a large language model (LLM). If you would like to experiment with testing
91
+ various cluster parameters in order construct cluster layers appropriate to your data feel free to cluster
92
+ your data ahead of time via:
93
+
94
+ .. code-block:: python
95
+
96
+ from toponymy import ToponymyClusterer
97
+ clusterer = ToponymyClusterer(min_clusters=4)
98
+ clusterer.fit(clusterable_vectors=document_map, embedding_vectors=document_vectors)
99
+ for i, layer in enumerate(clusterer.cluster_layers_):
100
+ print(f'{len(np.unique(layer.cluster_labels))-1} clusters in layer {i}')
101
+
102
+ 428 clusters in layer 0
103
+ 136 clusters in layer 1
104
+ 42 clusters in layer 2
105
+ 14 clusters in layer 3
106
+ 5 clusters in layer 4
107
+
108
+ Toponymy supports multiple LLMs, including Cohere, OpenAI, and Anthropic via service calls, and local models via
109
+ Huggingface and LlamaCpp. Here we show an example using OpenAI. The following code will generate a topic naming
110
+ for the documents in the data set using an ``embedding_model``, ``document_vectors`` and ``document_map`` created above.
111
+
112
+ .. code-block:: python
113
+
114
+ from toponymy import Toponymy, KeyphraseBuilder
115
+ from toponymy.llm_wrappers import OpenAI
116
+
117
+ openai_api_key = open("openai_key.txt").read().strip()
118
+ llm = OpenAI('openai_api_key')
119
+
120
+ topic_model = Toponymy(
121
+ llm=llm,
122
+ embedding_model=embedding_model,
123
+ clusterer=clusterer,
124
+ object_description="newsgroup posts",
125
+ corpus_description="20-newsgroups dataset",
126
+ exemplar_delimiters=["<EXAMPLE_POST>\n","\n</EXAMPLE_POST>\n\n"],
127
+ )
128
+ topic_model.fit(text, document_vectors, document_map)
129
+
130
+ topic_names = topic_model.topic_names_
131
+ topics_per_document = topic_model.cluster_layers_
132
+
133
+ ``topic_names`` is a list of lists which can be used to explore the unique topic names in each layer or resolution.
134
+ Let's examine the last two layers of topics.
135
+
136
+ .. code-block:: python
137
+
138
+ topic_names[-2:]
139
+
140
+ [['NHL Playoffs and Player Analysis',
141
+ 'Major League Baseball Analysis',
142
+ 'Space Exploration and Technology Innovations',
143
+ 'Encryption Policy and Government Surveillance',
144
+ 'Health and Alternative Treatments',
145
+ 'Israeli-Palestinian and Lebanese Conflicts',
146
+ 'Automotive Performance and Safety',
147
+ 'Christian Theology and Debates',
148
+ 'Waco Siege and Government Accountability',
149
+ 'Debates on Morality and Free Speech',
150
+ 'Gun Rights and Legislation',
151
+ 'X Window System and Graphics Software',
152
+ 'Hard Drive Technologies and Troubleshooting',
153
+ 'Vintage Computer Hardware and Upgrades'],
154
+ ['Sports Analysis',
155
+ 'Religion and Government Accountability',
156
+ 'Automotive Performance and Safety',
157
+ 'X Window System and Graphics Software',
158
+ 'Computer Hardware']]
159
+
160
+
161
+ ``topics_per_document`` contains topic labels for each document, with one list for each level of resultion in our
162
+ cluster layers. In our above case this will be a list of 5 layers each containing a list of 18,170 topic names.
163
+ Documents that aren't contained within a cluster at a given layer are given the topic ``Unlabelled``.
164
+
165
+ .. code-block:: python
166
+
167
+ topics_per_document
168
+
169
+ [array(['Unlabelled',
170
+ 'Discussion on VESA Local Bus Video Cards and Performance',
171
+ 'Unlabelled', ...,
172
+ 'Cooling Solutions and Components for CPUs and Power Supplies',
173
+ 'Algorithms for Finding Sphere from Four Points in 3D',
174
+ 'Automotive Discussions on Performance Cars and Specifications'], dtype=object),
175
+ array(['NHL Playoff Analysis and Predictions',
176
+ 'Graphics Card Performance and Benchmark Discussions',
177
+ 'Armenian Genocide and Turkish Atrocities Discourse', ...,
178
+ 'Cooling Solutions and Components for CPUs and Power Supplies',
179
+ 'Algorithms for 3D Polygon Processing and Geometry',
180
+ 'Discussions on SUVs and Performance Cars'], dtype=object),
181
+ array(['NHL Playoff Analysis and Predictions',
182
+ 'Video Card Drivers and Performance',
183
+ 'Armenian Genocide and Turkish Atrocities', ..., 'Unlabelled',
184
+ 'Unlabelled', 'Automotive Performance and Used Cars'], dtype=object),
185
+ array(['NHL Playoffs and Player Analysis',
186
+ 'Vintage Computer Hardware and Upgrades', 'Unlabelled', ...,
187
+ 'Unlabelled', 'X Window System and Graphics Software',
188
+ 'Automotive Performance and Safety'], dtype=object),
189
+ array(['Sports Analysis', 'Computer Hardware', 'Unlabelled', ...,
190
+ 'Unlabelled', 'X Window System and Graphics Software',
191
+ 'Automotive Performance and Safety'], dtype=object)]
192
+
193
+ At this point we recommend that you explore your data and topic names with an interactive visualization library.
194
+ Our `DataMapPlot <https://github.com/TutteInstitute/datamapplot>`_ library is particularly well suited to exploring
195
+ data maps along with layers of topic names. It takes requires our ``document_map``, ``document_vectors`` and newly created ``topics_per_document``.
196
+
197
+ -------------------
198
+ Vector Construction
199
+ -------------------
200
+
201
+ If you do not have ready made document vectors and low dimensional representations of your data you will need to compute
202
+ your own. For faster encoding change device to: "cuda", "mps", "npu" or "cpu" depending on hardware availability. Alternatively,
203
+ one could make use of an API call to embedding service. Embedding wrappers can be found in:
204
+
205
+ .. code-block:: python
206
+
207
+ from toponymy.embedding_wrappers import OpenAIEmbedder
208
+
209
+ or the embedding wrapper of your choice. Once we generate document vectors we will need to construct a low dimensional representation.
210
+ Here we do that via our UMAP library.
211
+
212
+ .. code-block:: python
213
+
214
+ pip install umap-learn
215
+ pip install pandas
216
+ pip install sentence_transformers
217
+
218
+ import pandas as pd
219
+ from sentence_transformers import SentenceTransformer
220
+ import umap
221
+
222
+ newsgroups_df = pd.read_parquet("hf://datasets/lmcinnes/20newsgroups_embedded/data/train-00000-of-00001.parquet")
223
+ text = newsgroups_df["post"].str.strip().values
224
+ embedding_model = SentenceTransformer("all-MiniLM-L6-v2", device="cpu")
225
+
226
+ document_vectors = embedding_model.encode(text, show_progress_bar=True)
227
+ document_map = umap.UMAP(metric='cosine').fit_transform(document_vectors)
228
+
229
+ -------
230
+ License
231
+ -------
232
+
233
+ Toponymy is MIT licensed. See the LICENSE file for details.
234
+
235
+ ------------
236
+ Contributing
237
+ ------------
238
+
239
+ Contributions are more than welcome! If you have ideas for features of projects please get in touch. Everything from
240
+ code to notebooks to examples and documentation are all *equally valuable* so please don't feel you can't contribute.
241
+ To contribute please `fork the project <https://github.com/TutteInstitute/toponymy/fork>`_ make your
242
+ changes and submit a pull request. We will do our best to work through any issues with you and get your code merged in.
@@ -0,0 +1,222 @@
1
+ ===========
2
+ Toponymy
3
+ ===========
4
+
5
+ .. image:: doc/toponymy_text_horizontal.png
6
+ :width: 600
7
+ :align: center
8
+ :alt: Toponymy
9
+
10
+ The package name Toponymy is derived from the Greek topos ‘place’ + onuma ‘name’. Thus, the naming of places.
11
+ The goal of Toponymy is to put names to places in the space of information. This could be a corpus of documents,
12
+ in which case Toponymy can be viewed as a topic naming library. It could also be a collection of images, in which case
13
+ Toponymy could be used to name the themes of the images. The goal is to provide a names that can allow a user to
14
+ navigate through the space of information in a meaningful way.
15
+
16
+ Toponymy is designed to scale to very large corpora and collections, providing meaningful names on multiple scales,
17
+ from broad themes to fine-grained topics. We make use a custom clustering methods, information extraction,
18
+ and large language models to power this. The library is designed to be flexible and easy to use.
19
+
20
+ As of now this is an beta version of the library. Things can and will break right now.
21
+ We welcome feedback, use cases and feature suggestions.
22
+
23
+ ------------------
24
+ Basic Installation
25
+ ------------------
26
+
27
+ For now install the latest version of Toponymy from source you can do so by cloning the repository and running:
28
+
29
+ .. code-block:: bash
30
+
31
+ git clone https://github.com/TutteInstitute/toponymy
32
+ cd toponymy
33
+ pip install .
34
+
35
+ -----------
36
+ Basic Usage
37
+ -----------
38
+
39
+ We will need documents, document vectors and a low dimensional representation of these document vector to construct
40
+ a representation. This can be very expensive without a GPU so we recommend storing and reloading these vectors as
41
+ needed. For ease of experimentation we have precomputed and stored such vectors for the `20-Newsgroups dataset <http://qwone.com/~jason/20Newsgroups/>`_
42
+ on hugging face. Code to retrieve these vectors is below.
43
+
44
+ .. code-block:: python
45
+
46
+ pip install pandas
47
+
48
+ import numpy as np
49
+ import pandas as pd
50
+ newsgroups_df = pd.read_parquet("hf://datasets/lmcinnes/20newsgroups_embedded/data/train-00000-of-00001.parquet")
51
+ text = newsgroups_df["post"].str.strip().values
52
+ document_vectors = np.stack(newsgroups_df["embedding"].values)
53
+ document_map = np.stack(newsgroups_df["map"].values)
54
+
55
+ Toponymy also requires an embedding model for determining which of the documents will be most relevant to each
56
+ of our clusters. This doesn't have to be the embedding model that our documents were embedded with but it
57
+ should be similar.
58
+
59
+ .. code-block:: python
60
+
61
+ pip install sentence_transformers
62
+
63
+ from sentence_transformers import SentenceTransformer
64
+ embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
65
+
66
+
67
+ Once the low-dimensional representation is available (``document_map`` in this case), we can do the topic naming.
68
+ Toponymy will make use of a clusterer (such as ``ToponymyClusterer``) to create a balanced hierarchical layered
69
+ clustering of our documents. It will then use a variety of sampling and summarization techniques to construct prompts
70
+ describing each cluster to pass to a large language model (LLM). If you would like to experiment with testing
71
+ various cluster parameters in order construct cluster layers appropriate to your data feel free to cluster
72
+ your data ahead of time via:
73
+
74
+ .. code-block:: python
75
+
76
+ from toponymy import ToponymyClusterer
77
+ clusterer = ToponymyClusterer(min_clusters=4)
78
+ clusterer.fit(clusterable_vectors=document_map, embedding_vectors=document_vectors)
79
+ for i, layer in enumerate(clusterer.cluster_layers_):
80
+ print(f'{len(np.unique(layer.cluster_labels))-1} clusters in layer {i}')
81
+
82
+ 428 clusters in layer 0
83
+ 136 clusters in layer 1
84
+ 42 clusters in layer 2
85
+ 14 clusters in layer 3
86
+ 5 clusters in layer 4
87
+
88
+ Toponymy supports multiple LLMs, including Cohere, OpenAI, and Anthropic via service calls, and local models via
89
+ Huggingface and LlamaCpp. Here we show an example using OpenAI. The following code will generate a topic naming
90
+ for the documents in the data set using an ``embedding_model``, ``document_vectors`` and ``document_map`` created above.
91
+
92
+ .. code-block:: python
93
+
94
+ from toponymy import Toponymy, KeyphraseBuilder
95
+ from toponymy.llm_wrappers import OpenAI
96
+
97
+ openai_api_key = open("openai_key.txt").read().strip()
98
+ llm = OpenAI('openai_api_key')
99
+
100
+ topic_model = Toponymy(
101
+ llm=llm,
102
+ embedding_model=embedding_model,
103
+ clusterer=clusterer,
104
+ object_description="newsgroup posts",
105
+ corpus_description="20-newsgroups dataset",
106
+ exemplar_delimiters=["<EXAMPLE_POST>\n","\n</EXAMPLE_POST>\n\n"],
107
+ )
108
+ topic_model.fit(text, document_vectors, document_map)
109
+
110
+ topic_names = topic_model.topic_names_
111
+ topics_per_document = topic_model.cluster_layers_
112
+
113
+ ``topic_names`` is a list of lists which can be used to explore the unique topic names in each layer or resolution.
114
+ Let's examine the last two layers of topics.
115
+
116
+ .. code-block:: python
117
+
118
+ topic_names[-2:]
119
+
120
+ [['NHL Playoffs and Player Analysis',
121
+ 'Major League Baseball Analysis',
122
+ 'Space Exploration and Technology Innovations',
123
+ 'Encryption Policy and Government Surveillance',
124
+ 'Health and Alternative Treatments',
125
+ 'Israeli-Palestinian and Lebanese Conflicts',
126
+ 'Automotive Performance and Safety',
127
+ 'Christian Theology and Debates',
128
+ 'Waco Siege and Government Accountability',
129
+ 'Debates on Morality and Free Speech',
130
+ 'Gun Rights and Legislation',
131
+ 'X Window System and Graphics Software',
132
+ 'Hard Drive Technologies and Troubleshooting',
133
+ 'Vintage Computer Hardware and Upgrades'],
134
+ ['Sports Analysis',
135
+ 'Religion and Government Accountability',
136
+ 'Automotive Performance and Safety',
137
+ 'X Window System and Graphics Software',
138
+ 'Computer Hardware']]
139
+
140
+
141
+ ``topics_per_document`` contains topic labels for each document, with one list for each level of resultion in our
142
+ cluster layers. In our above case this will be a list of 5 layers each containing a list of 18,170 topic names.
143
+ Documents that aren't contained within a cluster at a given layer are given the topic ``Unlabelled``.
144
+
145
+ .. code-block:: python
146
+
147
+ topics_per_document
148
+
149
+ [array(['Unlabelled',
150
+ 'Discussion on VESA Local Bus Video Cards and Performance',
151
+ 'Unlabelled', ...,
152
+ 'Cooling Solutions and Components for CPUs and Power Supplies',
153
+ 'Algorithms for Finding Sphere from Four Points in 3D',
154
+ 'Automotive Discussions on Performance Cars and Specifications'], dtype=object),
155
+ array(['NHL Playoff Analysis and Predictions',
156
+ 'Graphics Card Performance and Benchmark Discussions',
157
+ 'Armenian Genocide and Turkish Atrocities Discourse', ...,
158
+ 'Cooling Solutions and Components for CPUs and Power Supplies',
159
+ 'Algorithms for 3D Polygon Processing and Geometry',
160
+ 'Discussions on SUVs and Performance Cars'], dtype=object),
161
+ array(['NHL Playoff Analysis and Predictions',
162
+ 'Video Card Drivers and Performance',
163
+ 'Armenian Genocide and Turkish Atrocities', ..., 'Unlabelled',
164
+ 'Unlabelled', 'Automotive Performance and Used Cars'], dtype=object),
165
+ array(['NHL Playoffs and Player Analysis',
166
+ 'Vintage Computer Hardware and Upgrades', 'Unlabelled', ...,
167
+ 'Unlabelled', 'X Window System and Graphics Software',
168
+ 'Automotive Performance and Safety'], dtype=object),
169
+ array(['Sports Analysis', 'Computer Hardware', 'Unlabelled', ...,
170
+ 'Unlabelled', 'X Window System and Graphics Software',
171
+ 'Automotive Performance and Safety'], dtype=object)]
172
+
173
+ At this point we recommend that you explore your data and topic names with an interactive visualization library.
174
+ Our `DataMapPlot <https://github.com/TutteInstitute/datamapplot>`_ library is particularly well suited to exploring
175
+ data maps along with layers of topic names. It takes requires our ``document_map``, ``document_vectors`` and newly created ``topics_per_document``.
176
+
177
+ -------------------
178
+ Vector Construction
179
+ -------------------
180
+
181
+ If you do not have ready made document vectors and low dimensional representations of your data you will need to compute
182
+ your own. For faster encoding change device to: "cuda", "mps", "npu" or "cpu" depending on hardware availability. Alternatively,
183
+ one could make use of an API call to embedding service. Embedding wrappers can be found in:
184
+
185
+ .. code-block:: python
186
+
187
+ from toponymy.embedding_wrappers import OpenAIEmbedder
188
+
189
+ or the embedding wrapper of your choice. Once we generate document vectors we will need to construct a low dimensional representation.
190
+ Here we do that via our UMAP library.
191
+
192
+ .. code-block:: python
193
+
194
+ pip install umap-learn
195
+ pip install pandas
196
+ pip install sentence_transformers
197
+
198
+ import pandas as pd
199
+ from sentence_transformers import SentenceTransformer
200
+ import umap
201
+
202
+ newsgroups_df = pd.read_parquet("hf://datasets/lmcinnes/20newsgroups_embedded/data/train-00000-of-00001.parquet")
203
+ text = newsgroups_df["post"].str.strip().values
204
+ embedding_model = SentenceTransformer("all-MiniLM-L6-v2", device="cpu")
205
+
206
+ document_vectors = embedding_model.encode(text, show_progress_bar=True)
207
+ document_map = umap.UMAP(metric='cosine').fit_transform(document_vectors)
208
+
209
+ -------
210
+ License
211
+ -------
212
+
213
+ Toponymy is MIT licensed. See the LICENSE file for details.
214
+
215
+ ------------
216
+ Contributing
217
+ ------------
218
+
219
+ Contributions are more than welcome! If you have ideas for features of projects please get in touch. Everything from
220
+ code to notebooks to examples and documentation are all *equally valuable* so please don't feel you can't contribute.
221
+ To contribute please `fork the project <https://github.com/TutteInstitute/toponymy/fork>`_ make your
222
+ changes and submit a pull request. We will do our best to work through any issues with you and get your code merged in.
@@ -0,0 +1,56 @@
1
+ [metadata]
2
+ name = toponymy
3
+ version = 0.2.0
4
+ author = John Healy, Leland McInnes
5
+ author_email = jchealy@gmail.com, leland.mcinnes@gmail.com
6
+ maintainer = John Healy, Leland McInnes
7
+ maintainer_email = jchealy@gmail.com, leland.mcinnes@gmail.com
8
+ description = A library for using large language models to name topics
9
+ long_description = file: README.rst
10
+ keywords = topic modeing, representation, cluster, clustering, large language models, LLM, topic naming
11
+ url = https://github.com/TutteInstitute/toponymy
12
+ license = MIT License
13
+ license_files = LICENSE
14
+ classifiers =
15
+ License :: OSI Approved :: MIT License
16
+ Programming Language :: Python :: 3.9
17
+ Programming Language :: Python :: 3.10
18
+ Development Status :: 4 - Beta
19
+ Operating System :: OS Independent
20
+
21
+ [options]
22
+ zip_safe = False
23
+ packages = toponymy
24
+ python_requires = >=3.9
25
+ install_requires =
26
+ numpy>=1.21
27
+ pandas>=1.0
28
+ numba>=0.56
29
+ datasets
30
+ scikit-learn>=1.6
31
+ vectorizers
32
+ scipy
33
+ fast_hdbscan>=0.2.2
34
+ sentence_transformers
35
+ dataclasses
36
+ tqdm
37
+ tenacity
38
+
39
+ [options.extras_require]
40
+ dev =
41
+ black
42
+ isort
43
+ pylint
44
+ pytest
45
+ anthropic
46
+ cohere
47
+ azure-ai-inference
48
+ llama-cpp-python
49
+ openai
50
+ transformers
51
+ bm25s
52
+
53
+ [egg_info]
54
+ tag_build =
55
+ tag_date = 0
56
+
@@ -0,0 +1,4 @@
1
+ from setuptools import setup
2
+
3
+ if __name__ == '__main__':
4
+ setup()
@@ -0,0 +1,11 @@
1
+ from .toponymy import Toponymy
2
+ from .clustering import ToponymyClusterer
3
+ from .keyphrases import KeyphraseBuilder
4
+ from .cluster_layer import ClusterLayerText
5
+
6
+ __all__ = [
7
+ "Toponymy",
8
+ "ToponymyClusterer",
9
+ "KeyphraseBuilder",
10
+ "ClusterLayerText",
11
+ ]