Warning, /sdk/pology/lang/nn/exclusion/lag-paradigme-oversikt.R is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/Rscript --vanilla
0002 #
0003 # Lag oversikt over kva kombinasjonar av bøyingar
0004 # som eksisterer i Norsk ordbank.
0005 #
0006 # For kvar kombinasjon vel me éi føretrekt bøying,
0007 # dersom dette gjev meining (det gjer det for eksempel
0008 # ikkje for ord som berre har valfritt kjønn).
0009 #
0010 # Brukar òg ordfrekvensinformasjon frå KDE-omsettinga,
0011 # for å få betre ordeksempel (funkar ikkje perfekt,
0012 # men er nyttig).
0013
0014
0015 # Innstillingar og filinnlesing -------------------------------------------
0016
0017 # Ymse pakkar for datahandsaming
0018 library(tidyverse)
0019
0020 # Mappe som inneheld filene til Norsk ordbank
0021 # og frekvensinformasjon frå KDE-omsettinga
0022 mappe_ordbank = "~/utvikling/ordbanken"
0023 mappe_frek = "~/utvikling/kde/trunk/l10n-support/nn/skript/frekvensoversikt"
0024
0025 # Les ordbankfiler og fjern unødvendige kolonnar
0026 les_fil = function(filnamn, ...) {
0027 d = read_tsv(paste0(mappe_ordbank, "/", filnamn), ...)
0028 d
0029 }
0030
0031 # Les inn alle datafilene
0032 d_lemma = les_fil(
0033 "lemma_nn.txt",
0034 col_types = cols_only(LEMMA_ID = col_integer(), GRUNNFORM = col_character()))
0035 d_fullform = les_fil(
0036 "fullformsliste_nn.txt",
0037 col_types = cols_only(
0038 LEMMA_ID = col_integer(),
0039 OPPSLAG = col_character(),
0040 TAG = col_character(),
0041 PARADIGME_ID = col_character(),
0042 BOY_NUMMER = col_integer(),
0043 FRADATO = col_character(),
0044 TILDATO = col_character(),
0045 NORMERING = col_character()
0046 )
0047 )
0048 d_lemmaparadigme = les_fil(
0049 "lemma_paradigme_nn.txt",
0050 col_types = cols_only(
0051 LEMMA_ID = col_integer(),
0052 PARADIGME_ID = col_character(),
0053 NORMERING = col_character(),
0054 FRADATO = col_character(),
0055 TILDATO = col_character(),
0056 KOMMENTAR = col_character()
0057 )
0058 )
0059 d_paradigme = les_fil(
0060 "paradigme_boying_nn.txt",
0061 col_types = cols_only(
0062 PARADIGME_ID = col_character(),
0063 BOY_NUMMER = col_integer(),
0064 BOY_GRUPPE = col_character(),
0065 BOY_UTTRYKK = col_character()
0066 )
0067 )
0068 d_frek = read_table(paste0(mappe_frek, "/", "frekvens-nn.dat"),
0069 col_names = c("frek", "OPPSLAG"), col_types = "nc")
0070
0071
0072
0073 # Lag paradigmeoversikt ---------------------------------------------------
0074
0075 # Legg til bruksfrekvensinfo for kvar fullform,
0076 # og oppsummer til slutt på lemmanivå
0077 # (vil vera misvisande for homograf, men ikkje noko stort problem)
0078 d_ffrek = d_fullform %>%
0079 select(LEMMA_ID, OPPSLAG) %>%
0080 distinct %>% # Vil ikkje telja frekvensinfo for duplikatbøyingar fleire gongar
0081 left_join(d_frek, by="OPPSLAG")
0082 d_lfrek = d_ffrek %>%
0083 group_by(LEMMA_ID) %>%
0084 summarise(frek = sum(frek, na.rm = TRUE), .groups = "drop") %>%
0085 left_join(d_lemma, by = "LEMMA_ID")
0086
0087 # d_lemmaparadigme skal i utgangspunktet innehalda alle
0088 # bøyingsparadigma til dei ulike lemmaa (gjer det ikkje heilt,
0089 # men det er vel ein feil som skal rettast?), så me
0090 # brukar denne for å finna paradigmekomboar
0091
0092 # Paradigma står i vilkårleg rekkjefølgje innanfor lemma,
0093 # så me vil sjå vekk frå rekkjefølgja
0094 d_lp = d_lemmaparadigme %>%
0095 arrange(LEMMA_ID, PARADIGME_ID)
0096
0097 # Samandrag over paradigme for kvart lemma
0098 d_psam_alle = d_lp %>%
0099 group_by(LEMMA_ID) %>%
0100 summarise(par_tekst = str_c(PARADIGME_ID, collapse=","),
0101 n_par = n(), .groups = "drop")
0102
0103 # Sjå berre på tilfelle der me har valfridom i bøying
0104 d_psam = d_psam_alle %>%
0105 filter(n_par > 1)
0106
0107 # Legg til frekvensinfo og hent ut
0108 # det mest frekvente lemmaet for
0109 # kvar paradigmekombo
0110 d_psam_pop = d_psam %>%
0111 left_join(d_lfrek, by = "LEMMA_ID") %>%
0112 arrange(par_tekst, desc(frek)) %>%
0113 distinct(par_tekst, .keep_all = TRUE) %>% # Berre første/mest populære lemma
0114 arrange(desc(frek)) # Sorter paradigmekomboar etter frekvens
0115
0116
0117
0118 # Oppdatering og lagring av fil -------------------------------------------
0119
0120 # Gjer klar fil for manuell redigering
0121 # Treng berre laga oversikt for ord
0122 # som faktisk er brukte i omsettingane
0123 d_utdata = d_psam_pop %>%
0124 filter(frek > 0) %>%
0125 select(par_tekst, LEMMA_ID, GRUNNFORM)
0126
0127 # Legg til ekstrakolonnar
0128 # (Brukar NA i staden for "" på grunn av seinare eksport)
0129 d_utdata$val = NA_character_ # Paradigmet me vel for denne typen ord
0130 d_utdata$kommentar = NA_character_ # Kommentar til valet/paradigmekomboen
0131 d_utdata$unntak = NA_character_ # Ev. unntak, på forma LEMMA_ID1=700,LEMMA_ID2=49G,…
0132
0133
0134 # Les inn gammal fil (for oppdatering)
0135 d_gammal = read_csv("paradigme-komboar.csv",
0136 col_types = cols(par_tekst = col_character(),
0137 LEMMA_ID = col_integer(),
0138 GRUNNFORM = col_character(),
0139 val = col_character(),
0140 kommentar = col_character()
0141 ))
0142 d_nye = d_utdata %>%
0143 anti_join(d_gammal, by = "par_tekst")
0144 d_oppdatert = bind_rows(d_gammal, d_nye)
0145
0146
0147 # Lagra oversiktsfil i CSV-format for manuell redigering
0148 #
0149 # Gjer det nøyaktig slik (og brukar for eksempel ikkje write_csv())
0150 # for at fila skal kunna redigerast med LibreOffice Calc utan at
0151 # det vert gjort formateringsendringar. Bruk følgjande innstillingar
0152 # ved import:
0153 #
0154 # Skild med: Komma (ingenting anna)
0155 # Formater sitatfelt som tekst: ja (kryssa av)
0156 #
0157 # Må etter import merkja heile «val»-kolonnen og endra «Talformat» til
0158 # «Tekst», for å hindra at talkodar som begynner med 0 mistar 0-talet.
0159 # (Det er *ikkje* nok eller nødvendig å gjera dette ved sjølve importen.)
0160 #
0161 write.csv(d_oppdatert, "paradigme-komboar.csv", row.names = FALSE, na = "")
0162
0163
0164
0165
0166 # Lag ordekskluderingsfil -------------------------------------------------
0167
0168 # Skal så laga ei oversikt over alle orda som skal ekskluderast
0169 d = d_oppdatert
0170
0171 # Bør først sjekka at paradigmekoden me har valt faktisk er
0172 # ein av dei gyldige paradigmekodane for lemmaet
0173 d = d %>% mutate(ok_val = is.na(val) |
0174 str_detect(par_tekst, str_c("\\b", d$val, "\\b")))
0175 if(!all(d$ok_val)) {
0176 stop(paste0("Minst éin paradigmekombo har ugyldig paradigmekode valt:\n",
0177 paste0(format(filter(d, !ok_val)), collapse="\n")))
0178 }
0179
0180 # Unntak er litt komlisert å handtera,
0181 # men det går bra … :)
0182
0183 # Hent ut unntaka frå ein tekststreng
0184 # og lag ein tibble med tilhøyrande info
0185 hent_unntak = function(x) {
0186 d_unntak = str_split_fixed(x, "=", 2)
0187 colnames(d_unntak) = c("LEMMA_ID", "val")
0188 as_tibble(d_unntak)
0189 }
0190
0191 # Unntaksmønstera, med éi rad for
0192 # kvart lemma som har eit unntak
0193 d_unntaksmønster = d %>%
0194 filter(!is.na(unntak)) %>%
0195 select(par_tekst, unntak) %>%
0196 mutate(
0197 unntak_liste =
0198 str_split(unntak, ",") %>%
0199 map(hent_unntak)) %>%
0200 unnest(unntak_liste) %>%
0201 mutate(LEMMA_ID = as.integer(LEMMA_ID))
0202
0203 # Sjekk at me ikkje har fleire unntak for same lemma
0204 stopifnot(!any(duplicated(d_unntaksmønster)))
0205
0206 # Sjekk at alle unntaka viser til LEMMA_ID-ar som
0207 # finst og at tilhøyrande PARADIGME_ID-ar òg finst
0208 # for den aktuelle LEMMA_ID-en
0209 unntak_feil = d_unntaksmønster %>%
0210 anti_join(d_fullform, by=c("LEMMA_ID", "val"="PARADIGME_ID"))
0211 if(nrow(unntak_feil) > 0) {
0212 stop(paste0("Minst eitt unntak viser til ugyldig lemma-ID eller paradigme-ID:\n",
0213 paste0(format(unntak_feil), collapse="\n")))
0214 }
0215
0216
0217 # Alle fullformene + info om føretrekt paradigme
0218 # for lemmaa som følgjer hovudregelen
0219 d_alle_hovudregel = d_oppdatert %>%
0220 select(par_tekst, val) %>%
0221 left_join(d_psam, by="par_tekst") %>%
0222 right_join(d_fullform, by="LEMMA_ID")
0223
0224 # Alle fullformene for unntaka + info om føretrekt paradigme
0225 d_unntak = d_unntaksmønster %>%
0226 left_join(d_fullform, by="LEMMA_ID")
0227
0228 # Alle fullformene, med unntak der det trengst +
0229 # info om føretrekt paradigme
0230 d_alle = d_alle_hovudregel %>%
0231 anti_join(d_unntak, by="LEMMA_ID") %>%
0232 bind_rows(d_unntak)
0233
0234 # Info om ei fullform er gyldig
0235 d_alle = d_alle %>%
0236 mutate(gyldig_form = (is.na(val) | PARADIGME_ID == val))
0237
0238 # Fullformene som er gyldige eller ugyldige
0239 d_gyldige = d_alle %>% filter(gyldig_form)
0240 d_ugyldige = d_alle %>% filter(!gyldig_form)
0241
0242 # Men at ei form er ugyldig er ikkje god nok
0243 # grunn til å ekskludera ho. Det kan vera det
0244 # same «ordet» òg er med blant dei gyldige
0245 # formene, anten i det utvaldet paradigmet til
0246 # lemmaet, eller for eit anna lemma (homografar).
0247 # Eksluderer derfor berre dei orda som ikkje
0248 # finst i samlinga av gyldige ord.
0249 ord_ekskluder = sort(setdiff(d_ugyldige$OPPSLAG, d_gyldige$OPPSLAG))
0250
0251 # Lagra ekskluderingsordlista
0252 write_lines(ord_ekskluder, "feil-paradigme.dat")
0253
0254 # Vis orda me *har* brukt i omsettingane men
0255 # som no vert ekskluderte …
0256 cat("Ord brukte i omsetjingane som no vert forbodne:")
0257 d_frek %>%
0258 filter(OPPSLAG %in% ord_ekskluder) %>%
0259 print(n=Inf)