Spaces:
Sleeping
Sleeping
| from sklearn import svm | |
| import re | |
| import nltk | |
| import pandas as pd | |
| from nltk.corpus import stopwords | |
| from nltk.stem import WordNetLemmatizer | |
| from nltk.stem import PorterStemmer | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.preprocessing import LabelEncoder | |
| from sklearn.metrics import classification_report | |
| import pickle | |
| """" | |
| *** USAGE *** | |
| Proprocessing and model loading should be done at the initialization of the app, | |
| /model.pkl/ can be found at ./app/ml/ alongside the dataset, can be done by | |
| /init_model/ | |
| from utils import init_model, inference | |
| model = init_model("BooksDataSet.csv", "model.pkl") | |
| Then, for inference we can simply call /inference/ which returns a string (genre) | |
| print(inference(model, "spaceship armada")) # returns "Science Fiction" | |
| """ | |
| tfidf_vectorizer = TfidfVectorizer(max_df=0.8, max_features=10000) | |
| LE = LabelEncoder() | |
| def setup_vectorizer(xtrain, xval): | |
| "vectorizer used for converting words to vector" | |
| xtrain_tfidf = tfidf_vectorizer.fit_transform(xtrain.values.astype('U')) | |
| xval_tfidf = tfidf_vectorizer.transform(xval.values.astype('U')) | |
| return xtrain_tfidf, xval_tfidf | |
| def setup_nltk(): | |
| """ | |
| Initialize nltk before preprocessing, needs to be called only once for python | |
| dependencies | |
| """ | |
| nltk.download('stopwords') | |
| nltk.download('wordnet') | |
| def lematizing(sentence): | |
| lemma=WordNetLemmatizer() | |
| stemSentence = "" | |
| for word in sentence.split(): | |
| stem = lemma.lemmatize(word) | |
| stemSentence += stem | |
| stemSentence += " " | |
| stemSentence = stemSentence.strip() | |
| return stemSentence | |
| def remove_stopwords(text): | |
| """ | |
| function to remove stopwords | |
| """ | |
| stop_words = set(stopwords.words('english')) | |
| no_stopword_text = [w for w in text.split() if not w in stop_words] | |
| return ' '.join(no_stopword_text) | |
| def stemming(sentence): | |
| stemmer = PorterStemmer() | |
| stemSentence = "" | |
| for word in sentence.split(): | |
| stem = stemmer.stem(word) | |
| stemSentence += stem | |
| stemSentence += " " | |
| stemSentence = stemSentence.strip() | |
| return stemSentence | |
| def clean(text): | |
| """ | |
| remove backslash-apostrophe, whitespace and convert to lowercase | |
| """ | |
| text = re.sub("\'", "", text) | |
| text = re.sub("[^a-zA-Z]"," ",text) | |
| text = ' '.join(text.split()) | |
| text = text.lower() | |
| return text | |
| def train_model(xtrain, xval, ytrain, yval): | |
| """ | |
| Train the model on the dataset | |
| """ | |
| svc = svm.SVC(kernel='linear').fit(xtrain, ytrain) | |
| return svc | |
| def validate_model(model, xval, yval): | |
| """ | |
| Validate the model for accuracy | |
| """ | |
| svpred=model.predict(xval) | |
| # for accuracy reports | |
| print(classification_report(yval,svpred)) | |
| return svpred | |
| def save_model(model): | |
| pickle.dump(model, open("model.pkl", 'wb')) | |
| def preprocess_data(filename: str): | |
| """ | |
| Data preprocessing for variability and cleanliness | |
| """ | |
| books=pd.read_csv(filename) | |
| books=pd.DataFrame(books,columns=['book_id','book_name','genre','summary']) | |
| books.loc[:,'summary']=books.loc[:,'summary'].apply(lambda x: clean(x)) | |
| books['summary'] = books['summary'].apply(lambda x: remove_stopwords(x)) | |
| books['summary'] = books['summary'].apply(lambda x: lematizing(x)) | |
| books['summary'] = books['summary'].apply(lambda x: stemming(x)) | |
| y=LE.fit_transform(books['genre']) | |
| xtrain, xval, ytrain, yval = train_test_split(books['summary'], y, test_size=0.15, random_state=557) | |
| xtrain, xval = setup_vectorizer(xtrain, xval) | |
| # print(books['summary']) | |
| return [xtrain, xval, ytrain, yval] | |
| def load_model(filename: str): | |
| "load a model from a filename" | |
| model = pickle.load(open("model.pkl", 'rb')) | |
| return model | |
| def inference(model, q): | |
| "enter a string to return the genre of the summary" | |
| q = clean(q) | |
| q = remove_stopwords(q) | |
| q = lematizing(q) | |
| q = stemming(q) | |
| q_vec = tfidf_vectorizer.transform([q]) | |
| q_pred = model.predict(q_vec) | |
| return LE.inverse_transform(q_pred)[0] | |
| def init_model(dataset: str, model: str): | |
| """ | |
| Initializes the model should be called at the start of the application | |
| """ | |
| setup_nltk() | |
| xtrain, xval, ytrain, yval = preprocess_data(dataset) | |
| model = load_model(model) | |
| return model | |