sporc 0.1.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.
- sporc-0.1.0/LICENSE +21 -0
- sporc-0.1.0/MANIFEST.in +6 -0
- sporc-0.1.0/PKG-INFO +624 -0
- sporc-0.1.0/README.md +566 -0
- sporc-0.1.0/pyproject.toml +184 -0
- sporc-0.1.0/setup.cfg +4 -0
- sporc-0.1.0/setup.py +61 -0
- sporc-0.1.0/sporc/__init__.py +23 -0
- sporc-0.1.0/sporc/cli.py +251 -0
- sporc-0.1.0/sporc/dataset.py +1043 -0
- sporc-0.1.0/sporc/episode.py +393 -0
- sporc-0.1.0/sporc/exceptions.py +33 -0
- sporc-0.1.0/sporc/podcast.py +413 -0
- sporc-0.1.0/sporc/turn.py +164 -0
- sporc-0.1.0/sporc.egg-info/PKG-INFO +624 -0
- sporc-0.1.0/sporc.egg-info/SOURCES.txt +21 -0
- sporc-0.1.0/sporc.egg-info/dependency_links.txt +1 -0
- sporc-0.1.0/sporc.egg-info/entry_points.txt +2 -0
- sporc-0.1.0/sporc.egg-info/requires.txt +22 -0
- sporc-0.1.0/sporc.egg-info/top_level.txt +1 -0
- sporc-0.1.0/tests/test_selective_loading.py +869 -0
- sporc-0.1.0/tests/test_sporc.py +969 -0
- sporc-0.1.0/tests/test_streaming.py +426 -0
sporc-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 SPORC Package Maintainer
|
|
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.
|
sporc-0.1.0/MANIFEST.in
ADDED
sporc-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sporc
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python package for working with the SPORC (Structured Podcast Open Research Corpus) dataset
|
|
5
|
+
Home-page: https://github.com/yourusername/sporc
|
|
6
|
+
Author: SPORC Package Maintainer
|
|
7
|
+
Author-email: David Jurgens <jurgens@umich.edu>
|
|
8
|
+
Maintainer-email: David Jurgens <jurgens@umich.edu>
|
|
9
|
+
License: MIT
|
|
10
|
+
Project-URL: Homepage, https://github.com/davidjurgens/sporc
|
|
11
|
+
Project-URL: Documentation, https://github.com/davidjurgens/sporc/wiki
|
|
12
|
+
Project-URL: Repository, https://github.com/davidjurgens/sporc.git
|
|
13
|
+
Project-URL: Bug Tracker, https://github.com/davidjurgens/sporc/issues
|
|
14
|
+
Project-URL: Source Code, https://github.com/davidjurgens/sporc
|
|
15
|
+
Project-URL: Dataset, https://huggingface.co/datasets/blitt/SPoRC
|
|
16
|
+
Keywords: podcast,dataset,nlp,conversation,speech,transcript,huggingface
|
|
17
|
+
Classifier: Development Status :: 4 - Beta
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: Intended Audience :: Developers
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
28
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
30
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
31
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
32
|
+
Requires-Python: >=3.8
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: datasets>=2.0.0
|
|
36
|
+
Requires-Dist: huggingface_hub>=0.16.0
|
|
37
|
+
Requires-Dist: psutil>=5.8.0
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
42
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pre-commit>=2.20.0; extra == "dev"
|
|
46
|
+
Provides-Extra: docs
|
|
47
|
+
Requires-Dist: sphinx>=5.0.0; extra == "docs"
|
|
48
|
+
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
|
|
49
|
+
Requires-Dist: myst-parser>=0.18.0; extra == "docs"
|
|
50
|
+
Provides-Extra: test
|
|
51
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
52
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
53
|
+
Requires-Dist: pytest-mock>=3.8.0; extra == "test"
|
|
54
|
+
Dynamic: author
|
|
55
|
+
Dynamic: home-page
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
Dynamic: requires-python
|
|
58
|
+
|
|
59
|
+
# SPORC: Structured Podcast Open Research Corpus
|
|
60
|
+
|
|
61
|
+
A Python package for working with the [SPORC (Structured Podcast Open Research Corpus)](https://huggingface.co/datasets/blitt/SPoRC) dataset from Hugging Face.
|
|
62
|
+
|
|
63
|
+
## Overview
|
|
64
|
+
|
|
65
|
+
SPORC is a large multimodal dataset for the study of the podcast ecosystem. This package provides easy-to-use Python classes and functions to interact with the dataset, including:
|
|
66
|
+
|
|
67
|
+
- **Podcast** class: Collection of episodes and metadata about a podcast
|
|
68
|
+
- **Episode** class: Single episode with information about its contents
|
|
69
|
+
- Search functionality for podcasts and episodes
|
|
70
|
+
- Conversation turn analysis and filtering
|
|
71
|
+
- Time-based and speaker-based queries
|
|
72
|
+
- **Streaming support** for memory-efficient processing of large datasets
|
|
73
|
+
- **Selective loading** for filtering and loading specific podcast subsets into memory
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
### Prerequisites
|
|
78
|
+
|
|
79
|
+
Before installing this package, you need to:
|
|
80
|
+
|
|
81
|
+
1. **Accept the SPORC dataset terms** on Hugging Face:
|
|
82
|
+
- Visit [https://huggingface.co/datasets/blitt/SPoRC](https://huggingface.co/datasets/blitt/SPoRC)
|
|
83
|
+
- Log in to your Hugging Face account
|
|
84
|
+
- Click "I agree" to accept the dataset terms
|
|
85
|
+
|
|
86
|
+
2. **Set up Hugging Face credentials** on your local machine:
|
|
87
|
+
```bash
|
|
88
|
+
pip install huggingface_hub
|
|
89
|
+
huggingface-cli login
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Install the Package
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install sporc
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or install from source:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone https://github.com/yourusername/sporc.git
|
|
102
|
+
cd sporc
|
|
103
|
+
pip install -e .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Quick Start
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from sporc import SPORCDataset
|
|
110
|
+
|
|
111
|
+
# Initialize the dataset (memory mode - default)
|
|
112
|
+
sporc = SPORCDataset()
|
|
113
|
+
|
|
114
|
+
# Or use streaming mode for memory efficiency
|
|
115
|
+
sporc_streaming = SPORCDataset(streaming=True)
|
|
116
|
+
|
|
117
|
+
# Or use selective mode to load specific podcasts into memory
|
|
118
|
+
sporc_selective = SPORCDataset(streaming=True)
|
|
119
|
+
sporc_selective.load_podcast_subset(categories=['education'])
|
|
120
|
+
|
|
121
|
+
# Search for a specific podcast
|
|
122
|
+
podcast = sporc.search_podcast("SingOut SpeakOut")
|
|
123
|
+
|
|
124
|
+
# Get all episodes for this podcast
|
|
125
|
+
for episode in podcast.episodes:
|
|
126
|
+
print(f"Episode: {episode.title}")
|
|
127
|
+
print(f"Duration: {episode.duration_seconds} seconds")
|
|
128
|
+
print(f"Hosts: {episode.host_names}")
|
|
129
|
+
print("---")
|
|
130
|
+
|
|
131
|
+
# Search for episodes with specific criteria
|
|
132
|
+
episodes = sporc.search_episodes(
|
|
133
|
+
min_duration=300, # At least 5 minutes
|
|
134
|
+
max_speakers=3, # Maximum 3 speakers
|
|
135
|
+
host_name="Simon Shapiro"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Get conversation turns for a specific episode
|
|
139
|
+
episode = episodes[0]
|
|
140
|
+
turns = episode.get_turns_by_time_range(0, 180) # First 3 minutes
|
|
141
|
+
for turn in turns:
|
|
142
|
+
print(f"Speaker: {turn.speaker}")
|
|
143
|
+
print(f"Text: {turn.text[:100]}...")
|
|
144
|
+
print(f"Duration: {turn.duration} seconds")
|
|
145
|
+
print("---")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Memory vs Streaming vs Selective Mode
|
|
149
|
+
|
|
150
|
+
The SPORC package supports three modes for loading the dataset:
|
|
151
|
+
|
|
152
|
+
### Memory Mode (Default)
|
|
153
|
+
```python
|
|
154
|
+
sporc = SPORCDataset() # streaming=False (default)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Advantages:**
|
|
158
|
+
- Fast access to all data
|
|
159
|
+
- Can use `len()` to get dataset size
|
|
160
|
+
- All search operations are instant
|
|
161
|
+
- Can iterate over data multiple times
|
|
162
|
+
- Full dataset statistics available immediately
|
|
163
|
+
|
|
164
|
+
**Disadvantages:**
|
|
165
|
+
- High memory usage (loads entire dataset into RAM)
|
|
166
|
+
- Slower initial loading time
|
|
167
|
+
- May not work on systems with limited memory
|
|
168
|
+
|
|
169
|
+
### Streaming Mode
|
|
170
|
+
```python
|
|
171
|
+
sporc = SPORCDataset(streaming=True)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Advantages:**
|
|
175
|
+
- Low memory usage (loads data on-demand)
|
|
176
|
+
- Fast initial loading
|
|
177
|
+
- Works on systems with limited memory
|
|
178
|
+
- Can process datasets larger than available RAM
|
|
179
|
+
|
|
180
|
+
**Disadvantages:**
|
|
181
|
+
- Slower access to individual items
|
|
182
|
+
- Cannot use `len()` (raises RuntimeError)
|
|
183
|
+
- Search operations require iterating through data
|
|
184
|
+
- Cannot iterate over data multiple times without reloading
|
|
185
|
+
- Statistics calculation requires full iteration
|
|
186
|
+
|
|
187
|
+
### Selective Mode
|
|
188
|
+
```python
|
|
189
|
+
sporc = SPORCDataset(streaming=True)
|
|
190
|
+
sporc.load_podcast_subset(categories=['education'])
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Advantages:**
|
|
194
|
+
- Memory efficient (only loads selected subset)
|
|
195
|
+
- O(1) access to selected podcasts and episodes
|
|
196
|
+
- Fast search operations on the subset
|
|
197
|
+
- Can iterate over data multiple times
|
|
198
|
+
- Statistics available immediately for the subset
|
|
199
|
+
- Best of both worlds: memory efficiency + fast access
|
|
200
|
+
|
|
201
|
+
**Disadvantages:**
|
|
202
|
+
- Initial filtering requires O(n) iteration
|
|
203
|
+
- Cannot access podcasts outside the selected subset
|
|
204
|
+
- Requires knowing filtering criteria in advance
|
|
205
|
+
|
|
206
|
+
### When to Use Each Mode
|
|
207
|
+
|
|
208
|
+
**Use Memory Mode when:**
|
|
209
|
+
- You have sufficient RAM (8GB+ recommended)
|
|
210
|
+
- You need fast access to multiple episodes
|
|
211
|
+
- You want to perform complex searches frequently
|
|
212
|
+
- You need to iterate over data multiple times
|
|
213
|
+
- You're working with smaller subsets of the dataset
|
|
214
|
+
|
|
215
|
+
**Use Streaming Mode when:**
|
|
216
|
+
- You have limited RAM (< 8GB)
|
|
217
|
+
- You're processing the entire dataset sequentially
|
|
218
|
+
- You only need to access a few episodes
|
|
219
|
+
- You're doing one-pass analysis
|
|
220
|
+
- You're working on systems with memory constraints
|
|
221
|
+
|
|
222
|
+
**Use Selective Mode when:**
|
|
223
|
+
- You want to work with a specific genre, host, or category
|
|
224
|
+
- You have limited RAM but need fast access to a subset
|
|
225
|
+
- You want to perform frequent searches on a filtered dataset
|
|
226
|
+
- You know your filtering criteria in advance
|
|
227
|
+
- You want the best balance of memory efficiency and performance
|
|
228
|
+
|
|
229
|
+
### Selective Mode Examples
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
# Initialize streaming mode
|
|
233
|
+
sporc = SPORCDataset(streaming=True)
|
|
234
|
+
|
|
235
|
+
# Load only education podcasts
|
|
236
|
+
sporc.load_podcast_subset(categories=['education'])
|
|
237
|
+
print(f"Loaded {len(sporc)} episodes from education podcasts")
|
|
238
|
+
|
|
239
|
+
# Now you have O(1) access to education podcasts
|
|
240
|
+
education_podcasts = sporc.get_all_podcasts()
|
|
241
|
+
for podcast in education_podcasts:
|
|
242
|
+
print(f"Education podcast: {podcast.title}")
|
|
243
|
+
|
|
244
|
+
# Fast search within the subset
|
|
245
|
+
long_education_episodes = sporc.search_episodes(min_duration=1800) # 30+ minutes
|
|
246
|
+
print(f"Found {len(long_education_episodes)} long education episodes")
|
|
247
|
+
|
|
248
|
+
# Load podcasts by specific hosts
|
|
249
|
+
sporc = SPORCDataset(streaming=True)
|
|
250
|
+
sporc.load_podcast_subset(hosts=['Simon Shapiro', 'John Doe'])
|
|
251
|
+
print(f"Loaded {len(sporc)} episodes from selected hosts")
|
|
252
|
+
|
|
253
|
+
# Load podcasts with at least 10 episodes
|
|
254
|
+
sporc = SPORCDataset(streaming=True)
|
|
255
|
+
sporc.load_podcast_subset(min_episodes=10)
|
|
256
|
+
print(f"Loaded {len(sporc)} episodes from podcasts with 10+ episodes")
|
|
257
|
+
|
|
258
|
+
# Load English podcasts with at least 5 hours of content
|
|
259
|
+
sporc = SPORCDataset(streaming=True)
|
|
260
|
+
sporc.load_podcast_subset(language='en', min_total_duration=5.0)
|
|
261
|
+
print(f"Loaded {len(sporc)} episodes from substantial English podcasts")
|
|
262
|
+
|
|
263
|
+
# Complex filtering
|
|
264
|
+
sporc = SPORCDataset(streaming=True)
|
|
265
|
+
sporc.load_podcast_subset(
|
|
266
|
+
categories=['education', 'science'],
|
|
267
|
+
min_episodes=5,
|
|
268
|
+
min_total_duration=2.0, # 2+ hours
|
|
269
|
+
language='en'
|
|
270
|
+
)
|
|
271
|
+
print(f"Loaded {len(sporc)} episodes from substantial English education/science podcasts")
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Core Classes
|
|
275
|
+
|
|
276
|
+
### SPORCDataset
|
|
277
|
+
|
|
278
|
+
The main class for interacting with the SPORC dataset.
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from sporc import SPORCDataset
|
|
282
|
+
|
|
283
|
+
# Memory mode
|
|
284
|
+
sporc = SPORCDataset()
|
|
285
|
+
|
|
286
|
+
# Streaming mode
|
|
287
|
+
sporc = SPORCDataset(streaming=True)
|
|
288
|
+
|
|
289
|
+
# Selective mode
|
|
290
|
+
sporc = SPORCDataset(streaming=True)
|
|
291
|
+
sporc.load_podcast_subset(categories=['education'])
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Methods:**
|
|
295
|
+
- `search_podcast(name: str) -> Podcast`: Find a podcast by name
|
|
296
|
+
- `search_episodes(**criteria) -> List[Episode]`: Search episodes by various criteria
|
|
297
|
+
- `get_all_podcasts() -> List[Podcast]`: Get all podcasts in the dataset
|
|
298
|
+
- `get_all_episodes() -> List[Episode]`: Get all episodes in the dataset
|
|
299
|
+
- `iterate_episodes() -> Iterator[Episode]`: Iterate over episodes (streaming only)
|
|
300
|
+
- `iterate_podcasts() -> Iterator[Podcast]`: Iterate over podcasts (streaming only)
|
|
301
|
+
- `load_podcast_subset(**criteria) -> None`: Load filtered subset into memory (streaming only)
|
|
302
|
+
- `get_dataset_statistics() -> Dict[str, Any]`: Get dataset statistics
|
|
303
|
+
|
|
304
|
+
### Podcast
|
|
305
|
+
|
|
306
|
+
Represents a podcast with its episodes and metadata.
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
podcast = sporc.search_podcast("Example Podcast")
|
|
310
|
+
print(f"Title: {podcast.title}")
|
|
311
|
+
print(f"Description: {podcast.description}")
|
|
312
|
+
print(f"Category: {podcast.category}")
|
|
313
|
+
print(f"Number of episodes: {len(podcast.episodes)}")
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Properties:**
|
|
317
|
+
- `title`: Podcast title
|
|
318
|
+
- `description`: Podcast description
|
|
319
|
+
- `category`: Primary category
|
|
320
|
+
- `episodes`: List of Episode objects
|
|
321
|
+
- `host_names`: List of predicted host names
|
|
322
|
+
|
|
323
|
+
### Episode
|
|
324
|
+
|
|
325
|
+
Represents a single podcast episode.
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
episode = podcast.episodes[0]
|
|
329
|
+
print(f"Title: {episode.title}")
|
|
330
|
+
print(f"Duration: {episode.duration_seconds} seconds")
|
|
331
|
+
print(f"Hosts: {episode.host_names}")
|
|
332
|
+
print(f"Guests: {episode.guest_names}")
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Methods:**
|
|
336
|
+
- `get_turns_by_time_range(start_time: float, end_time: float) -> List[Turn]`
|
|
337
|
+
- `get_turns_by_speaker(speaker_name: str) -> List[Turn]`
|
|
338
|
+
- `get_turns_by_min_length(min_length: int) -> List[Turn]`
|
|
339
|
+
- `get_all_turns() -> List[Turn]`
|
|
340
|
+
|
|
341
|
+
**Properties:**
|
|
342
|
+
- `title`: Episode title
|
|
343
|
+
- `description`: Episode description
|
|
344
|
+
- `duration_seconds`: Episode duration in seconds
|
|
345
|
+
- `host_names`: List of predicted host names
|
|
346
|
+
- `guest_names`: List of predicted guest names
|
|
347
|
+
- `main_speakers`: List of main speaker labels
|
|
348
|
+
- `transcript`: Full episode transcript
|
|
349
|
+
|
|
350
|
+
### Turn
|
|
351
|
+
|
|
352
|
+
Represents a single conversation turn in an episode.
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
turn = episode.get_all_turns()[0]
|
|
356
|
+
print(f"Speaker: {turn.speaker}")
|
|
357
|
+
print(f"Text: {turn.text}")
|
|
358
|
+
print(f"Start time: {turn.start_time} seconds")
|
|
359
|
+
print(f"End time: {turn.end_time} seconds")
|
|
360
|
+
print(f"Duration: {turn.duration} seconds")
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Properties:**
|
|
364
|
+
- `speaker`: Speaker label (e.g., "SPEAKER_00")
|
|
365
|
+
- `text`: Spoken text
|
|
366
|
+
- `start_time`: Turn start time in seconds
|
|
367
|
+
- `end_time`: Turn end time in seconds
|
|
368
|
+
- `duration`: Turn duration in seconds
|
|
369
|
+
- `inferred_role`: Inferred speaker role (host, guest, etc.)
|
|
370
|
+
- `inferred_name`: Inferred speaker name
|
|
371
|
+
|
|
372
|
+
## Search Examples
|
|
373
|
+
|
|
374
|
+
### Search by Podcast Name
|
|
375
|
+
```python
|
|
376
|
+
podcast = sporc.search_podcast("Brazen Education")
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Search Episodes by Duration
|
|
380
|
+
```python
|
|
381
|
+
# Episodes longer than 10 minutes
|
|
382
|
+
long_episodes = sporc.search_episodes(min_duration=600)
|
|
383
|
+
|
|
384
|
+
# Episodes between 5-15 minutes
|
|
385
|
+
medium_episodes = sporc.search_episodes(min_duration=300, max_duration=900)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Search Episodes by Speaker Count
|
|
389
|
+
```python
|
|
390
|
+
# Episodes with exactly 2 speakers
|
|
391
|
+
two_speaker_episodes = sporc.search_episodes(min_speakers=2, max_speakers=2)
|
|
392
|
+
|
|
393
|
+
# Episodes with 3 or more speakers
|
|
394
|
+
multi_speaker_episodes = sporc.search_episodes(min_speakers=3)
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Search Episodes by Host
|
|
398
|
+
```python
|
|
399
|
+
# Episodes hosted by Simon Shapiro
|
|
400
|
+
simon_episodes = sporc.search_episodes(host_name="Simon Shapiro")
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Search Episodes by Category
|
|
404
|
+
```python
|
|
405
|
+
# Education podcasts
|
|
406
|
+
education_episodes = sporc.search_episodes(category="education")
|
|
407
|
+
|
|
408
|
+
# Music podcasts
|
|
409
|
+
music_episodes = sporc.search_episodes(category="music")
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Selective Loading Examples
|
|
413
|
+
|
|
414
|
+
### Load by Category
|
|
415
|
+
```python
|
|
416
|
+
# Load only education podcasts
|
|
417
|
+
sporc = SPORCDataset(streaming=True)
|
|
418
|
+
sporc.load_podcast_subset(categories=['education'])
|
|
419
|
+
|
|
420
|
+
# Now fast access to education content
|
|
421
|
+
education_podcasts = sporc.get_all_podcasts()
|
|
422
|
+
long_education_episodes = sporc.search_episodes(min_duration=1800)
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Load by Host
|
|
426
|
+
```python
|
|
427
|
+
# Load podcasts by specific hosts
|
|
428
|
+
sporc = SPORCDataset(streaming=True)
|
|
429
|
+
sporc.load_podcast_subset(hosts=['Simon Shapiro', 'John Doe'])
|
|
430
|
+
|
|
431
|
+
# Fast access to episodes from these hosts
|
|
432
|
+
host_episodes = sporc.get_all_episodes()
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Load by Episode Count
|
|
436
|
+
```python
|
|
437
|
+
# Load podcasts with substantial episode counts
|
|
438
|
+
sporc = SPORCDataset(streaming=True)
|
|
439
|
+
sporc.load_podcast_subset(min_episodes=10)
|
|
440
|
+
|
|
441
|
+
# Work with established podcasts
|
|
442
|
+
established_podcasts = sporc.get_all_podcasts()
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Load by Duration
|
|
446
|
+
```python
|
|
447
|
+
# Load podcasts with substantial content
|
|
448
|
+
sporc = SPORCDataset(streaming=True)
|
|
449
|
+
sporc.load_podcast_subset(min_total_duration=5.0) # 5+ hours
|
|
450
|
+
|
|
451
|
+
# Work with substantial podcasts
|
|
452
|
+
substantial_podcasts = sporc.get_all_podcasts()
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Complex Filtering
|
|
456
|
+
```python
|
|
457
|
+
# Load substantial English education/science podcasts
|
|
458
|
+
sporc = SPORCDataset(streaming=True)
|
|
459
|
+
sporc.load_podcast_subset(
|
|
460
|
+
categories=['education', 'science'],
|
|
461
|
+
min_episodes=5,
|
|
462
|
+
min_total_duration=2.0,
|
|
463
|
+
language='en'
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
# Now you have fast access to a curated subset
|
|
467
|
+
curated_episodes = sporc.get_all_episodes()
|
|
468
|
+
curated_podcasts = sporc.get_all_podcasts()
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## Conversation Turn Analysis
|
|
472
|
+
|
|
473
|
+
### Get Turns by Time Range
|
|
474
|
+
```python
|
|
475
|
+
# First 5 minutes of an episode
|
|
476
|
+
early_turns = episode.get_turns_by_time_range(0, 300)
|
|
477
|
+
|
|
478
|
+
# Last 10 minutes of an episode
|
|
479
|
+
late_turns = episode.get_turns_by_time_range(
|
|
480
|
+
episode.duration_seconds - 600,
|
|
481
|
+
episode.duration_seconds
|
|
482
|
+
)
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Get Turns by Speaker
|
|
486
|
+
```python
|
|
487
|
+
# All turns by the host
|
|
488
|
+
host_turns = episode.get_turns_by_speaker("SPEAKER_00")
|
|
489
|
+
|
|
490
|
+
# All turns by a specific guest
|
|
491
|
+
guest_turns = episode.get_turns_by_speaker("SPEAKER_01")
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Get Turns by Length
|
|
495
|
+
```python
|
|
496
|
+
# Turns longer than 30 seconds
|
|
497
|
+
long_turns = episode.get_turns_by_min_length(30)
|
|
498
|
+
|
|
499
|
+
# Turns longer than 2 minutes
|
|
500
|
+
very_long_turns = episode.get_turns_by_min_length(120)
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
## Data Quality Indicators
|
|
504
|
+
|
|
505
|
+
The SPORC dataset includes several quality indicators that can help you filter data:
|
|
506
|
+
|
|
507
|
+
```python
|
|
508
|
+
episode = podcast.episodes[0]
|
|
509
|
+
|
|
510
|
+
# Diarization quality indicators
|
|
511
|
+
print(f"Overlap proportion (duration): {episode.overlap_prop_duration}")
|
|
512
|
+
print(f"Overlap proportion (turn count): {episode.overlap_prop_turn_count}")
|
|
513
|
+
print(f"Average turn duration: {episode.avg_turn_duration}")
|
|
514
|
+
print(f"Total speaker labels: {episode.total_speaker_labels}")
|
|
515
|
+
|
|
516
|
+
# Filter episodes with good diarization quality
|
|
517
|
+
good_quality_episodes = sporc.search_episodes(
|
|
518
|
+
max_overlap_prop_duration=0.1, # Less than 10% overlap
|
|
519
|
+
max_overlap_prop_turn_count=0.2 # Less than 20% overlapping turns
|
|
520
|
+
)
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
## Performance Considerations
|
|
524
|
+
|
|
525
|
+
### Memory Usage
|
|
526
|
+
|
|
527
|
+
**Memory Mode:**
|
|
528
|
+
- Initial memory usage: ~2-4GB (depending on dataset size)
|
|
529
|
+
- Memory usage remains constant during processing
|
|
530
|
+
- Fast access to all data
|
|
531
|
+
|
|
532
|
+
**Streaming Mode:**
|
|
533
|
+
- Initial memory usage: ~50-100MB
|
|
534
|
+
- Memory usage varies during processing (typically 100-500MB per episode)
|
|
535
|
+
- Memory is freed after processing each episode
|
|
536
|
+
|
|
537
|
+
**Selective Mode:**
|
|
538
|
+
- Initial memory usage: ~50-100MB
|
|
539
|
+
- Memory usage after loading: ~100MB-2GB (depending on subset size)
|
|
540
|
+
- Memory usage remains constant during processing
|
|
541
|
+
- Fast access to selected subset
|
|
542
|
+
|
|
543
|
+
### Processing Speed
|
|
544
|
+
|
|
545
|
+
**Memory Mode:**
|
|
546
|
+
- Fast search operations (O(1) for indexed data)
|
|
547
|
+
- Instant access to any episode
|
|
548
|
+
- Slower initial loading
|
|
549
|
+
|
|
550
|
+
**Streaming Mode:**
|
|
551
|
+
- Slower search operations (O(n) - must iterate through data)
|
|
552
|
+
- Slower access to individual episodes
|
|
553
|
+
- Fast initial loading
|
|
554
|
+
|
|
555
|
+
**Selective Mode:**
|
|
556
|
+
- Initial filtering: O(n) (one-time cost)
|
|
557
|
+
- Fast search operations on subset (O(1) for indexed data)
|
|
558
|
+
- Fast access to selected episodes
|
|
559
|
+
- Fast initial loading
|
|
560
|
+
|
|
561
|
+
### Recommended System Requirements
|
|
562
|
+
|
|
563
|
+
**Memory Mode:**
|
|
564
|
+
- RAM: 8GB+ recommended
|
|
565
|
+
- Storage: 10GB+ for dataset cache
|
|
566
|
+
- CPU: Any modern processor
|
|
567
|
+
|
|
568
|
+
**Streaming Mode:**
|
|
569
|
+
- RAM: 4GB+ minimum, 8GB+ recommended
|
|
570
|
+
- Storage: 10GB+ for dataset cache
|
|
571
|
+
- CPU: Any modern processor
|
|
572
|
+
|
|
573
|
+
**Selective Mode:**
|
|
574
|
+
- RAM: 4GB+ minimum, 8GB+ recommended
|
|
575
|
+
- Storage: 10GB+ for dataset cache
|
|
576
|
+
- CPU: Any modern processor
|
|
577
|
+
|
|
578
|
+
## Error Handling
|
|
579
|
+
|
|
580
|
+
The package includes comprehensive error handling for common issues:
|
|
581
|
+
|
|
582
|
+
```python
|
|
583
|
+
from sporc import SPORCDataset, SPORCError
|
|
584
|
+
|
|
585
|
+
try:
|
|
586
|
+
sporc = SPORCDataset()
|
|
587
|
+
podcast = sporc.search_podcast("Nonexistent Podcast")
|
|
588
|
+
except SPORCError as e:
|
|
589
|
+
print(f"Error: {e}")
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Contributing
|
|
593
|
+
|
|
594
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
595
|
+
|
|
596
|
+
## License
|
|
597
|
+
|
|
598
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
599
|
+
|
|
600
|
+
## Citation
|
|
601
|
+
|
|
602
|
+
If you use this package in your research, please cite the original SPORC paper:
|
|
603
|
+
|
|
604
|
+
```bibtex
|
|
605
|
+
@article{blitt2025sporc,
|
|
606
|
+
title={SPORC: the Structured Podcast Open Research Corpus},
|
|
607
|
+
author={Litterer, Ben and Jurgens, David and Card, Dallas},
|
|
608
|
+
booktitle={Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics},
|
|
609
|
+
year={2025}
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
## Support
|
|
614
|
+
|
|
615
|
+
For questions, issues, or feature requests, please:
|
|
616
|
+
|
|
617
|
+
1. Check the [documentation](https://github.com/yourusername/sporc/wiki)
|
|
618
|
+
2. Search existing [issues](https://github.com/yourusername/sporc/issues)
|
|
619
|
+
3. Create a new issue if your problem isn't already addressed
|
|
620
|
+
|
|
621
|
+
## Acknowledgments
|
|
622
|
+
|
|
623
|
+
- Hugging Face for hosting the dataset
|
|
624
|
+
- The open-source community for the tools that made this package possible
|