129 lines
6.4 KiB
Python
129 lines
6.4 KiB
Python
"""
|
|
TF-IDF Feature Extraction Module
|
|
Mengubah teks (posisi pekerjaan, instansi, kompetensi) menjadi representasi numerik menggunakan algoritma TF-IDF (Term Frequency - Inverse Document Frequency).
|
|
Nilai bobot TF-IDF merefleksikan seberapa penting suatu kata dalam suatu dokumen relatif terhadap keseluruhan korpus data tracer study.
|
|
"""
|
|
|
|
# Mengimpor modul Any untuk type hint fleksibel
|
|
from typing import Any
|
|
# Mengimpor class TfidfVectorizer dari scikit-learn untuk proses tokenisasi, penghitungan frekuensi kata, dan pembobotan inverse document frequency
|
|
from sklearn.feature_extraction.text import TfidfVectorizer
|
|
# Mengimpor pustaka numpy untuk operasi numerik array
|
|
import numpy as np
|
|
|
|
|
|
# Mendefinisikan class TfidfExtractor sebagai wrapper class untuk memudahkan penggunaan TF-IDF dalam pipeline klastering
|
|
class TfidfExtractor:
|
|
"""TF-IDF Vectorizer wrapper untuk keperluan ekstraksi fitur pemodelan clustering"""
|
|
|
|
# Konstruktor kelas untuk menginisialisasi parameter vektorisasi teks
|
|
def __init__(self, max_features: int = 500, ngram_range: tuple = (1, 1), min_df: int = 1, max_df: float = 1.0, **kwargs):
|
|
"""
|
|
Inisialisasi hyperparameter pembobotan TF-IDF:
|
|
Args:
|
|
max_features: Jumlah batas kosakata teratas yang akan diikutsertakan sebagai kolom fitur (default: 500 kata paling relevan)
|
|
ngram_range: Rentang kombinasi kata, (1, 1) berarti unigram (satu kata per fitur)
|
|
min_df: Batas minimum kemunculan kata dalam dokumen agar tidak diabaikan (mengeliminasi kata typo/sangat langka)
|
|
max_df: Batas maksimum proporsi dokumen yang memuat kata agar tidak diabaikan (mengeliminasi stopword umum)
|
|
**kwargs: Parameter opsional tambahan yang diteruskan langsung ke TfidfVectorizer Scikit-Learn
|
|
"""
|
|
# Menginstansiasi objek TfidfVectorizer dari Scikit-Learn dengan konfigurasi yang diberikan
|
|
self.vectorizer = TfidfVectorizer(
|
|
max_features=max_features,
|
|
ngram_range=ngram_range,
|
|
min_df=min_df,
|
|
max_df=max_df,
|
|
**kwargs
|
|
)
|
|
# Menyiapkan variabel untuk menampung matriks fitur numerik hasil transformasi (default None)
|
|
self.feature_matrix = None
|
|
|
|
|
|
# Metode fit_transform: Melakukan fitting vocabulary sekaligus mengubah kumpulan dokumen teks menjadi matriks numerik
|
|
def fit_transform(self, texts: list) -> Any:
|
|
"""
|
|
Mempelajari kosakata (vocabulary) dari kumpulan teks masukan dan mentransformasikannya menjadi feature matrix sparse.
|
|
|
|
Args:
|
|
texts: List berisi kumpulan teks string yang sudah dibersihkan (preprocessed text)
|
|
|
|
Returns:
|
|
Matriks numerik berbobot TF-IDF berformat scipy sparse matrix
|
|
"""
|
|
# Melatih vectorizer dengan korpus data teks masukan sekaligus menghitung nilai TF-IDF untuk setiap dokumen
|
|
self.feature_matrix = self.vectorizer.fit_transform(texts)
|
|
# Mengembalikan matriks fitur numerik berbobot TF-IDF
|
|
return self.feature_matrix
|
|
|
|
# Metode transform: Mengubah teks dokumen baru menjadi representasi numerik menggunakan kosakata yang sudah dipelajari sebelumnya
|
|
def transform(self, texts: list) -> Any:
|
|
"""
|
|
Mentransformasikan teks baru menggunakan model TF-IDF vectorizer yang sudah dilatih (tanpa mengubah vocabulary).
|
|
|
|
Args:
|
|
texts: List dokumen teks baru yang ingin ditransformasi
|
|
|
|
Returns:
|
|
Matriks numerik berbobot TF-IDF sesuai dengan dimensi kosakata model
|
|
"""
|
|
# Mentransformasi teks masukan baru menggunakan kamus kata dan bobot IDF yang telah terbentuk
|
|
return self.vectorizer.transform(texts)
|
|
|
|
# Metode untuk mengambil seluruh daftar nama kata unik (fitur) yang terpilih sebagai kolom pada matriks
|
|
def get_feature_names(self) -> list:
|
|
"""Mendapatkan daftar nama fitur kata unik (vocabulary features) yang digunakan model"""
|
|
# Mengembalikan nama-nama fitur kata dalam bentuk list Python
|
|
return self.vectorizer.get_feature_names_out().tolist()
|
|
|
|
# Metode untuk mengetahui jumlah total kosakata unik yang dipelajari oleh model
|
|
def get_vocab_size(self) -> int:
|
|
"""Mendapatkan total jumlah kosakata unik (vocabulary size) yang terdaftar"""
|
|
# Mengembalikan panjang (banyaknya entri) dictionary vocabulary_
|
|
return len(self.vectorizer.vocabulary_)
|
|
|
|
# Metode untuk mendapatkan bobot IDF (Inverse Document Frequency) masing-masing kata
|
|
def get_idf(self) -> dict:
|
|
"""Mendapatkan skor bobot IDF untuk masing-masing kata dalam bentuk pasangan key-value dictionary"""
|
|
# Mengambil daftar nama seluruh fitur kata
|
|
feature_names = self.get_feature_names()
|
|
# Menggabungkan nama fitur dengan nilai bobot idf_ menggunakan zip dan mengonversinya menjadi dictionary Python
|
|
return dict(zip(feature_names, self.vectorizer.idf_))
|
|
|
|
|
|
# Fungsi utilitas pembantu (helper function) untuk membangun feature matrix secara ringkas dalam satu pemanggilan
|
|
def create_feature_matrix(texts: list, **kwargs) -> tuple:
|
|
"""
|
|
Fungsi pembantu sekali panggil untuk memproses teks mentah menjadi matriks fitur TF-IDF.
|
|
|
|
Args:
|
|
texts: List kumpulan dokumen teks hasil praproses
|
|
**kwargs: Argumen konfigurasi tambahan untuk TfidfExtractor
|
|
|
|
Returns:
|
|
Tuple 3 elemen berisi: (feature_matrix, daftar_nama_fitur, instance_extractor)
|
|
"""
|
|
# Menginisialisasi instance ekstraktor TF-IDF dengan parameter kwargs
|
|
extractor = TfidfExtractor(**kwargs)
|
|
# Melakukan fitting dan transformasi teks menjadi matriks fitur
|
|
matrix = extractor.fit_transform(texts)
|
|
# Mengembalikan matriks bobot TF-IDF, daftar nama kosakata fitur, dan objek extractor
|
|
return matrix, extractor.get_feature_names(), extractor
|
|
|
|
|
|
# Blok pengetesan lokal modul yang hanya dijalankan ketika file ini dieksekusi langsung
|
|
if __name__ == "__main__":
|
|
# Menyiapkan sampel kalimat tiruan untuk menguji proses vektorisasi teks
|
|
sample_texts = [
|
|
"software engineer developer",
|
|
"data analyst scientist",
|
|
"project manager leader"
|
|
]
|
|
|
|
# Menjalankan fungsi create_feature_matrix pada sampel teks
|
|
matrix, features, extractor = create_feature_matrix(sample_texts)
|
|
# Menampilkan dimensi baris dan kolom matriks fitur (jumlah dokumen x jumlah kosakata)
|
|
print(f"Feature Matrix Shape: {matrix.shape}")
|
|
# Menampilkan seluruh nama fitur kata yang diekstraksi
|
|
print(f"Features: {features}")
|
|
|