3
votes

Comment remplacer une liste de mots mal orthographiés par une liste de mots corrects?

J'essaie de trouver comment remplacer une longue liste de mots mal orthographiés d'une liste de mots corrects, mais je ne sais pas comment le faire. S'il vous plaît aviser si possible. Merci.

J'ai essayé str_replace et gsub, mais il semble que je veuille implémenter les modifications à partir d'un dataframe pour que cela ne fonctionne pas vraiment de cette façon.

df = tibble(Movie_Name = list("Black Panther", "Iron Man", "Captain America", "Black Panther", "Iron Man", "Captain America", "Avengers"))

Je m'attends à ce que la sortie soit comme ceci:

df = tibble(Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerica", "Black Panthers", "Iron Men", "Captain America", "Avangers"))

correct = tibble(correct_movie_name = list("Black Panther", "Iron Man", "Captain American", "Avengers"))


3 commentaires

Avez-vous une liste spécifique de chaînes possibles comme les titres de vos films ou s'agit-il d'un texte général?


J'ai une longue liste de mots dont certains sont mal orthographiés et je voudrais le nettoyer, alors j'ai proposé une liste de mots d'orthographe corrects et j'aimerais voir si je peux remplacer les mots mal orthographiés dans la longue liste avec celui que j'ai créé.


Vous pouvez consulter le package fuzzyjoin: github. com / dgrtwo /…


4 Réponses :


1
votes

Une solution pourrait être d'utiliser la distance de Levenshtein, qui est disponible dans le package stringdist .

library(stringdist)

MovieNames   = unlist(df$Movie_Name)
CorrectNames = unlist(correct$correct_movie_name)

for(MN in MovieNames) {
    CMN = which.min(stringdist(CorrectNames,  MN, method = "lv"))
    cat(MN, " should be ",  CorrectNames[CMN], "\n")
}

Black Panthet  should be  Black Panther 
Irom Man  should be  Iron Man 
Captain Anerica  should be  Captain American 
Black Panthers  should be  Black Panther 
Iron Men  should be  Iron Man 
Captain America  should be  Captain American 
Avangers  should be  Avengers 


0 commentaires

0
votes

Je ne pense pas qu'il existe une solution parfaite pour cela. Le mieux est de calculer une sorte de distance d'édition entre Movie_Name et correct_movie_name et de remplacer par le mot de correct_movie_name par la distance la plus petite. La métrique à utiliser dépend beaucoup de la situation et de nombreux ajustements sont nécessaires. Ici, j'ai utilisé la fonction stringdist du package stringdist qui propose une variété de mesures de distance que vous pouvez choisir. La valeur par défaut est la "distance Damerau-Levenshtein restreinte" (de ? Stringdist ). Nous pouvons également utiliser levenshsteinDist du package RecordLinkage :

# A tibble: 7 x 3
  Movie_Name      Correct_stringdist Correct_levenshsteinDist
  <chr>           <chr>              <chr>                   
1 Black Panthet   Black Panther      Black Panther           
2 Irom Man        Iron Man           Iron Man                
3 Captain Anerica Captain American   Captain American        
4 Black Panthers  Black Panther      Black Panther           
5 Iron Men        Iron Man           Iron Man                
6 Captain America Captain American   Captain American        
7 Avangers        Avengers           Avengers 

Sortie:

library(dplyr)
library(stringdist)
library(RecordLinkage)

replace_names <- function(vec, replace_list, dist_func){
  map_chr(vec, ~{
    replace_list[which.min(dist_func(.x, replace_list))]
  })
}

df %>%
  mutate(Correct_stringdist = replace_names(Movie_Name, correct$correct_movie_name, stringdist),
         Correct_levenshsteinDist = replace_names(Movie_Name, correct$correct_movie_name, levenshteinDist))


0 commentaires

0
votes

La fonction consentp vous permet de faire une correspondance approximative entre les chaînes.

df = tibble(Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerican", "Black Panthers", "Iron Men", "Captain America", "Avangers"))

correct = tibble(correct_movie_name = list("Black Panther", "Iron Man", "Captain America", "Avengers"))

df2 = tibble( Movie_Name = sapply(df$Movie_Name, function(x){
                  for(i in correct$correct_movie_name){
                    comparison <- agrep(i, x)
                    if(length(comparison) != 0){
                      if(comparison == 1){
                      return(i)
                    }}
                  }
                  return(x)
                }))


0 commentaires

0
votes

Voici une solution basée sur les réponses de @ G5W et avid_useR

library(tidyverse)
library(stringdist)

Movie_Name = list("Black Panthet", "Irom Man", "Captain Anerica", "Black Panthers", "Iron Men", "Captain America", "Avangers")

correct_movie_name = list("Black Panther", "Iron Man", "Captain America", "Avengers")

New_Movie_name <- lapply(Movie_Name, function(x) {
  lapply(correct_movie_name, function(y) {
    stringdist(x,y)
  }) %>% unlist() %>% which.min() %>% correct_movie_name[[.]]
})

# New_Movie_name is a list of the same length as Movie_Name but with correct movie names based on elements in list correct_movie_name


0 commentaires