omaradly's picture
Upload folder using huggingface_hub
018abf3 verified
Raw
History Blame Contribute Delete
3.71 kB
from pathlib import Path
import pandas as pd
import joblib
from sklearn.model_selection import train_test_split
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, ConfusionMatrixDisplay
import matplotlib.pyplot as plt
BASE_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = BASE_DIR.parent
dataset_path = PROJECT_ROOT / "data" / "processed" / "final_cleaned.csv"
model_metric_test_path = PROJECT_ROOT / "model_tests"
models_dir = PROJECT_ROOT / "models"
model_metric_test_path.mkdir(parents=True, exist_ok=True)
models_dir.mkdir(parents=True, exist_ok=True)
if not dataset_path.exists():
raise FileNotFoundError("Dataset not found.")
df = pd.read_csv(dataset_path)
df["total_text"] = (
df["summary"].fillna("").astype(str)
+ " "
+ df["description"].fillna("").astype(str)
)
categorical_features = [
"priority_name",
"issuetype_name",
"project_key",
"project_category_name",
"created_year",
"created_month",
]
numeric_features = [
"summary_char_count",
"summary_word_count",
"description_char_count",
"description_word_count",
"has_description",
"labels_count",
"has_assignee",
"votes_votes",
"watches_watch_count",
]
target_col = "duration_category"
# X -> Independent Variables (all except duration_category), y -> Dependent Variable (duration_category)
x = df[["total_text"] + numeric_features + categorical_features]
y = df[target_col]
# Split data
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42, stratify=y)
# Preprocessing pipeline
preprocessor = ColumnTransformer(
transformers=[
(
"text",
TfidfVectorizer(
max_features=10000,
stop_words="english",
ngram_range=(1, 2),
min_df=5,
max_df=0.9,
sublinear_tf=True,
),
"total_text",
),
(
"cat",
OneHotEncoder(handle_unknown="ignore"),
categorical_features,
),
(
"num",
Pipeline(
steps=[
("imputer", SimpleImputer(strategy="median")),
("scaler", StandardScaler()),
]
),
numeric_features,
),
]
)
# Model pipeline
model = Pipeline(
steps=[
("preprocessor", preprocessor),
(
"classifier",
LogisticRegression(
C=1.0,
solver="saga",
penalty="l2",
max_iter=1200,
class_weight=None,
n_jobs=-1,
random_state=42,
)
),
]
)
# Train
model.fit(x_train, y_train)
# Evaluate
y_pred = model.predict(x_test)
report = classification_report(y_test, y_pred)
print(report)
with open(model_metric_test_path / "classification_report.txt", "w", encoding="utf-8") as f:
f.write(report)
ConfusionMatrixDisplay.from_predictions(y_test, y_pred, xticks_rotation=45)
plt.title("Confusion Matrix")
plt.tight_layout()
plt.savefig(model_metric_test_path / "confusion_matrix.png", dpi=300)
plt.close()
# Save model
joblib.dump(model, models_dir / "duration_logistic_regression_classifier.joblib", compress=3)
print("Model saved.")