import pandas as pd
import numpy as np
import warnings

warnings.filterwarnings('ignore')

train_df = pd.read_csv("data/preprocessed/train_new.csv", index_col=None)
dev_df = pd.read_csv("data/preprocessed/dev_new.csv", index_col=None)
print(len(train_df), len(dev_df))

train_df = train_df.dropna()
dev_df = dev_df.dropna()

print(len(train_df), len(dev_df))
train_df.info()

train_df['Text'] == train_df['Text'].astype(str)
dev_df['Text'] == dev_df['Text'].astype(str)

train_df.head()

from sklearn.feature_extraction.text import TfidfVectorizer

def whitespace_tokenizer(text: str):
    return text.split()


train_texts = train_df['Text']
train_labels = train_df['Target']

dev_texts = dev_df['Text']
dev_labels = dev_df['Target']

# get tf-idf vectors
tfidf_vectorizer = TfidfVectorizer(tokenizer=whitespace_tokenizer)
train_tfidf = tfidf_vectorizer.fit_transform(train_texts)
dev_tfidf = tfidf_vectorizer.transform(dev_texts)

from sklearn.svm import LinearSVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier

from sklearn.metrics import accuracy_score

for c in [0.001, 0.01, 0.1, 1, 10, 100, 1000]:
    lsvc = LinearSVC(C=c)
    lsvc.fit(train_tfidf, train_labels)
    preds = lsvc.predict(dev_tfidf)
    print(f"C={c:6}, acc: {accuracy_score(dev_labels, preds):.3f}")

for c in [0.001, 0.01, 0.1, 1, 10, 100, 1000]:
    lr = LogisticRegression(C=c)
    lr.fit(train_tfidf, train_labels)
    preds = lr.predict(dev_tfidf)
    print(f"C={c:6}, acc: {accuracy_score(dev_labels, preds):.3f}")

for a in [0.001, 0.01, 0.1, 1, 10, 100, 1000]:
    nb = MultinomialNB(alpha=a)
    nb.fit(train_tfidf, train_labels)
    preds = nb.predict(dev_tfidf)
    print(f"alpha={a: 6}, acc: {accuracy_score(dev_labels, preds):.3f}")

for n_neighbors in range(1, 10):
    for weights in ['uniform', 'distance']:
        knn = KNeighborsClassifier(n_neighbors=n_neighbors)
        knn.fit(train_tfidf, train_labels)
        preds = knn.predict(dev_tfidf)
        print(f"n_neighbors={n_neighbors: 2}, weights={weights:9}, acc: {accuracy_score(dev_labels, preds):.3f}")