|
@@ -19,15 +19,18 @@ from pyannote.core import Annotation, Segment, Timeline
|
|
|
|
|
|
import stan
|
|
|
|
|
|
-parser = argparse.ArgumentParser(description = 'main model described throughout the notes.')
|
|
|
-parser.add_argument('--group', default = 'child', choices = ['corpus', 'child'])
|
|
|
-parser.add_argument('--chains', default = 4, type = int)
|
|
|
-parser.add_argument('--samples', default = 2000, type = int)
|
|
|
-parser.add_argument('--validation', default = 0, type = float)
|
|
|
-parser.add_argument('--output', default = 'model3')
|
|
|
+parser = argparse.ArgumentParser(
|
|
|
+ description="main model described throughout the notes."
|
|
|
+)
|
|
|
+parser.add_argument("--group", default="child", choices=["corpus", "child"])
|
|
|
+parser.add_argument("--chains", default=4, type=int)
|
|
|
+parser.add_argument("--samples", default=2000, type=int)
|
|
|
+parser.add_argument("--validation", default=0, type=float)
|
|
|
+parser.add_argument("--output", default="model3")
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
-def extrude(self, removed, mode: str = 'intersection'):
|
|
|
+
|
|
|
+def extrude(self, removed, mode: str = "intersection"):
|
|
|
if isinstance(removed, Segment):
|
|
|
removed = Timeline([removed])
|
|
|
|
|
@@ -37,89 +40,117 @@ def extrude(self, removed, mode: str = 'intersection'):
|
|
|
mode = "strict"
|
|
|
elif mode == "strict":
|
|
|
mode = "loose"
|
|
|
-
|
|
|
+
|
|
|
return self.crop(truncating_support, mode=mode)
|
|
|
|
|
|
+
|
|
|
def compute_counts(parameters):
|
|
|
- corpus = parameters['corpus']
|
|
|
- annotator = parameters['annotator']
|
|
|
- speakers = ['CHI', 'OCH', 'FEM', 'MAL']
|
|
|
+ corpus = parameters["corpus"]
|
|
|
+ annotator = parameters["annotator"]
|
|
|
+ speakers = ["CHI", "OCH", "FEM", "MAL"]
|
|
|
|
|
|
- project = ChildProject(parameters['path'])
|
|
|
+ project = ChildProject(parameters["path"])
|
|
|
am = AnnotationManager(project)
|
|
|
am.read()
|
|
|
|
|
|
- intersection = AnnotationManager.intersection(
|
|
|
- am.annotations, ['vtc', annotator]
|
|
|
- )
|
|
|
+ intersection = AnnotationManager.intersection(am.annotations, ["vtc", annotator])
|
|
|
|
|
|
- intersection['path'] = intersection.apply(
|
|
|
- lambda r: opj(project.path, 'annotations', r['set'], 'converted', r['annotation_filename']),
|
|
|
- axis = 1
|
|
|
+ intersection["path"] = intersection.apply(
|
|
|
+ lambda r: opj(
|
|
|
+ project.path, "annotations", r["set"], "converted", r["annotation_filename"]
|
|
|
+ ),
|
|
|
+ axis=1,
|
|
|
)
|
|
|
- datalad.api.get(list(intersection['path'].unique()))
|
|
|
+ datalad.api.get(list(intersection["path"].unique()))
|
|
|
|
|
|
- intersection = intersection.merge(project.recordings[['recording_filename', 'child_id']], how = 'left')
|
|
|
- intersection['child'] = corpus + '_' + intersection['child_id'].astype(str)
|
|
|
- intersection['duration'] = intersection['range_offset']-intersection['range_onset']
|
|
|
- print(corpus, annotator, (intersection['duration']/1000/2).sum()/3600)
|
|
|
+ intersection = intersection.merge(
|
|
|
+ project.recordings[["recording_filename", "child_id"]], how="left"
|
|
|
+ )
|
|
|
+ intersection["child"] = corpus + "_" + intersection["child_id"].astype(str)
|
|
|
+ intersection["duration"] = (
|
|
|
+ intersection["range_offset"] - intersection["range_onset"]
|
|
|
+ )
|
|
|
+ print(corpus, annotator, (intersection["duration"] / 1000 / 2).sum() / 3600)
|
|
|
|
|
|
data = []
|
|
|
- for child, ann in intersection.groupby('child'):
|
|
|
- #print(corpus, child)
|
|
|
+ for child, ann in intersection.groupby("child"):
|
|
|
+ # print(corpus, child)
|
|
|
|
|
|
segments = am.get_collapsed_segments(ann)
|
|
|
- if 'speaker_type' not in segments.columns:
|
|
|
+ if "speaker_type" not in segments.columns:
|
|
|
continue
|
|
|
|
|
|
- segments = segments[segments['speaker_type'].isin(speakers)]
|
|
|
-
|
|
|
+ segments = segments[segments["speaker_type"].isin(speakers)]
|
|
|
+
|
|
|
vtc = {
|
|
|
- speaker: segments_to_annotation(segments[(segments['set'] == 'vtc') & (segments['speaker_type'] == speaker)], 'speaker_type').get_timeline()
|
|
|
+ speaker: segments_to_annotation(
|
|
|
+ segments[
|
|
|
+ (segments["set"] == "vtc") & (segments["speaker_type"] == speaker)
|
|
|
+ ],
|
|
|
+ "speaker_type",
|
|
|
+ ).get_timeline()
|
|
|
for speaker in speakers
|
|
|
}
|
|
|
|
|
|
truth = {
|
|
|
- speaker: segments_to_annotation(segments[(segments['set'] == annotator) & (segments['speaker_type'] == speaker)], 'speaker_type').get_timeline()
|
|
|
+ speaker: segments_to_annotation(
|
|
|
+ segments[
|
|
|
+ (segments["set"] == annotator)
|
|
|
+ & (segments["speaker_type"] == speaker)
|
|
|
+ ],
|
|
|
+ "speaker_type",
|
|
|
+ ).get_timeline()
|
|
|
for speaker in speakers
|
|
|
}
|
|
|
|
|
|
for speaker_A in speakers:
|
|
|
- vtc[f'{speaker_A}_vocs_explained'] = vtc[speaker_A].crop(truth[speaker_A], mode = 'loose')
|
|
|
- vtc[f'{speaker_A}_vocs_fp'] = extrude(vtc[speaker_A], vtc[f'{speaker_A}_vocs_explained'])
|
|
|
- vtc[f'{speaker_A}_vocs_fn'] = extrude(truth[speaker_A], truth[speaker_A].crop(vtc[speaker_A], mode = 'loose'))
|
|
|
+ vtc[f"{speaker_A}_vocs_explained"] = vtc[speaker_A].crop(
|
|
|
+ truth[speaker_A], mode="loose"
|
|
|
+ )
|
|
|
+ vtc[f"{speaker_A}_vocs_fp"] = extrude(
|
|
|
+ vtc[speaker_A], vtc[f"{speaker_A}_vocs_explained"]
|
|
|
+ )
|
|
|
+ vtc[f"{speaker_A}_vocs_fn"] = extrude(
|
|
|
+ truth[speaker_A], truth[speaker_A].crop(vtc[speaker_A], mode="loose")
|
|
|
+ )
|
|
|
|
|
|
for speaker_B in speakers:
|
|
|
- vtc[f'{speaker_A}_vocs_fp_{speaker_B}'] = vtc[f'{speaker_A}_vocs_fp'].crop(truth[speaker_B], mode = 'loose')
|
|
|
+ vtc[f"{speaker_A}_vocs_fp_{speaker_B}"] = vtc[
|
|
|
+ f"{speaker_A}_vocs_fp"
|
|
|
+ ].crop(truth[speaker_B], mode="loose")
|
|
|
|
|
|
for speaker_C in speakers:
|
|
|
if speaker_C != speaker_B and speaker_C != speaker_A:
|
|
|
- vtc[f'{speaker_A}_vocs_fp_{speaker_B}'] = extrude(
|
|
|
- vtc[f'{speaker_A}_vocs_fp_{speaker_B}'],
|
|
|
- vtc[f'{speaker_A}_vocs_fp_{speaker_B}'].crop(truth[speaker_C], mode = 'loose')
|
|
|
+ vtc[f"{speaker_A}_vocs_fp_{speaker_B}"] = extrude(
|
|
|
+ vtc[f"{speaker_A}_vocs_fp_{speaker_B}"],
|
|
|
+ vtc[f"{speaker_A}_vocs_fp_{speaker_B}"].crop(
|
|
|
+ truth[speaker_C], mode="loose"
|
|
|
+ ),
|
|
|
)
|
|
|
|
|
|
-
|
|
|
d = {}
|
|
|
for i, speaker_A in enumerate(speakers):
|
|
|
for j, speaker_B in enumerate(speakers):
|
|
|
if i != j:
|
|
|
- z = len(vtc[f'{speaker_A}_vocs_fp_{speaker_B}'])
|
|
|
+ z = len(vtc[f"{speaker_A}_vocs_fp_{speaker_B}"])
|
|
|
else:
|
|
|
- z = min(len(vtc[f'{speaker_A}_vocs_explained']), len(truth[speaker_A]))
|
|
|
+ z = min(
|
|
|
+ len(vtc[f"{speaker_A}_vocs_explained"]), len(truth[speaker_A])
|
|
|
+ )
|
|
|
|
|
|
- d[f'vtc_{i}_{j}'] = z
|
|
|
+ d[f"vtc_{i}_{j}"] = z
|
|
|
|
|
|
- d[f'truth_{i}'] = len(truth[speaker_A])
|
|
|
- d['child'] = child
|
|
|
+ d[f"truth_{i}"] = len(truth[speaker_A])
|
|
|
+ d["child"] = child
|
|
|
|
|
|
- d['duration'] = ann['duration'].sum()/2/1000
|
|
|
+ d["duration"] = ann["duration"].sum() / 2 / 1000
|
|
|
data.append(d)
|
|
|
|
|
|
return pd.DataFrame(data).assign(
|
|
|
- corpus = corpus,
|
|
|
+ corpus=corpus,
|
|
|
)
|
|
|
|
|
|
+
|
|
|
stan_code = """
|
|
|
data {
|
|
|
int<lower=1> n_clips; // number of clips
|
|
@@ -239,47 +270,47 @@ generated quantities {
|
|
|
"""
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
- annotators = pd.read_csv('input/annotators.csv')
|
|
|
- annotators['path'] = annotators['corpus'].apply(lambda c: opj('input', c))
|
|
|
+ annotators = pd.read_csv("input/annotators.csv")
|
|
|
+ annotators["path"] = annotators["corpus"].apply(lambda c: opj("input", c))
|
|
|
|
|
|
- with mp.Pool(processes = 8) as pool:
|
|
|
- data = pd.concat(pool.map(compute_counts, annotators.to_dict(orient = 'records')))
|
|
|
+ with mp.Pool(processes=8) as pool:
|
|
|
+ data = pd.concat(pool.map(compute_counts, annotators.to_dict(orient="records")))
|
|
|
|
|
|
- data = data.sample(frac = 1)
|
|
|
- duration = data['duration'].sum()
|
|
|
+ data = data.sample(frac=1)
|
|
|
+ duration = data["duration"].sum()
|
|
|
|
|
|
- vtc = np.moveaxis([[data[f'vtc_{j}_{i}'].values for i in range(4)] for j in range(4)], -1, 0)
|
|
|
- truth = np.transpose([data[f'truth_{i}'].values for i in range(4)])
|
|
|
+ vtc = np.moveaxis(
|
|
|
+ [[data[f"vtc_{j}_{i}"].values for i in range(4)] for j in range(4)], -1, 0
|
|
|
+ )
|
|
|
+ truth = np.transpose([data[f"truth_{i}"].values for i in range(4)])
|
|
|
|
|
|
print(vtc.shape)
|
|
|
|
|
|
- rates = pd.read_csv('output/speech_dist.csv')
|
|
|
+ rates = pd.read_csv("output/speech_dist.csv")
|
|
|
|
|
|
data = {
|
|
|
- 'n_clips': truth.shape[0],
|
|
|
- 'n_classes': truth.shape[1],
|
|
|
- 'n_groups': data[args.group].nunique(),
|
|
|
- 'n_validation': max(1, int(truth.shape[0]*args.validation)),
|
|
|
- 'n_sim': 40,
|
|
|
- 'group': 1+data[args.group].astype('category').cat.codes.values,
|
|
|
- 'truth': truth.astype(int),
|
|
|
- 'vtc': vtc.astype(int),
|
|
|
- 'rates_alphas': rates['alpha'].values,
|
|
|
- 'rates_betas': rates['beta'].values
|
|
|
+ "n_clips": truth.shape[0],
|
|
|
+ "n_classes": truth.shape[1],
|
|
|
+ "n_groups": data[args.group].nunique(),
|
|
|
+ "n_validation": max(1, int(truth.shape[0] * args.validation)),
|
|
|
+ "n_sim": 40,
|
|
|
+ "group": 1 + data[args.group].astype("category").cat.codes.values,
|
|
|
+ "truth": truth.astype(int),
|
|
|
+ "vtc": vtc.astype(int),
|
|
|
+ "rates_alphas": rates["alpha"].values,
|
|
|
+ "rates_betas": rates["beta"].values,
|
|
|
}
|
|
|
|
|
|
print(f"clips: {data['n_clips']}")
|
|
|
print(f"groups: {data['n_groups']}")
|
|
|
- print("true vocs: {}".format(np.sum(data['truth'])))
|
|
|
- print("vtc vocs: {}".format(np.sum(data['vtc'])))
|
|
|
+ print("true vocs: {}".format(np.sum(data["truth"])))
|
|
|
+ print("vtc vocs: {}".format(np.sum(data["vtc"])))
|
|
|
print("duration: {}".format(duration))
|
|
|
|
|
|
- with open(f'output/samples/data_{args.output}.pickle', 'wb') as fp:
|
|
|
+ with open(f"output/samples/data_{args.output}.pickle", "wb") as fp:
|
|
|
pickle.dump(data, fp, pickle.HIGHEST_PROTOCOL)
|
|
|
|
|
|
- posterior = stan.build(stan_code, data = data)
|
|
|
- fit = posterior.sample(num_chains = args.chains, num_samples = args.samples)
|
|
|
+ posterior = stan.build(stan_code, data=data)
|
|
|
+ fit = posterior.sample(num_chains=args.chains, num_samples=args.samples)
|
|
|
df = fit.to_frame()
|
|
|
- df.to_parquet(f'output/samples/fit_{args.output}.parquet')
|
|
|
-
|
|
|
-
|
|
|
+ df.to_parquet(f"output/samples/fit_{args.output}.parquet")
|