Ustvarjanje podatkov o pregledu filmov IMDB za teste NLP – revija Visual Studio

Laboratorij za znanost o podatkih

IMDB pripravlja podatke o pregledu filmov za NLP poskuse

Dr. Microsoft Research. James McCaffrey prikazuje, kako pridobiti izvirne podatke IMDB, si zapomniti recenzije filmov, razčleniti preglede in tokenizirati, ustvariti slovarski slovar in pretvoriti ocene v številski format.

Najpogostejša zbirka podatkov za teste obdelave naravnega jezika (NLP) so podatki o pregledu filmov IMDB. Cilj problema baze podatkov IMDB je predvideti, ali bo filmski pregled imel pozitivno (“To je odličen film”) ali negativno konotacijo (“Film je bil izguba časa”). Ustvarjanje podatkov je velik izziv pri delu z bazo podatkov IMDB.

V tem članku je razloženo, kako pridobiti izvorne podatke IMDB, prebrati filmske recenzije v pomnilniku, analizirati in označiti recenzije, ustvariti besedni slovar in pretvoriti ocene v številski format, primeren za uporabo v sistemu, kot je globoka nevronska mreža. , Ali omrežje LSDM ali omrežje transformatorske arhitekture.

Najbolj priljubljene knjižnice nevronskih omrežij, vključno s PyTorch, scikit in Keras, imajo nekakšno vgrajeno bazo podatkov IMDB, zasnovano za delo s knjižnico. Toda pri uporabi vgrajene baze podatkov sta dve težavi. Prvič, dostop do podatkov postane čarobna črna skrinjica in pomembne informacije so skrite. Drugič, vgrajena baza podatkov uporablja vseh 25.000 treningov in 25.000 pregledov testnih filmov, s katerimi je težko delati, ker so tako veliki.

Slika 1: Pretvarjanje podatkov pregleda izvornih IMDB v ID-je žetonov
[Click on image for larger view.] Slika 1: Pretvori izvorne podatke pregleda IMDB v ID-je žetonov

Odličen način, da vidite, kam gre ta članek, je, da naredite posnetek zaslona jezikovnega programa Python. Slika 1. Izvorne ocene filmov IMDB so shranjene kot besedilne datoteke, po en pregled na datoteko. Program se začne tako, da v pomnilnik naloži 50.000 filmskih ocen in nato vsako recenzijo razvrsti v besede/žetone. Besede/žetoni se uporabljajo za ustvarjanje slovarja besedišča, ki preslika vsako besedo/žeton v celoštevilski ID. Na primer, beseda “the” je bila spremenjena v ID = 4.

Zbirka besedišča se uporablja za pretvorbo filmskih pregledov z 20 ali manj besedami v ID-je žetonov. Mnenja z manj kot 20 besedami/žetoni so obložena na točno 20 dolžin s predstavitvijo edinstvenega ID-ja oblazinjenja 0.

Ocene filmov s pozitivnimi čustvi, kot je “To je dober film”, dobijo oznako 1 kot zadnjo vrednost, negativne ocene pa 0. Rezultat je bilo 16 filmskih ocen za usposabljanje in 17 ocen za testiranje. V primerih, ki niso demo, boste dovolili daljše preglede, na primer do 80 besed, s čimer boste pridobili več pregledov prakse in testov.

Ta članek predvideva, da imate vmesno ali bolje znanje programskega jezika družine C, po možnosti Python, vendar ne domnevajte, da veste kaj o bazi podatkov IMDB. Celotna izvorna koda za demo program je na voljo v tem članku, koda pa je na voljo tudi v priloženi datoteki za prenos.

Pridobivanje izvornih podatkovnih datotek
Podatki o pregledu filmov IMDB vsebujejo 50.000 pregledov – 25.000 za usposabljanje in 25.000 za testiranje. Datoteke za usposabljanje in preizkuse so razdeljene na 12.500 pozitivnih ocen in 12.500 negativnih ocen. Negativne ocene so ocene, povezane s filmi, ki jih je recenzent ocenil z oceno od 1 do 4. Pozitivne ocene so ocenjene s 7 do 10 zvezdicami. Ocene filmov, ki dobijo 5 ali 6 zvezdic, se ne štejejo za pozitivne ali negativne in se ne uporabljajo.

The Odlična zbirka filmskih pregledov Izvorni IMDB je primarno skladišče za podatke o pregledih filmov, vendar ga lahko najdete tudi drugje z internetnim iskanjem. Če kliknete povezavo na spletni strani, boste prenesli 80 MB datoteko v formatu tar-GNU-zip z imenom aclImdb_v1.tar.gz.

Za razliko od običajnih stisnjenih datotek .zip Windows ne more ekstrahirati datotek tar.gz, zato morate uporabiti aplikacijo. priporočam brezplačno Aplikacija 7-zip. Po namestitvi 7-Zip lahko odprete Windows File Explorer in nato z desno tipko miške kliknete datoteko aclImdb_v1.tar.gz in izberete možnost Extract Here. Nastala datoteka velikosti 284 MB se bo imenovala aclImdb_v1.tar (“Tračni arhiv”). Če z desno miškino tipko kliknete to datoteko tar in izberete možnost Extract Here, boste dobili neimenovani korenski imenik velikosti aclimdb približno 300 MB.

Korenski imenik aclimdb vsebuje podimenike z oznako test in train ter tri datoteke, ki jih lahko preglasite. Imeniki test in train vsebujejo podimenike z oznako neg in pos, in lahko preglasite pet datotek in en imenik z oznako unup (50.000 neimenovanih pregledov za nenadzorovano analizo). Imenika neg in pos vsebujeta po 12.500 besedilnih datotek, pri čemer je vsak pregled datoteka.

50.000 imen datotek izgleda kot 102_4.txt, prvi del imena datoteke [0] Narediti [12499] Drugi del pregledne tabele in imena datoteke je številčna ocena ocene (od 0 do 4 za negativne ocene in od 7 do 10 za pozitivne ocene).

Slika 2: Prvi pregled pozitivnega usposabljanja nabora podatkov IMDB
[Click on image for larger view.] Slika 2: Prva pozitivna ocena usposabljanja iz baze podatkov IMDB

Posnetek zaslona Slika 2 Prikaže strukturo imenika podatkov o pregledu filma IMDB. Vsebina prvega Positive Training Training Review (datoteka 0.9.txt) bo prikazana na beležnici.

Ustvarjanje datotek vlakov in testov za preglede IMDB
Celoten načrt izdelave podatkov make_data_files.py je na voljo z nekaj manjšimi spremembami za prihranek prostora. Seznam 1. Program sprejme 50.000 datotek za pregled filmov kot vhod in ustvari datoteko vadnice in testno datoteko.

Program ima tri pomožne funkcije, ki opravijo vse delo:

get_reviews(dir_path, max_reviews)
make_vocab(all_reviews)
generate_file(reviews_lists, outpt_file, w_or_a, 
  vocab_dict, max_review_len, label_char)

Funkcija get_reviews () prebere vse datoteke v imeniku, označi preglede in upodablja seznam. [[“a”, “great”, “movie”], [“i”, “liked”, “it”, “a”, “lot”],. . [“terrific”, “film”]]. Funkcija make_vocab () sprejme seznam žetoniziranih pregledov in ustvari zbirko slovarjev, kjer so ključi tokenizirane besede, kot je “film”, vrednosti pa so 27 kot cela števila. V besedilno datoteko so zapisani tudi slovarski pari ključ/vrednost. Imenuje se vocab_file.txt, tako da jih lahko sistem NLP uporablja pozneje.

Funkcija Generate_file () sprejme rezultate get_reviews () in make_vocab () ter ustvari vadnico ali testno datoteko. Logika krmiljenja programa ima funkcijo ključa (), ki se začne z:

def main():
  print("Loading all reviews into memory - be patient ")
  pos_train_reviews = get_reviews(".\\aclImdb\\train\\pos", 12500)
  neg_train_reviews = get_reviews(".\\aclImdb\\train\\neg", 12500)
  pos_test_reviews = get_reviews(".\\aclImdb\\test\\pos", 12500)
  neg_test_reviews = get_reviews(".\\aclImdb\\test\\neg", 12500)
. . .

Nato slovar besedišča, ustvarjen iz podatkov o usposabljanju:

  vocab_dict = make_vocab([pos_train_reviews, 
    neg_train_reviews])  # key = word, value = word rank
  v_len = len(vocab_dict)  
  # need this plus 4, for Embedding: 129888+4 = 129892

Za demo je na voljo 129.888 edinstvenih besed/žetonov. To je ogromno, saj poleg običajnih angleških besed, kot sta “movie” in “excellent”, obstaja na tisoče besed za posebne filmske kritike, kot sta “Hitchcock” (režiser) in “DiCaprio” (igralec). )

Besedišče temelji na pogostosti besed, kjer je ID = 4 najpogostejša beseda (“the”), ID = 5 je druga najpogostejša beseda (“in”) in tako naprej. To vam omogoča filtriranje redkih besed, ki se pojavijo samo enkrat ali dvakrat.

ID-ji besedišča za posebne žetone so 0, 1, 2 in 3. ID = 0 Za oblazinjenje. ID = 1 Označuje začetek vrstice. ID = 2 za besede brez besedišča Je. ID = 3 je dodeljen, vendar se ne uporablja. Skupno število žetonov v besednjaku je 129.888 + 4 = 129.892. Ta številka je potrebna za plast za vdelavo pri ustvarjanju sistema napovedi NLP.

Demo program ustvari datoteko z vadnico, ki vsebuje recenzije filmov z 20 ali manj besedami s temi tremi izjavami:

  max_review_len = 20  # exact fixed length
  generate_file(pos_train_reviews, ".\\imdb_train_20w.txt", 
    "w", vocab_dict, max_review_len, "1")
  generate_file(neg_train_reviews, ".\\imdb_train_20w.txt",
    "a", vocab_dict, max_review_len, "0")

Prvi klic gene_file () uporablja argument “w”, ki ustvari ciljno datoteko za pisanje pozitivnih ocen. Drugi klic uporablja argument “a” za dodajanje negativnih ocen. Možno je uporabiti način “a +”, vendar sta ločena načina “w” in “a” po mojem mnenju zelo jasna.

Testna datoteka je bila ustvarjena podobno:

  generate_file(pos_test_reviews, ".\\imdb_test_20w.txt", 
    "w", vocab_dict, max_review_len, "1")
  generate_file(neg_test_reviews, ".\\imdb_test_20w.txt", 
    "a", vocab_dict, max_review_len, "0")

Pregledovanje datoteke predstavitvene vadnice:

  f = open(".\\imdb_train_20w.txt", "r", encoding="utf8")
  for line in f: 
    print(line, end="")
  f.close()

Slovar besedišča sprejema besedo/žeton, kot je “film”, in dodeli ID 87. Demo sprejme ID, upošteva štiri posebne žetone in ustvari objekt inverznega besednjaka, imenovan index_to_word, ki zagotavlja ustrezno besedo/žeton:

  index_to_word = {}
  index_to_word[0] = "<PAD>"
  index_to_word[1] = "<ST>"
  index_to_word[2] = "<OOV>"
  for (k,v) in vocab_dict.items():
    index_to_word[v+3] = k

Demo program se zaključi s spremenjenim obratnim slovarjem za dekodiranje in prikaz vadnice:

  f = open(".\\imdb_train_20w.txt", "r", encoding="utf8")
  for line in f:
    line = line.strip()
    indexes = line.split(" ")
    for i in range(len(indexes)-1):  # last is '0' or '1'
      idx = (int)(indexes[i])
      w = index_to_word[idx]
      print("%s " % w, end="")
    print("%s " % indexes[len(indexes)-1])
  f.close()

Standardnega programa za zbiranje besedišča NLP ni, kar je še ena težava pri uporabi vgrajenih baz podatkov IMDB iz PyTorch in Keras. Poleg tega je zbirka besedišča v celoti odvisna od tega, kako so izvorni podatki žetonizirani. To pomeni, da morate vedno tokenizirati podatke NLP in hkrati ustvariti ustrezen besednjak.

Seznam 1: Načrtujte ustvarjanje vlakovnih in testnih datotek za pregled filmov IMDB

# make_data_files.py
#
# input: source Stanford 50,000 data files reviews
# output: one combined train file, one combined test file
# output files are in index version, using the Keras dataset
# format where 0 = padding, 1 = 'start', 2 = OOV, 3 = unused
# 4 = most frequent word ('the'), 5 = next most frequent, etc.

import os
# allow the Windws cmd shell to deal with wacky characters
import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout.buffer)

# ---------------------------------------------------------------

def get_reviews(dir_path, max_reviews):
  remove_chars = "!\"#$%&()*+,-./:;<=>[email protected][\\]^_`{|}~" 
  # leave ' for words like it's 
  punc_table = {ord(char): None for char in remove_chars}  # dict
  reviews = []  # list-of-lists of words
  ctr = 1
  for file in os.listdir(dir_path):
    if ctr > max_reviews: break
    curr_file = os.path.join(dir_path, file)
    f = open(curr_file, "r", encoding="utf8")  # one line
    for line in f:
      line = line.strip()
      if len(line) > 0:  # number characters
        # print(line)  # to show non-ASCII == errors
        line = line.translate(punc_table)  # remove punc
        line = line.lower()  # lower case
        line = " ".join(line.split())  # remove consecutive WS
        word_list = line.split(" ")  # list of words
        reviews.append(word_list)
    f.close()  # close curr file
    ctr += 1
  return reviews

# ---------------------------------------------------------------

def make_vocab(all_reviews):
  word_freq_dict = {}   # key = word, value = frequency

  for i in range(len(all_reviews)):
    reviews = all_reviews[i]
    for review in reviews:
      for word in review:
        if word in word_freq_dict:
          word_freq_dict[word] += 1
        else:
          word_freq_dict[word] = 1

  kv_list = []  # list of word-freq tuples so can sort
  for (k,v) in word_freq_dict.items():
    kv_list.append((k,v))

  # list of tuples index is 0-based rank, val is (word,freq)
  sorted_kv_list = \
    sorted(kv_list, key=lambda x: x[1], \
      reverse=True)  # sort by freq

  f = open(".\\vocab_file.txt", "w", encoding="utf8")
  vocab_dict = {}  
  # key = word, value = 1-based rank 
  # ('the' = 1, 'a' = 2, etc.)
  for i in range(len(sorted_kv_list)):  # filter here . . 
    w = sorted_kv_list[i][0]  # word is at [0]
    vocab_dict[w] = i+1       # 1-based as in Keras dataset

    f.write(w + " " + str(i+1) + "\n")  # save word-space-index
  f.close()

  return vocab_dict

# ---------------------------------------------------------------

def generate_file(reviews_lists, outpt_file, w_or_a, 
  vocab_dict, max_review_len, label_char):

  # write first time, append later. could use "a+" mode instead.
  fout = open(outpt_file, w_or_a, encoding="utf8")  
  offset = 3  # Keras offset: 'the' = 1 (most frequent) 1+3 = 4
      
  for i in range(len(reviews_lists)):  # walk each review-list
    curr_review = reviews_lists[i]
    n_words = len(curr_review)     
    if n_words > max_review_len:
      continue  # next i, continue without writing anything

    n_pad = max_review_len - n_words   # number 0s to prepend

    for j in range(n_pad):
      fout.write("0 ")
    
    for word in curr_review: 
      # a word in test set might not have been in train set     
      if word not in vocab_dict:  
        fout.write("2 ")   # out-of-vocab index        
      else:
        idx = vocab_dict[word] + offset
        fout.write("%d " % idx)
    
    fout.write(label_char + "\n")  # '0' or '1
        
  fout.close()

# ---------------------------------------------------------------          

def main():
  print("Loading all reviews into memory - be patient ")
  pos_train_reviews = get_reviews(".\\aclImdb\\train\\pos", 12500)
  neg_train_reviews = get_reviews(".\\aclImdb\\train\\neg", 12500)
  pos_test_reviews = get_reviews(".\\aclImdb\\test\\pos", 12500)
  neg_test_reviews = get_reviews(".\\aclImdb\\test\\neg", 12500)

  # mp = max(len(l) for l in pos_train_reviews)  # 2469
  # mn = max(len(l) for l in neg_train_reviews)  # 1520
  # mm = max(mp, mn)  # longest review is 2469
  # print(mp, mn)

# ---------------------------------------------------------------  

  print("Analyzing reviews and making vocabulary ")
  vocab_dict = make_vocab([pos_train_reviews, 
    neg_train_reviews])  # key = word, value = word rank
  v_len = len(vocab_dict)  
  # need this value, plus 4, for Embedding: 129888+4 = 129892
  print("Vocab size = %d -- use this +4 for \
    Embedding nw " % v_len)

  max_review_len = 20  # exact fixed length
  # if max_review_len == None or max_review_len > mm:
  #   max_review_len = mm

  print("Generating training file len %d words or less " \
    % max_review_len)

  generate_file(pos_train_reviews, ".\\imdb_train_20w.txt", 
    "w", vocab_dict, max_review_len, "1")
  generate_file(neg_train_reviews, ".\\imdb_train_20w.txt",
    "a", vocab_dict, max_review_len, "0")

  print("Generating test file with len %d words or less " \
    % max_review_len)

  generate_file(pos_test_reviews, ".\\imdb_test_20w.txt", 
    "w", vocab_dict, max_review_len, "1")
  generate_file(neg_test_reviews, ".\\imdb_test_20w.txt", 
    "a", vocab_dict, max_review_len, "0")

  # inspect a generated file
  # vocab_dict was used indirectly (offset)

  print("Displaying encoded training file: \n")
  f = open(".\\imdb_train_20w.txt", "r", encoding="utf8")
  for line in f: 
    print(line, end="")
  f.close()

# ---------------------------------------------------------------  

  print("Displaying decoded training file: ") 

  index_to_word = {}
  index_to_word[0] = "<PAD>"
  index_to_word[1] = "<ST>"
  index_to_word[2] = "<OOV>"
  for (k,v) in vocab_dict.items():
    index_to_word[v+3] = k

  f = open(".\\imdb_train_20w.txt", "r", encoding="utf8")
  for line in f:
    line = line.strip()
    indexes = line.split(" ")
    for i in range(len(indexes)-1):  # last is '0' or '1'
      idx = (int)(indexes[i])
      w = index_to_word[idx]
      print("%s " % w, end="")
    print("%s " % indexes[len(indexes)-1])
  f.close()

if __name__ == "__main__":
  main()

READ  WHIO TV 7 in WHIO Radio - Shiffrinova ima še vedno veliko priložnosti, da preseže Vonnov rekord.

Marko Andrej

“Zombi fanatik. Nagrajeni ljubitelj potovanj. Navdušen glasbeni kreten. Spletni strokovnjak za internet. "

Related Posts

Dodaj odgovor

Vaš e-naslov ne bo objavljen. * označuje zahtevana polja

Read also x