speech_rate.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!/usr/bin/env python3
  2. import pandas as pd
  3. import pickle
  4. import numpy as np
  5. from scipy.special import logit, expit
  6. import argparse
  7. import matplotlib
  8. import matplotlib.pyplot as plt
  9. from scipy.stats import gamma
  10. from os.path import basename
  11. matplotlib.use("pgf")
  12. matplotlib.rcParams.update(
  13. {
  14. "pgf.texsystem": "pdflatex",
  15. "font.family": "serif",
  16. "font.serif": "Times New Roman",
  17. "text.usetex": True,
  18. "pgf.rcfonts": False,
  19. }
  20. )
  21. def set_size(width, fraction=1, ratio=None):
  22. fig_width_pt = width * fraction
  23. inches_per_pt = 1 / 72.27
  24. if ratio is None:
  25. ratio = (5**0.5 - 1) / 2
  26. fig_width_in = fig_width_pt * inches_per_pt
  27. fig_height_in = fig_width_in * ratio
  28. return fig_width_in, fig_height_in
  29. parser = argparse.ArgumentParser(description="speech_rate")
  30. parser.add_argument("data")
  31. parser.add_argument("fit")
  32. parser.add_argument("output")
  33. parser.add_argument("--selected-corpus", type=int, default=-1)
  34. args = parser.parse_args()
  35. with open(args.data, "rb") as fp:
  36. data = pickle.load(fp)
  37. fit = pd.read_parquet(args.fit)
  38. corpora = pd.read_csv("output/training_set.csv")
  39. corpora = corpora["corpus"].map(basename).tolist()
  40. speakers = ["CHI", "OCH", "FEM", "MAL"]
  41. n_groups = data["n_groups"]
  42. n_corpora = data["n_corpora"]
  43. colors = ['#377eb8', '#ff7f00', '#4daf4a', '#f781bf']
  44. mu = np.zeros((data['n_corpora'], 4))
  45. mu_low = np.zeros((data['n_corpora'], 4))
  46. mu_high = np.zeros((data['n_corpora'], 4))
  47. inputs = np.zeros((data['n_corpora'], len(fit)))
  48. input = np.zeros(data['n_corpora'])
  49. input_low = np.zeros(data['n_corpora'])
  50. input_high = np.zeros(data['n_corpora'])
  51. output_speech = np.zeros((data['n_corpora'], len(fit)))
  52. input_speech = np.zeros((data['n_corpora'], len(fit)))
  53. output_dur = np.zeros(data['n_corpora'])
  54. output_dur_low = np.zeros(data['n_corpora'])
  55. output_dur_high = np.zeros(data['n_corpora'])
  56. input_dur = np.zeros(data['n_corpora'])
  57. input_dur_low = np.zeros(data['n_corpora'])
  58. input_dur_high = np.zeros(data['n_corpora'])
  59. for c in range(data['n_corpora']):
  60. for i in range(4):
  61. # alphas = fit[f"speech_rate_alpha.{i+1}.{c+1}"].values
  62. # betas = fit[f"speech_rate_beta.{i+1}.{c+1}"].values/1000
  63. # voc_dur_alphas = fit[f"voc_dur_alpha.{i+1}.{c+1}"].values
  64. # voc_dur_betas = fit[f"voc_dur_beta.{i+1}.{c+1}"].values
  65. mus = 1000*fit[f"speech_rate_mu.{i+1}.{c+1}"].values
  66. voc_dur_means = fit[f"voc_dur_mu.{i+1}.{c+1}"].values
  67. print(corpora[c], voc_dur_means.mean())
  68. mu[c,i] = np.mean(mus)
  69. mu_low[c,i] = np.quantile(mus, q=0.05/2)
  70. mu_high[c,i] = np.quantile(mus, q=1-0.05/2)
  71. if i > 0:
  72. inputs[c,:] += mus
  73. input_speech[c,:] += voc_dur_means*mus
  74. else:
  75. output_speech[c,:] = voc_dur_means*mus
  76. input[c] = inputs[c,:].mean()
  77. input_low[c] = np.quantile(inputs[c,:], q=0.05/2)
  78. input_high[c] = np.quantile(inputs[c,:], q=1-0.05/2)
  79. output_dur[c] = output_speech[c,:].mean()/60
  80. output_dur_low[c] = np.quantile(output_speech[c,:], q=0.05/2)/60
  81. output_dur_high[c] = np.quantile(output_speech[c,:], q=1-0.05/2)/60
  82. input_dur[c] = input_speech[c,:].mean()/60
  83. input_dur_low[c] = np.quantile(input_speech[c,:], q=0.05/2)/60
  84. input_dur_high[c] = np.quantile(input_speech[c,:], q=1-0.05/2)/60
  85. keep = [c not in ["winnipeg", "tsimane2017"] for c in corpora]
  86. corpora = [corpora[i] for i in range(len(corpora)) if keep[i]]
  87. mu = mu[keep,:]
  88. mu_low = mu_low[keep,:]
  89. mu_high = mu_high[keep,:]
  90. input = input[keep]
  91. input_low = input_low[keep]
  92. input_high = input_high[keep]
  93. input_dur = input_dur[keep]
  94. input_dur_low = input_dur_low[keep]
  95. input_dur_high = input_dur_high[keep]
  96. output_dur = output_dur[keep]
  97. output_dur_low = output_dur_low[keep]
  98. output_dur_high = output_dur_high[keep]
  99. print(corpora)
  100. print(mu.shape)
  101. fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
  102. for row in range (2):
  103. for col in range(2):
  104. i = row+2*col
  105. axes[row,col].scatter(np.arange(mu.shape[0]), mu[:,i])
  106. axes[row,col].errorbar(np.arange(mu.shape[0]), mu[:,i], (mu[:,i]-mu_low[:,i], mu_high[:,i]-mu[:,i]) ,ls="none")
  107. axes[row,col].set_title(speakers[i])
  108. axes[row,col].set_ylim(0,1200)
  109. axes[row,col].set_xticks(np.arange(mu.shape[0]))
  110. axes[row,col].set_xticklabels(corpora)
  111. axes[row,col].xaxis.set_tick_params(rotation=90)
  112. if col==0:
  113. axes[row,col].set_ylabel("voc/h")
  114. fig.suptitle("Latent population mean voc/h\n(human annotations)")
  115. fig.savefig("output/quantities.png", bbox_inches="tight")
  116. fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
  117. for col in range(2):
  118. if col == 0:
  119. axes[col].scatter(np.arange(mu.shape[0]), mu[:,0])
  120. axes[col].errorbar(np.arange(mu.shape[0]), mu[:,0], (mu[:,0]-mu_low[:,0], mu_high[:,0]-mu[:,0]) ,ls="none")
  121. else:
  122. axes[col].scatter(np.arange(len(input)), input)
  123. axes[col].errorbar(np.arange(len(input)), input, (input-input_low, input_high-input) ,ls="none")
  124. axes[col].set_title("output" if col == 0 else "input")
  125. axes[col].set_ylim(0,2000)
  126. axes[col].set_xticks(np.arange(mu.shape[0]))
  127. axes[col].set_xticklabels(corpora)
  128. axes[col].xaxis.set_tick_params(rotation=90)
  129. if col==0:
  130. axes[col].set_ylabel("voc/h")
  131. fig.suptitle("Latent population mean voc/h\n(human annotations)")
  132. fig.savefig("output/input_output.png", bbox_inches="tight")
  133. fig, axes = plt.subplots(1, 2, sharex=True, sharey=True)
  134. for col in range(2):
  135. if col == 0:
  136. axes[col].scatter(np.arange(len(output_dur)), output_dur)
  137. axes[col].errorbar(np.arange(len(output_dur)), output_dur, (output_dur-output_dur_low, output_dur_high-output_dur) ,ls="none")
  138. else:
  139. axes[col].scatter(np.arange(len(input_dur)), input_dur)
  140. axes[col].errorbar(np.arange(len(input_dur)), input_dur, (input_dur-input_dur_low, input_dur_high-input_dur) ,ls="none")
  141. axes[col].set_title("output" if col == 0 else "input")
  142. axes[col].set_ylim(0,60)
  143. axes[col].set_xticks(np.arange(mu.shape[0]))
  144. axes[col].set_xticklabels(corpora)
  145. axes[col].xaxis.set_tick_params(rotation=90)
  146. if col==0:
  147. axes[col].set_ylabel("min/h")
  148. fig.suptitle("Latent population mean min/h\n(human annotations)")
  149. fig.savefig("output/input_output_dur.png", bbox_inches="tight")
  150. fig, ax = plt.subplots(1,1)
  151. for i in range(4):
  152. alphas = fit[f"speech_rate_alpha.{i+1}.{args.selected_corpus}"].values
  153. scale = 1000*fit[f"speech_rate_mu.{i+1}.{args.selected_corpus}"].values/alphas
  154. x = np.linspace(0,500,200,True)
  155. pdf = np.zeros((len(x), len(alphas)))
  156. for k in range(len(x)):
  157. pdf[k,:] = gamma.pdf(x[k], alphas, np.zeros(len(alphas)), scale)
  158. pdf_low = np.quantile(pdf, q=0.05, axis=1)
  159. pdf_high = np.quantile(pdf, q=0.95, axis=1)
  160. pdf_mean = np.mean(pdf, axis=1)
  161. ax.plot(x, pdf_mean, color=colors[i], label=speakers[i])
  162. ax.fill_between(x, pdf_low, pdf_high, color=colors[i], alpha=0.2)
  163. ax.set_xlim(0, 500)
  164. ax.set_xlabel("voc/h")
  165. # ax.axvline(np.mean(data), linestyle="--", linewidth=0.5, color="#333", alpha=1)
  166. # ax.text(0.5, 4.5, f"{low:.2f} - {high:.2f}", ha="center", va="center")
  167. ax.legend()
  168. corpus = pd.read_csv("output/training_set.csv")["corpus"].map(basename).tolist()[args.selected_corpus-1]
  169. fig.suptitle(f"voc/h distribution for each kind of speaker ({corpus})")
  170. fig.savefig(f"output/speech_distribution_{corpus}.png", bbox_inches="tight")
  171. plt.show()