Spaces:
Build error
Build error
""" | |
Learn to classify the manually annotated CDA attributes (frames, 'riferimento', orientation) | |
""" | |
GLOVE_MODEL = "/net/aistaff/gminnema/thesis_data/data/glove-it/glove_WIKI" | |
from sklearn.svm import SVC | |
from sklearn.feature_extraction.text import CountVectorizer | |
from sklearn.metrics import precision_recall_fscore_support | |
import gensim | |
import pandas as pd | |
import spacy | |
import json | |
def train(attrib): | |
assert attrib in ["cda_frame", "riferimento", "orientation"] | |
# load data | |
print("Loading data...") | |
x_train, y_train, x_dev, y_dev = load_data(attrib) | |
print(f"\t\ttrain size: {len(x_train)}") | |
print(f"\t\tdev size: {len(x_dev)}") | |
# try different setups | |
print("Running training setups...") | |
scores = [] | |
setups = [ | |
# defaults: remove_punct=True, lowercase=True, lemmatize=False, remove_stop=False | |
# ({}, {}, SVC(kernel='linear')), | |
# ({"lemmatize": True, "remove_stop": True}, {}, SVC(kernel='linear')), | |
# ({"lemmatize": True, "remove_stop": True}, {"min_freq": 5}, SVC(kernel='linear')), | |
# ({"lemmatize": True, "remove_stop": True}, {"min_freq": 5, "max_freq": .70}, SVC(kernel='linear')), | |
# ({"lemmatize": True, "remove_stop": True}, {}, SVC(kernel='linear', C=0.6)), | |
# ({"lemmatize": True, "remove_stop": True}, {}, SVC(kernel='linear', C=0.7)), | |
# ({"lemmatize": True, "remove_stop": True}, {}, SVC(kernel='linear', C=0.8)), | |
({"lemmatize": True, "remove_stop": True}, {"embed": "glove"}, SVC(kernel='linear', C=0.8)), | |
# ({"lemmatize": True, "remove_stop": True}, {}, SVC(kernel="rbf")), | |
] | |
nlp = spacy.load("it_core_news_md") | |
for s_idx, (text_options, vect_options, model) in enumerate(setups): | |
print(f"\tSetup #{s_idx}") | |
# extract features | |
print("\t\tExtracting features...") | |
x_train_fts, vectorizer = extract_features(x_train, nlp, text_options, **vect_options) | |
x_dev_fts, _ = extract_features(x_dev, nlp, text_options, **vect_options, vectorizer=vectorizer) | |
print(f"\t\t\tnum features: {len(vectorizer.vocabulary_)}") | |
print("\t\tTraining the model...") | |
model.fit(x_train_fts, y_train) | |
# evaluate on dev | |
print("\t\tValidating the model...") | |
y_dev_pred = model.predict(x_dev_fts) | |
p_micro, r_micro, f_micro, _ = precision_recall_fscore_support( | |
y_dev, y_dev_pred, average="micro") | |
p_classes, r_classes, f_classes, _ = precision_recall_fscore_support( | |
y_dev, y_dev_pred, average=None, labels=model.classes_, zero_division=0) | |
print( | |
f"\t\t\tOverall scores (micro-averaged):\tP={p_micro}\tR={r_micro}\tF={f_micro}" | |
) | |
scores.append({ | |
"micro": { | |
"p": p_micro, | |
"r": r_micro, | |
"f": f_micro | |
}, | |
"classes": { | |
"p": list(zip(model.classes_, p_classes)), | |
"r": list(zip(model.classes_, r_classes)), | |
"f": list(zip(model.classes_, f_classes)), | |
} | |
}) | |
prediction_df = pd.DataFrame(zip(x_dev, y_dev, y_dev_pred), columns=["headline", "gold", "prediction"]) | |
prediction_df.to_csv(f"output/migration/cda_classify/predictions_{s_idx:02}.csv") | |
with open("output/migration/cda_classify/scores.json", "w", encoding="utf-8") as f_scores: | |
json.dump(scores, f_scores, indent=4) | |
def load_data(attrib): | |
train_data = pd.read_csv( | |
"output/migration/preprocess/annotations_train.csv") | |
dev_data = pd.read_csv("output/migration/preprocess/annotations_dev.csv") | |
x_train = train_data["Titolo"] | |
x_dev = dev_data["Titolo"] | |
if attrib == "cda_frame": | |
y_train = train_data["frame"] | |
y_dev = dev_data["frame"] | |
elif attrib == "riferimento": | |
y_train = train_data["riferimento"] | |
y_dev = dev_data["riferimento"] | |
else: | |
x_train = train_data["orientation"] | |
y_dev = dev_data["orientation"] | |
return x_train, y_train, x_dev, y_dev | |
def extract_features(headlines, nlp, text_options, min_freq=1, max_freq=1.0, embed=None, vectorizer=None): | |
tokenized = [" ".join(sent) for sent in tokenize(headlines, nlp, **text_options)] | |
if vectorizer is None: | |
if embed is None: | |
vectorizer = CountVectorizer(lowercase=False, analyzer="word", min_df=min_freq, max_df=max_freq) | |
vectorized = vectorizer.fit_transform(tokenized) | |
else: | |
vectorizer = gensim.models. | |
else: | |
vectorized = vectorizer.transform(tokenized) | |
return vectorized, vectorizer | |
def tokenize(headlines, nlp, remove_punct=True, lowercase=True, lemmatize=False, remove_stop=False): | |
for sent in headlines: | |
doc = nlp(sent) | |
tokens = ( | |
t.lemma_ if lemmatize else t.text | |
for t in doc | |
if (not remove_stop or not t.is_stop) and (not remove_punct or t.pos_ not in ["PUNCT", "SYM", "X"]) | |
) | |
if lowercase: | |
tokens = [t.lower() for t in tokens] | |
else: | |
tokens = [t for t in tokens] | |
yield tokens | |
if __name__ == '__main__': | |
train(attrib="cda_frame") | |