Searching in podcast collection

using SimilaritySearch, SimSearchManifoldLearning, TextSearch, CodecZlib, JSON, DataFrames, Plots, StatsBase, DataFrames, Clustering, Markdown, Latexify
using Downloads: download

This example is about searching in a caption/subtitle collection, i.e., looking for passages in audiobooks, youtube videos, conferences, podcasts, etc. The audio should be translated with a speech to text model, i.e., Whisper of OpenAI.

Having a WebVTT set of files we need to load the corpus. The files we are using as dataset are WebVTT subtitles, which can be readed with the following code, note that this code is not part of the example and can be ignored.

mutable struct EntryVTT
    type::Symbol
    name::String
    tbegin::String
    tend::String
    data::Vector{String}
end

function webvtt!(filename, idfile, D)
    L = []
    B = nothing

    open(filename) do f
        lineno = 0
        while !eof(f)
            line = readline(f)
            lineno += 1
            if line == "WEBVTT"
                B = EntryVTT(:WEBVTT, "", "", "", String[])
                push!(L, B)
                continue
            end

            n = length(line)
            if n == 0 # flush
                if B.type === :caption
                    for caption in B.data
                        push!(D, (; idfile, B.name, B.tbegin, B.tend, caption))
                    end
                end
                B = nothing
                continue
            end

            if B === nothing
                m = match(r"^NOTE (.*)", line)
                if m !== nothing
                    B = EntryVTT(:NOTE, "", "", "", String[])
                    push!(L, B)
                    if length(m.captures[1]) > 0
                        push!(B.data, m.captures[1])
                    end

                    continue
                end

                if "REGION" == line
                    B = EntryVTT(:REGION, "", "", "", String[])
                    push!(L, B)
                    continue
                end

                if occursin("-->", line)
                    tbegin, tend = split(line)[[1, 3]]
                    B = EntryVTT(:caption, "", tbegin, tend, String[])
                    continue
                end

                B = EntryVTT(:caption, line, "", "", String[])
                push!(L, B)
            else
                if occursin("-->", line)
                    B.tbegin, B.tend = split(line)[[1, 3]]
                    continue
                end
                push!(B.data, line) # appends to the last
            end
        end
    end

    B !== nothing && push!(L, B)
    L, D
end

Now, we load the dataset

podcasts = sort!(readdir("/home/sadit/sites/SimilaritySearchDemos/podcast-vtt/", join=true))

D = DataFrame(idfile=String[], name=String[], tbegin=String[], tend=String[], caption=String[])

for filename in podcasts
    webvtt!(filename, basename(filename), D)
end

D
21013×5 DataFrame
20988 rows omitted
Row idfile name tbegin tend caption
String String String String String
1 tres-patines-y-la-tremenda-corte_0000.vtt 00:00.000 00:11.000 Audiencia pública, el tremendo juez de la tremenda corte va a resolver un tremendo caso.
2 tres-patines-y-la-tremenda-corte_0000.vtt 00:11.000 00:13.000 Buenas noches, secretario.
3 tres-patines-y-la-tremenda-corte_0000.vtt 00:15.000 00:18.000 Buenas noches, señor juez. ¿Cómo se siente hoy?
4 tres-patines-y-la-tremenda-corte_0000.vtt 00:18.000 00:25.000 Campana. Hoy me siento panetela. De manera que vamos a ver si acabamos pronto que esta noche me voy de rumba.
5 tres-patines-y-la-tremenda-corte_0000.vtt 00:25.000 00:27.000 No me digas. ¿Se va usted de rumba?
6 tres-patines-y-la-tremenda-corte_0000.vtt 00:27.000 00:30.000 Sí, tengo un carrito ahí que es algo serio.
7 tres-patines-y-la-tremenda-corte_0000.vtt 00:30.000 00:32.000 Ah, oígame. ¿Jóven?
8 tres-patines-y-la-tremenda-corte_0000.vtt 00:32.000 00:36.000 Un pollito. No tiene más que 46 años.
9 tres-patines-y-la-tremenda-corte_0000.vtt 00:36.000 00:40.000 ¿Y una mujer de 46 años le llama a usted pollito todavía?
10 tres-patines-y-la-tremenda-corte_0000.vtt 00:40.000 00:42.000 Claro que sí. ¿Qué número es gallina en la bola?
11 tres-patines-y-la-tremenda-corte_0000.vtt 00:42.000 00:43.000 54.
12 tres-patines-y-la-tremenda-corte_0000.vtt 00:43.000 00:45.000 Entonces hasta los 53 sigue siendo un pollito.
13 tres-patines-y-la-tremenda-corte_0000.vtt 00:45.000 00:47.000 Ah, bueno. ¿Y es bonita?
21002 tres-patines-y-la-tremenda-corte_0050.vtt 16:26.080 16:26.880 ¿Por qué?
21003 tres-patines-y-la-tremenda-corte_0050.vtt 16:26.880 16:28.200 Porque no tuvieron éxito.
21004 tres-patines-y-la-tremenda-corte_0050.vtt 16:28.200 16:29.800 Escriba ahí, secretario.
21005 tres-patines-y-la-tremenda-corte_0050.vtt 16:29.840 16:31.400 Venga la sentencia.
21006 tres-patines-y-la-tremenda-corte_0050.vtt 16:31.400 16:35.040 El tribunal dictamina que ustedes han hecho leña a la finca de
21007 tres-patines-y-la-tremenda-corte_0050.vtt 16:35.040 16:37.440 Nananina perjudicando a su dueña.
21008 tres-patines-y-la-tremenda-corte_0050.vtt 16:37.440 16:40.520 Y por todo ese estropicio que parece obra de locos,
21009 tres-patines-y-la-tremenda-corte_0050.vtt 16:40.520 16:44.040 pagarán 5,000 cocos más las costas de este juicio.
21010 tres-patines-y-la-tremenda-corte_0050.vtt 16:44.040 16:47.720 Escucha el siguiente programa de La Tremenda Corte con Leopoldo
21011 tres-patines-y-la-tremenda-corte_0050.vtt 16:47.720 16:50.920 Fernández, Mimí Cali y Aníbal de Mar por esta emisora.
21012 tres-patines-y-la-tremenda-corte_0050.vtt 16:50.920 16:53.720 Hasta entonces, Manolo Iglesias, que les habla,
21013 tres-patines-y-la-tremenda-corte_0050.vtt 16:53.720 16:56.360 les dice, muy buena suerte, amigos.

Functions create to encode texto into bag-of-word vectors

textconfig = TextConfig(
    group_usr=true,
    group_url=true,
    del_diac=true,
    lc=true,
    group_num=true,
    nlist=[1],
    qlist=[])

# corpus here can be a sample to avoid double parsing
voc = Vocabulary(textconfig, D.caption) 
model = VectorModel(IdfWeighting(), TfWeighting(), voc)
# model = VectorModel(EntropyWeighting(), BinaryLocalWeighting(), voc, D.text, D.klass; smooth=1.0)
#model = VectorModel(IdfWeighting(), TfWeighting(), voc)
model = filter_tokens(model) do t
    t.weight >= 0.05
end

vectors = vectorize_corpus(model, D.caption)

UMAP projections

UMAP projection can take a while, even on multithreading systems. Note that we are creating 2d and 3d projections.

1e2, e3 = let min_dist=0.5f0,
             k=16,
             n_epochs=75,
             neg_sample_rate=3,
             tol=1e-3,
             layout=SpectralLayout(),
             indexsize=2048,
             dist=NormalizedCosineDistance()

    index = ExhaustiveSearch(; db=rand(vectors, indexsize), dist)
    @time U2 = fit(UMAP, index; k, neg_sample_rate, layout, n_epochs, tol, min_dist)
    @time U3 = fit(U2, 3; neg_sample_rate, n_epochs, tol)
    @time e2 = clamp.(predict(U2, vectors), -10f0, 10f0)
    @time e3 = clamp.(predict(U3, vectors), -10f0, 10f0)
    e2, e3
end
1
The UMAP algorithm has a lot of hyperparameters; min_dist controls the distance between projected points, k is the number of neighbors to be used in the underlying \(k\)nn graph, n_epochs the number of epochs used to optimize the projection, neg_sample_rate means for the number of negative examples used in the optimization process, tol the tolerance to converge, layout

Visualizations

function normcolors(V)
    min_, max_ = extrema(V)
    V .= (V .- min_) ./ (max_ - min_)
    V .= clamp.(V, 0, 1)
end

normcolors(@view e3[1, :])
normcolors(@view e3[2, :])
normcolors(@view e3[3, :])

C = [RGB(c[1], c[2], c[3]) for c in eachcol(e3)]

X = @view e2[1, :]
Y = @view e2[2, :]
scatter(X, Y, color=C, fmt=:png, alpha=0.2, size=(600, 600), ma=0.3, ms=2, msw=0, label="")

plot!()
dbscanresult = dbscan(e2, 0.035, min_cluster_size=10);
display(length(dbscanresult.clusters))

plot()
for (i, c) in enumerate(dbscanresult.clusters)
    X = @view e2[1, c.core_indices]
    Y = @view e2[2, c.core_indices]
    scatter!(X, Y, c=:auto, fmt=:png, size=(600, 600), ma=0.3, a=0.3, ms=1, msw=0, label="")
    if rand() < 0.1  # just to show some examples 
        X = c.core_indices
        sampled = ""
        if length(X) > 20
            sampled = "-- showing a small sample"
            X = rand(X, 20)
        end
        display(Markdown.parse("## Cluster $i with $(length(c.core_indices)) elements $sampled"))
        display(latexify(D[X, :], env=:mdtable, latex=false))
    end
end

plot!()
153

Cluster 2 with 93 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0045.vtt 03:30.000 03:32.000 me das pena, pobrecito.
tres-patines-y-la-tremenda-corte_0002.vtt 11:07.000 11:08.000 No me digas, ¿tú eres la sala?
tres-patines-y-la-tremenda-corte_0031.vtt 09:15.000 09:17.000 Me tiraron flores.
tres-patines-y-la-tremenda-corte_0020.vtt 00:27.000 00:28.000 Me peleé.
tres-patines-y-la-tremenda-corte_0042.vtt 04:22.500 04:24.500 No me digas, ¿tú estuviste en París?
tres-patines-y-la-tremenda-corte_0042.vtt 02:55.000 02:57.500 No me digas, empezó a salir un fantasma.
tres-patines-y-la-tremenda-corte_0042.vtt 06:18.500 06:19.500 No me digas.
tres-patines-y-la-tremenda-corte_0045.vtt 13:29.000 13:31.000 Calma, Ruedesindo, no me digas nada.
tres-patines-y-la-tremenda-corte_0045.vtt 13:17.000 13:18.000 No me digas.
tres-patines-y-la-tremenda-corte_0023.vtt 09:28.600 09:29.600 No me digas.
tres-patines-y-la-tremenda-corte_0046.vtt 07:47.000 07:48.000 ¡No me digas!
tres-patines-y-la-tremenda-corte_0009.vtt 12:19.000 12:20.000 No me digas.
tres-patines-y-la-tremenda-corte_0043.vtt 05:41.000 05:42.000 No me digas.
tres-patines-y-la-tremenda-corte_0050.vtt 11:18.600 11:19.600 No me digas.
tres-patines-y-la-tremenda-corte_0030.vtt 08:42.440 08:44.440 No me digas.
tres-patines-y-la-tremenda-corte_0030.vtt 09:00.440 09:02.440 ¡No me digas! Mire, háganme el favor
tres-patines-y-la-tremenda-corte_0043.vtt 04:46.000 04:48.000 Le digo, no me digas, es una exclamación, señor.
tres-patines-y-la-tremenda-corte_0050.vtt 13:50.600 13:52.680 No me digas, ¿y los frijoles colorados?
tres-patines-y-la-tremenda-corte_0016.vtt 00:21.480 00:22.360 No me digas.
tres-patines-y-la-tremenda-corte_0001.vtt 07:44.000 07:45.000 No me digas.

Cluster 3 with 240 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0038.vtt 12:54.000 12:55.000 Ah, ¿y qué más?
tres-patines-y-la-tremenda-corte_0001.vtt 14:08.000 14:09.000 Ah, sí.
tres-patines-y-la-tremenda-corte_0045.vtt 11:38.000 11:40.000 Ah, son de barca pesquera, chicos.
tres-patines-y-la-tremenda-corte_0031.vtt 02:49.000 02:50.000 ¿Ah, no?
tres-patines-y-la-tremenda-corte_0043.vtt 08:40.000 08:42.000 Ah, pero hay que pagar el seguro suyo.
tres-patines-y-la-tremenda-corte_0023.vtt 11:14.600 11:15.600 Ah, no.
tres-patines-y-la-tremenda-corte_0031.vtt 11:49.000 11:50.000 Ah, va.
tres-patines-y-la-tremenda-corte_0001.vtt 02:20.000 02:22.000 Ah, tú no trajiste a abogado tampoco.
tres-patines-y-la-tremenda-corte_0031.vtt 07:02.000 07:03.000 Ah, eso sí.
tres-patines-y-la-tremenda-corte_0011.vtt 05:58.000 05:59.000 Ah, sí.
tres-patines-y-la-tremenda-corte_0008.vtt 07:19.000 07:20.000 ¿Ah, tiene tubería?
tres-patines-y-la-tremenda-corte_0002.vtt 05:35.000 05:36.000 Ah, arruleciendo.
tres-patines-y-la-tremenda-corte_0006.vtt 04:46.000 04:47.000 Ah, dijiste vigente.
tres-patines-y-la-tremenda-corte_0031.vtt 14:21.000 14:22.000 ¿Ah, sí?
tres-patines-y-la-tremenda-corte_0041.vtt 12:57.120 12:58.120 ¿Ah, sí?
tres-patines-y-la-tremenda-corte_0008.vtt 15:46.000 15:48.000 Ah, sí, pues estaba lleno de fruta.
tres-patines-y-la-tremenda-corte_0031.vtt 01:17.000 01:18.000 Ah, qué bambaridad.
tres-patines-y-la-tremenda-corte_0011.vtt 10:56.000 10:57.000 Ah, ¿y cómo yo no lo sentí?
tres-patines-y-la-tremenda-corte_0047.vtt 09:31.000 09:33.000 Ah, todavía piensa dispararme más.
tres-patines-y-la-tremenda-corte_0033.vtt 10:16.000 10:18.000 Ah, esto es aparte de Cucúsita

Cluster 16 with 32 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0043.vtt 11:25.000 11:26.000 él.
tres-patines-y-la-tremenda-corte_0023.vtt 05:42.600 05:43.600 Y déjeme acabar de leer.
tres-patines-y-la-tremenda-corte_0001.vtt 11:10.000 11:11.000 No, es bravo, pero es así.
tres-patines-y-la-tremenda-corte_0030.vtt 08:08.440 08:10.440 que le... El manco del espanto, del espanto, lo que le espanta
tres-patines-y-la-tremenda-corte_0006.vtt 07:30.000 07:34.000 ¿Nosotros nos quedamos en que la casa la barreríamos un día sí, un día no?
tres-patines-y-la-tremenda-corte_0046.vtt 00:11.000 00:16.000 con Leopardo Fernández, Aníbal Demar, Mimi Cal y Miguel Ángel Herrera
tres-patines-y-la-tremenda-corte_0023.vtt 08:42.600 08:43.600 ¿Para dónde?
tres-patines-y-la-tremenda-corte_0046.vtt 00:11.000 00:16.000 con Leopardo Fernández, Aníbal Demar, Mimi Cal y Miguel Ángel Herrera
tres-patines-y-la-tremenda-corte_0043.vtt 11:25.000 11:26.000 él.
tres-patines-y-la-tremenda-corte_0000.vtt 02:26.000 02:28.000 ¿Y entonces por qué dice que no lo trajiste?
tres-patines-y-la-tremenda-corte_0008.vtt 10:35.000 10:36.000 ¿Y entonces qué bicicleta fue la que dobló por Velacoini?
tres-patines-y-la-tremenda-corte_0049.vtt 02:58.000 02:59.000 Mitad caballo y mitad oso, chico.
tres-patines-y-la-tremenda-corte_0033.vtt 10:11.000 10:12.000 No, eso era...
tres-patines-y-la-tremenda-corte_0046.vtt 00:11.000 00:16.000 con Leopardo Fernández, Aníbal Demar, Mimi Cal y Miguel Ángel Herrera
tres-patines-y-la-tremenda-corte_0001.vtt 07:03.000 07:04.000 ¿Entonces usted no conoce de carrera?
tres-patines-y-la-tremenda-corte_0022.vtt 13:39.100 13:41.900 y porque estaban hechos con un aceite magnífico.
tres-patines-y-la-tremenda-corte_0005.vtt 11:42.000 11:44.000 Con el único que hay, con el que usted le robó al rudecinto.
tres-patines-y-la-tremenda-corte_0012.vtt 13:22.720 13:24.720 porque meterlo es fácil, pero para sacarlo
tres-patines-y-la-tremenda-corte_0044.vtt 05:02.000 05:03.000 El itinerario.
tres-patines-y-la-tremenda-corte_0019.vtt 07:20.000 07:21.000 No, yo con las...

Cluster 40 with 303 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0023.vtt 04:15.600 04:16.600 Sí.
tres-patines-y-la-tremenda-corte_0044.vtt 06:00.000 06:01.000 Sí.
tres-patines-y-la-tremenda-corte_0019.vtt 02:53.000 02:54.000 Sí.
tres-patines-y-la-tremenda-corte_0019.vtt 02:53.000 02:54.000 Sí.
tres-patines-y-la-tremenda-corte_0006.vtt 11:02.000 11:03.000 Sí.
tres-patines-y-la-tremenda-corte_0039.vtt 07:18.100 07:18.600 Sí.
tres-patines-y-la-tremenda-corte_0045.vtt 09:00.000 09:01.000 si las podíamos mandar.
tres-patines-y-la-tremenda-corte_0007.vtt 12:24.000 12:25.000 Sí.
tres-patines-y-la-tremenda-corte_0028.vtt 09:33.000 09:34.000 Sí.
tres-patines-y-la-tremenda-corte_0035.vtt 07:08.000 07:09.000 Sí.
tres-patines-y-la-tremenda-corte_0048.vtt 12:44.000 12:45.000 Sí.
tres-patines-y-la-tremenda-corte_0006.vtt 11:34.000 11:35.000 Sí.
tres-patines-y-la-tremenda-corte_0020.vtt 00:59.000 01:00.000 Sí.
tres-patines-y-la-tremenda-corte_0003.vtt 14:57.320 14:58.320 Yo sí.
tres-patines-y-la-tremenda-corte_0012.vtt 15:04.040 15:06.040 Sí.
tres-patines-y-la-tremenda-corte_0047.vtt 08:21.000 08:22.000 Sí.
tres-patines-y-la-tremenda-corte_0015.vtt 11:03.000 11:04.000 Sí.
tres-patines-y-la-tremenda-corte_0031.vtt 02:07.000 02:08.000 Sí.
tres-patines-y-la-tremenda-corte_0019.vtt 06:31.000 06:32.000 Sí.
tres-patines-y-la-tremenda-corte_0028.vtt 07:03.000 07:04.000 Sí.

Cluster 68 with 18 elements

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0001.vtt 04:17.000 04:18.000 De nada.
tres-patines-y-la-tremenda-corte_0001.vtt 12:56.000 12:57.000 Le dio una cos.
tres-patines-y-la-tremenda-corte_0006.vtt 10:45.000 10:47.000 Sí, pero de la parte de atrás nada más.
tres-patines-y-la-tremenda-corte_0010.vtt 04:44.000 04:45.000 De nada.
tres-patines-y-la-tremenda-corte_0010.vtt 04:50.000 04:51.000 De nada.
tres-patines-y-la-tremenda-corte_0011.vtt 08:44.000 08:47.000 Con la mosca que venía a posarse otra vez el hombro.
tres-patines-y-la-tremenda-corte_0012.vtt 10:17.640 10:19.640 En la escalera.
tres-patines-y-la-tremenda-corte_0013.vtt 07:12.000 07:16.000 Y cuando todo el mundo se llevó a la fuga, pues él se apoderó de los cuatrocientos
tres-patines-y-la-tremenda-corte_0014.vtt 09:12.000 09:13.000 De nada
tres-patines-y-la-tremenda-corte_0027.vtt 02:26.000 02:29.000 Yo vengo aquí en calidad de testigo, nada más.
tres-patines-y-la-tremenda-corte_0028.vtt 08:41.000 08:42.000 De nada.
tres-patines-y-la-tremenda-corte_0028.vtt 15:04.000 15:07.000 Tampoco, porque mi gato nunca ha sido piche ni nada de esto.
tres-patines-y-la-tremenda-corte_0031.vtt 14:29.000 14:30.000 te repito otra vez,
tres-patines-y-la-tremenda-corte_0033.vtt 02:29.000 02:32.000 Digo que soy inocente y me voy para casa
tres-patines-y-la-tremenda-corte_0045.vtt 05:54.000 05:56.000 Porque voy a conocerla.
tres-patines-y-la-tremenda-corte_0046.vtt 08:51.000 08:55.000 Se levantaron de la mesa y se fueron sin pagar
tres-patines-y-la-tremenda-corte_0047.vtt 14:22.000 14:24.000 Tú has visto, chicos, qué coincidencia.
tres-patines-y-la-tremenda-corte_0049.vtt 06:50.000 06:51.000 ¿Y cuándo me toque mi turno?

Cluster 104 with 59 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0048.vtt 11:34.000 11:35.000 ¡Eso es lo mismo!
tres-patines-y-la-tremenda-corte_0029.vtt 14:14.000 14:16.000 ¡Muy buena suerte, amigos!
tres-patines-y-la-tremenda-corte_0008.vtt 10:06.000 10:07.000 ¡No!
tres-patines-y-la-tremenda-corte_0033.vtt 01:58.000 01:59.000 ¡Preciente!
tres-patines-y-la-tremenda-corte_0004.vtt 01:02.000 01:05.000 ¡Luz María Nananina!
tres-patines-y-la-tremenda-corte_0040.vtt 02:18.000 02:20.000 ¡A la reja!
tres-patines-y-la-tremenda-corte_0034.vtt 00:03.000 00:04.000 ¡Silencio!
tres-patines-y-la-tremenda-corte_0015.vtt 08:54.000 08:55.000 ¡Y entonces!
tres-patines-y-la-tremenda-corte_0045.vtt 08:00.000 08:01.000 ¡180 días!
tres-patines-y-la-tremenda-corte_0010.vtt 02:43.000 02:44.000 ¡Gosa!
tres-patines-y-la-tremenda-corte_0022.vtt 05:55.000 05:56.000 ¡Bindito Dios!
tres-patines-y-la-tremenda-corte_0044.vtt 13:39.000 13:40.000 Y a los diez minutos, ¡pan!
tres-patines-y-la-tremenda-corte_0002.vtt 12:32.000 12:33.000 ¡Oh, ray! ¡Oh, ray!
tres-patines-y-la-tremenda-corte_0018.vtt 06:11.000 06:12.000 ¡Minucipio!
tres-patines-y-la-tremenda-corte_0013.vtt 04:59.000 05:00.000 ¡No!
tres-patines-y-la-tremenda-corte_0002.vtt 12:32.000 12:33.000 ¡Oh, ray! ¡Oh, ray!
tres-patines-y-la-tremenda-corte_0041.vtt 12:27.120 12:30.120 una gallina vino volando y ¡pam!
tres-patines-y-la-tremenda-corte_0030.vtt 09:16.440 09:18.440 ¡Obre! Los mosqueteros del rey.
tres-patines-y-la-tremenda-corte_0038.vtt 05:50.000 05:51.000 ¡Oh, manilla!
tres-patines-y-la-tremenda-corte_0048.vtt 15:51.000 15:53.000 ¡Muy buena suerte, amigos!

Cluster 119 with 23 elements – showing a small sample

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0004.vtt 06:59.000 07:00.000 ¿Dónde?
tres-patines-y-la-tremenda-corte_0005.vtt 01:34.000 01:35.000 ¿Entonces qué se mete usted?
tres-patines-y-la-tremenda-corte_0045.vtt 11:37.000 11:38.000 ¿Y de qué son entonces?
tres-patines-y-la-tremenda-corte_0012.vtt 13:16.280 13:18.280 ¿Qué me cuenta? ¿Usted no tiene más que
tres-patines-y-la-tremenda-corte_0040.vtt 10:42.000 10:43.000 ¿Cuál es lo que pasó?
tres-patines-y-la-tremenda-corte_0007.vtt 10:49.000 10:50.000 ¿Por qué su tío no está en buena posición?
tres-patines-y-la-tremenda-corte_0030.vtt 10:48.440 10:50.440 ¿Y en España? La conga llegó.
tres-patines-y-la-tremenda-corte_0029.vtt 09:13.000 09:15.000 ¿Usted quiere decir los gastos?
tres-patines-y-la-tremenda-corte_0025.vtt 12:04.760 12:06.320 ¿Se ha fijado?
tres-patines-y-la-tremenda-corte_0007.vtt 10:49.000 10:50.000 ¿Por qué su tío no está en buena posición?
tres-patines-y-la-tremenda-corte_0023.vtt 10:59.600 11:02.600 ¿Y entonces con qué se pronuncian las consonantes? ¿Con las orejas?
tres-patines-y-la-tremenda-corte_0005.vtt 01:34.000 01:35.000 ¿Entonces qué se mete usted?
tres-patines-y-la-tremenda-corte_0009.vtt 14:47.000 14:48.000 ¿Qué pasó entonces?
tres-patines-y-la-tremenda-corte_0009.vtt 14:47.000 14:48.000 ¿Qué pasó entonces?
tres-patines-y-la-tremenda-corte_0007.vtt 10:49.000 10:50.000 ¿Por qué su tío no está en buena posición?
tres-patines-y-la-tremenda-corte_0007.vtt 10:49.000 10:50.000 ¿Por qué su tío no está en buena posición?
tres-patines-y-la-tremenda-corte_0014.vtt 05:07.000 05:09.000 El que responde la firma que responde
tres-patines-y-la-tremenda-corte_0021.vtt 13:49.000 13:51.000 ¿Y qué, señora, no se ría?
tres-patines-y-la-tremenda-corte_0014.vtt 05:07.000 05:09.000 El que responde la firma que responde
tres-patines-y-la-tremenda-corte_0021.vtt 13:49.000 13:51.000 ¿Y qué, señora, no se ría?

Cluster 139 with 10 elements

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0006.vtt 11:44.000 11:46.000 Bueno, entonces la cosa es que no les dejan usar
tres-patines-y-la-tremenda-corte_0008.vtt 01:10.000 01:11.000 ¿Quién salió perdiendo?
tres-patines-y-la-tremenda-corte_0023.vtt 09:22.600 09:24.600 Oye, ¿y cómo se pronuncia entonces?
tres-patines-y-la-tremenda-corte_0042.vtt 02:01.000 02:03.000 Entonces, lo trae asando maíz.
tres-patines-y-la-tremenda-corte_0046.vtt 10:18.000 10:19.000 ¿Quién?
tres-patines-y-la-tremenda-corte_0047.vtt 00:57.000 00:58.000 ¿Y a quién se la robaron?
tres-patines-y-la-tremenda-corte_0047.vtt 06:59.000 07:01.000 ¿Quién es el acusado entonces?
tres-patines-y-la-tremenda-corte_0047.vtt 08:31.000 08:32.000 ¿Quién?
tres-patines-y-la-tremenda-corte_0048.vtt 05:50.000 05:51.000 ¿Quién?
tres-patines-y-la-tremenda-corte_0049.vtt 13:31.000 13:32.000 ¿Y de quién es la receta, entonces?

Cluster 152 with 10 elements

idfile name tbegin tend caption
tres-patines-y-la-tremenda-corte_0018.vtt 02:14.000 02:16.000 Usted no puede pedir eso, Rubesindo.
tres-patines-y-la-tremenda-corte_0020.vtt 15:32.000 15:35.000 Como usted le dijo que su mamita tenía una pierna muy mala y que no sabía qué hacer con ella.
tres-patines-y-la-tremenda-corte_0026.vtt 03:28.000 03:36.000 Bueno, eso de llevarse la hija para su casa lo podrán hacer algunas, pero mi suegra no lo puede hacer porque no tiene casa.
tres-patines-y-la-tremenda-corte_0035.vtt 03:27.000 03:28.000 Será porque tiene usted ganas.
tres-patines-y-la-tremenda-corte_0035.vtt 09:58.000 10:01.000 Porque usted tiene un idioma particular.
tres-patines-y-la-tremenda-corte_0040.vtt 09:31.000 09:32.000 Porque uno lo tiene bastante.
tres-patines-y-la-tremenda-corte_0041.vtt 06:33.120 06:36.120 ¿Y esto tiene algo que ver con la historia natural?
tres-patines-y-la-tremenda-corte_0041.vtt 07:04.120 07:07.120 No, doctor, lo que sintió nananina fue un toletazo
tres-patines-y-la-tremenda-corte_0049.vtt 14:29.000 14:33.000 Bueno, tres patines, ¿y usted vende esa sambumbia como si fuera gasolina?
tres-patines-y-la-tremenda-corte_0050.vtt 02:19.000 02:22.000 Sí, pero no se dice servidera, sino servidora.

Environment and dependencies

Julia Version 1.10.9
Commit 5595d20a287 (2025-03-10 12:51 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 64 × Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, cascadelake)
Threads: 64 default, 0 interactive, 32 GC (on 64 virtual cores)
Environment:
  JULIA_NUM_THREADS = auto
  JULIA_PROJECT = .
  JULIA_LOAD_PATH = @:@stdlib
Status `~/sites/SimilaritySearchDemos/Project.toml`
  [aaaa29a8] Clustering v0.15.8
  [944b1d66] CodecZlib v0.7.8
  [a93c6f00] DataFrames v1.7.0
  [c5bfea45] Embeddings v0.4.6
  [f67ccb44] HDF5 v0.17.2
  [b20bd276] InvertedFiles v0.8.0 `~/.julia/dev/InvertedFiles`
  [682c06a0] JSON v0.21.4
  [23fbe1c1] Latexify v0.16.6
  [eb30cadb] MLDatasets v0.7.18
  [06eb3307] ManifoldLearning v0.9.0
⌃ [ca7969ec] PlotlyLight v0.11.0
  [91a5bcdd] Plots v1.40.11
  [27ebfcd6] Primes v0.5.7
  [ca7ab67e] SimSearchManifoldLearning v0.3.0 `~/.julia/dev/SimSearchManifoldLearning`
  [053f045d] SimilaritySearch v0.12.0 `~/.julia/dev/SimilaritySearch`
⌅ [2913bbd2] StatsBase v0.33.21
  [f3b207a7] StatsPlots v0.15.7
  [7f6f6c8a] TextSearch v0.19.0 `~/.julia/dev/TextSearch`
Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`