challenging-america-word-ga.../run.py

82 lines
3.1 KiB
Python
Raw Normal View History

2022-04-04 17:54:10 +02:00
import pandas as pd
import csv
from collections import Counter, defaultdict
from nltk.tokenize import RegexpTokenizer
from nltk import trigrams
2022-04-04 18:31:33 +02:00
import regex as re
import lzma
2022-04-04 17:54:10 +02:00
class WordPred:
2022-04-04 17:54:10 +02:00
def __init__(self):
self.tokenizer = RegexpTokenizer(r"\w+")
2022-04-11 11:15:56 +02:00
self.model = defaultdict(lambda: defaultdict(lambda: 0))
self.vocab = set()
self.alpha = 0.001
2022-04-04 17:54:10 +02:00
2022-04-04 18:31:33 +02:00
def read_file(self, file):
for line in file:
text = line.split("\t")
yield re.sub(r"[^\w\d'\s]+", '', re.sub(' +', ' ', ' '.join([text[6], text[7]]).replace("\\n"," ").replace("\n","").lower()))
def read_file_7(self, file):
for line in file:
text = line.split("\t")
yield re.sub(r"[^\w\d'\s]+", '', re.sub(' +', ' ', text[7].replace("\\n"," ").replace("\n","").lower()))
2022-04-04 18:31:33 +02:00
def read_train_data(self, file_path):
with lzma.open(file_path, mode='rt') as file:
for index, text in enumerate(self.read_file(file)):
2022-04-04 17:54:10 +02:00
tokens = self.tokenizer.tokenize(text)
2022-04-04 18:31:33 +02:00
for w1, w2, w3 in trigrams(tokens, pad_right=True, pad_left=True):
if w1 and w2 and w3:
self.model[(w2, w3)][w1] += 1
2022-04-11 11:15:56 +02:00
self.vocab.add(w1)
self.vocab.add(w2)
self.vocab.add(w3)
if index == 300000:
2022-04-04 18:31:33 +02:00
break
for word_pair in self.model:
num_n_grams = float(sum(self.model[word_pair].values()))
for word in self.model[word_pair]:
2022-04-11 11:15:56 +02:00
self.model[word_pair][word] = (self.model[word_pair][word] + self.alpha) / (num_n_grams + self.alpha*len(self.vocab))
2022-04-04 18:31:33 +02:00
def generate_outputs(self, input_file, output_file):
with open(output_file, 'w') as outputf:
with lzma.open(input_file, mode='rt') as file:
for index, text in enumerate(self.read_file_7(file)):
tokens = self.tokenizer.tokenize(text)
if len(tokens) < 4:
prediction = 'the:0.2 be:0.2 to:0.2 of:0.1 and:0.1 a:0.1 :0.1'
else:
2022-04-04 18:43:08 +02:00
prediction = wp.predict_probs(tokens[0], tokens[1])
2022-04-04 18:31:33 +02:00
outputf.write(prediction + '\n')
2022-04-03 22:59:04 +02:00
2022-04-04 17:54:10 +02:00
def predict_probs(self, word1, word2):
predictions = dict(self.model[word1, word2])
most_common = dict(Counter(predictions).most_common(6))
total_prob = 0.0
str_prediction = ''
2022-04-03 22:59:04 +02:00
2022-04-04 17:54:10 +02:00
for word, prob in most_common.items():
total_prob += prob
str_prediction += f'{word}:{prob} '
2022-04-04 17:54:10 +02:00
if total_prob == 0.0:
return 'the:0.2 be:0.2 to:0.2 of:0.1 and:0.1 a:0.1 :0.1'
2022-04-04 17:54:10 +02:00
if 1 - total_prob >= 0.01:
str_prediction += f":{1-total_prob}"
else:
str_prediction += f":0.01"
return str_prediction
2022-04-04 18:43:08 +02:00
wp = WordPred()
wp.read_train_data('train/in.tsv.xz')
wp.generate_outputs('dev-0/in.tsv.xz', 'dev-0/out.tsv')
2022-04-11 11:15:56 +02:00
wp.generate_outputs('test-A/in.tsv.xz', 'test-A/out.tsv')