get_sample.py 4.28 KB
import argparse
import os
import random
import shutil


def main():
    args = parse_arguments()
    if not args.input or not args.output:
        print('Error: Input and output must be selected!')
    get_sample(args.input, args.output)


def parse_arguments():
    parser = argparse.ArgumentParser(description='Get conllup corpora sample.')
    required_arguments = parser.add_argument_group('required arguments')
    required_arguments.add_argument('-o', '--output', help='output directory', required=True)
    required_arguments.add_argument('-i', '--input', help='corpora root directory', required=True)
    return parser.parse_args()


def get_sample(root_directory, out_corpora_directory):
    docs_by_domains = sort_docs_by_domains(root_directory)
    for domain in docs_by_domains:
        draw_sample_and_copy(docs_by_domains[domain]['abstract'], docs_by_domains[domain]['full'],
                             out_corpora_directory)


def sort_docs_by_domains(root_directory):
    docs_by_domains = {}
    for root, dirs, files in os.walk(root_directory):
        for filename in files:
            print(filename)
            if filename.endswith('.conllup') or filename.endswith('.conllu'):
                src = os.path.join(root, filename)
                domain = get_domain(src)
                sentences_count = get_sentences_count(src)
                if sentences_count > 3:
                    if domain not in docs_by_domains:
                        docs_by_domains[domain] = {'full': [], 'abstract': []}
                    if is_full_text(src):
                        docs_by_domains[domain]['full'].append({'path': src, 'sentences': sentences_count})
                    else:
                        docs_by_domains[domain]['abstract'].append({'path': src, 'sentences': sentences_count})
    return docs_by_domains


def get_domain(filepath):
    with open(filepath, 'r') as conllup_file:
        for line in conllup_file:
            line = line.strip()
            if is_segment(line):
                continue
            elif is_metadata(line):
                name, value = get_metadata(line)
                if name == 'domain':
                    return value.strip()
    return ''


def is_segment(line):
    if line and line[0].isdigit():
        return True
    return False


def is_metadata(line):
    if line.startswith('#'):
        return True
    return False


def get_metadata(line):
    name_value_pair = line.split('=', 1)
    name = name_value_pair[0].lstrip('#').strip()
    value = name_value_pair[1].strip()
    return name, value


def is_full_text(filepath):
    with open(filepath, 'r') as conllup_file:
        for line in conllup_file:
            line = line.strip()
            if is_segment(line):
                continue
            elif is_metadata(line):
                name, value = get_metadata(line)
                if name == 'content_type':
                    if value.strip() == 'full_text':
                        return True
                    else:
                        return False
    return False


def get_sentences_count(filepath):
    sentences = 0
    with open(filepath, 'r') as conllup_file:
        for line in conllup_file:
            line = line.strip()
            if is_segment(line):
                pass
            elif is_metadata(line):
                name, value = get_metadata(line)
                if name == 'sent_id':
                    sentences += 1
    return sentences


def draw_sample_and_copy(abstracts, full_texts, out_corpora_directory):
    number_of_draws = 0
    sentences_count = 0
    sentences_cap = 6500
    random.shuffle(abstracts)
    random.shuffle(full_texts)

    for abstract in abstracts:

        if sentences_count >= sentences_cap:
            break

        filename = os.path.basename(abstract['path'])
        dst = os.path.join(out_corpora_directory, filename)
        shutil.copyfile(abstract['path'], dst)
        number_of_draws += 1
        sentences_count += abstract['sentences']

        if number_of_draws % 8 == 0:
            full_text = full_texts[number_of_draws // 8]
            filename = os.path.basename(full_text['path'])
            dst = os.path.join(out_corpora_directory, filename)
            shutil.copyfile(full_text['path'], dst)
            sentences_count += full_text['sentences']


if __name__ == '__main__':
    main()