From d0b2a6b8550f0bee50b8ef0fcc2870173989aa06 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Jan 2025 17:00:46 +0000 Subject: [PATCH] Deployed 58cb1db with MkDocs version: 1.6.1 --- .nojekyll | 0 404.html | 464 ++ algorithm-readme-template/index.html | 1141 +++ .../evolutionary-algorithms/index.html | 497 ++ .../expert-systems/index.html | 497 ++ algorithms/artificial-intelligence/index.html | 546 ++ .../knowledge-based-systems/index.html | 497 ++ .../reinforcement-learning/index.html | 497 ++ .../search-and-optimization/index.html | 497 ++ .../image-augmentation/index.html | 497 ++ .../image-processing/index.html | 497 ++ algorithms/computer-vision/index.html | 535 ++ .../object-detection/index.html | 497 ++ .../semantic-segmentation/index.html | 497 ++ .../deep-learning/architectures/index.html | 497 ++ algorithms/deep-learning/index.html | 535 ++ .../convolutional-neural-network/index.html | 714 ++ .../deep-learning/neural-networks/index.html | 502 ++ .../optimization-algorithms/index.html | 497 ++ .../pre-trained-models/index.html | 497 ++ .../ac-gan/index.html | 787 ++ .../basic-gan/index.html | 727 ++ .../c-gan/index.html | 755 ++ .../eb-gan/index.html | 729 ++ .../index.html | 542 ++ .../info-gan/index.html | 759 ++ algorithms/index.html | 631 ++ .../large-language-models/bert/index.html | 497 ++ .../large-language-models/bloom/index.html | 497 ++ .../gpt-series/index.html | 497 ++ algorithms/large-language-models/index.html | 535 ++ .../large-language-models/t5/index.html | 497 ++ .../machine-learning/boosting/index.html | 501 ++ .../boosting/light-gbm/index.html | 703 ++ .../data-preprocessing/encoding/index.html | 502 ++ .../encoding/ordinal-encoder/index.html | 669 ++ .../data-preprocessing/imputation/index.html | 497 ++ .../data-preprocessing/index.html | 526 ++ .../scaling-and-normalization/index.html | 513 ++ .../min-max-scaler/index.html | 689 ++ .../standard-scaler/index.html | 700 ++ algorithms/machine-learning/index.html | 535 ++ .../supervised/classifications/index.html | 497 ++ .../machine-learning/supervised/index.html | 513 ++ .../AdaBoost_Regression/index.html | 711 ++ .../Decision_Tree_Regression/index.html | 714 ++ .../Elastic_Net_Regression/index.html | 601 ++ .../Gradient_Boosting_Regression/index.html | 727 ++ .../regressions/Huber_Regression/index.html | 614 ++ .../K_Nearest_Neighbors_Regression/index.html | 603 ++ .../regressions/Lasso_Regression/index.html | 616 ++ .../Logistic_Regression/index.html | 633 ++ .../Neural_Network_Regression/index.html | 637 ++ .../Polynomial_Regression/index.html | 623 ++ .../Random_Forest_Regression/index.html | 753 ++ .../regressions/Ridge_Regression/index.html | 617 ++ .../Support_Vector_Regression/index.html | 649 ++ .../XG_Boost_Regression/index.html | 636 ++ .../regressions/bayesian/index.html | 610 ++ .../supervised/regressions/index.html | 512 ++ .../supervised/regressions/linear/index.html | 624 ++ .../unsupervised/clustering/index.html | 502 ++ .../clustering/kmeans-clustering/index.html | 720 ++ .../dimensionality-reduction/index.html | 497 ++ .../machine-learning/unsupervised/index.html | 513 ++ .../Bag_Of_Words/index.html | 536 ++ .../Fast_Text/index.html | 915 +++ .../GloVe/index.html | 824 ++ .../NLTK_Setup/index.html | 788 ++ .../N_L_P_Introduction/index.html | 648 ++ .../Text_PreProcessing_Techniques/index.html | 965 +++ .../Tf_Idf/index.html | 843 +++ .../Transformers/index.html | 669 ++ .../Word_2_Vec/index.html | 862 +++ .../Word_Embeddings/index.html | 846 +++ .../natural-language-processing/index.html | 591 ++ algorithms/statistics/descriptive/index.html | 497 ++ algorithms/statistics/index.html | 536 ++ algorithms/statistics/inferential/index.html | 497 ++ .../errors/Mean_Absolute_Error/index.html | 503 ++ .../errors/Mean_Squared_Error/index.html | 503 ++ .../errors/R2_Squared_Error/index.html | 506 ++ .../errors/Root_Mean_Squared_Error/index.html | 504 ++ .../statistics/metrics-and-losses/index.html | 488 ++ .../Cross_Entropy_Loss/index.html | 655 ++ .../loss-functions/Hinge_Loss/index.html | 524 ++ .../index.html | 539 ++ .../loss-functions/Ranking_Losses/index.html | 571 ++ algorithms/statistics/probability/index.html | 497 ++ assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.60a45f97.min.js | 16 + assets/javascripts/bundle.60a45f97.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.f8cc74c7.min.js | 42 + .../workers/search.f8cc74c7.min.js.map | 7 + assets/stylesheets/main.a40c8224.min.css | 1 + assets/stylesheets/main.a40c8224.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + contribute/index.html | 1243 +++ customs/extra.css | 49 + index.html | 662 ++ project-readme-template/index.html | 1273 ++++ projects/artificial-intelligence/index.html | 497 ++ .../index.html | 801 ++ .../brightness-control/index.html | 919 +++ .../counting-bicep-reps/index.html | 832 ++ .../computer-vision/face-detection/index.html | 816 ++ projects/computer-vision/index.html | 520 ++ .../index.html | 1014 +++ .../brain-tumor-detection-model/index.html | 784 ++ projects/deep-learning/index.html | 502 ++ .../index.html | 497 ++ projects/index.html | 631 ++ projects/large-language-models/index.html | 497 ++ .../air-quality-prediction/index.html | 962 +++ .../index.html | 1201 +++ .../index.html | 1308 ++++ .../heart-disease-detection-model/index.html | 921 +++ projects/machine-learning/index.html | 503 ++ .../poker-hand-prediction/index.html | 1089 +++ .../sleep-quality-prediction/index.html | 743 ++ .../used-cars-price-prediction/index.html | 1009 +++ .../chatbot-project-implementation/index.html | 845 +++ .../email_spam_detection/index.html | 933 +++ .../natural-language-processing/index.html | 501 ++ .../name_entity_recognition/index.html | 795 ++ .../next-word-pred/index.html | 869 +++ .../twitter_sentiment_analysis/index.html | 931 +++ .../index.html | 1194 +++ projects/statistics/index.html | 503 ++ search/search_index.json | 1 + sitemap.xml | 475 ++ sitemap.xml.gz | Bin 0 -> 1434 bytes 167 files changed, 86715 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 algorithm-readme-template/index.html create mode 100644 algorithms/artificial-intelligence/evolutionary-algorithms/index.html create mode 100644 algorithms/artificial-intelligence/expert-systems/index.html create mode 100644 algorithms/artificial-intelligence/index.html create mode 100644 algorithms/artificial-intelligence/knowledge-based-systems/index.html create mode 100644 algorithms/artificial-intelligence/reinforcement-learning/index.html create mode 100644 algorithms/artificial-intelligence/search-and-optimization/index.html create mode 100644 algorithms/computer-vision/image-augmentation/index.html create mode 100644 algorithms/computer-vision/image-processing/index.html create mode 100644 algorithms/computer-vision/index.html create mode 100644 algorithms/computer-vision/object-detection/index.html create mode 100644 algorithms/computer-vision/semantic-segmentation/index.html create mode 100644 algorithms/deep-learning/architectures/index.html create mode 100644 algorithms/deep-learning/index.html create mode 100644 algorithms/deep-learning/neural-networks/convolutional-neural-network/index.html create mode 100644 algorithms/deep-learning/neural-networks/index.html create mode 100644 algorithms/deep-learning/optimization-algorithms/index.html create mode 100644 algorithms/deep-learning/pre-trained-models/index.html create mode 100644 algorithms/generative-adversarial-networks/ac-gan/index.html create mode 100644 algorithms/generative-adversarial-networks/basic-gan/index.html create mode 100644 algorithms/generative-adversarial-networks/c-gan/index.html create mode 100644 algorithms/generative-adversarial-networks/eb-gan/index.html create mode 100644 algorithms/generative-adversarial-networks/index.html create mode 100644 algorithms/generative-adversarial-networks/info-gan/index.html create mode 100644 algorithms/index.html create mode 100644 algorithms/large-language-models/bert/index.html create mode 100644 algorithms/large-language-models/bloom/index.html create mode 100644 algorithms/large-language-models/gpt-series/index.html create mode 100644 algorithms/large-language-models/index.html create mode 100644 algorithms/large-language-models/t5/index.html create mode 100644 algorithms/machine-learning/boosting/index.html create mode 100644 algorithms/machine-learning/boosting/light-gbm/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/encoding/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/encoding/ordinal-encoder/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/imputation/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/scaling-and-normalization/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/scaling-and-normalization/min-max-scaler/index.html create mode 100644 algorithms/machine-learning/data-preprocessing/scaling-and-normalization/standard-scaler/index.html create mode 100644 algorithms/machine-learning/index.html create mode 100644 algorithms/machine-learning/supervised/classifications/index.html create mode 100644 algorithms/machine-learning/supervised/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/AdaBoost_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Decision_Tree_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Elastic_Net_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Gradient_Boosting_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Huber_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/K_Nearest_Neighbors_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Lasso_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Logistic_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Neural_Network_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Polynomial_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Random_Forest_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Ridge_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/Support_Vector_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/XG_Boost_Regression/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/bayesian/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/index.html create mode 100644 algorithms/machine-learning/supervised/regressions/linear/index.html create mode 100644 algorithms/machine-learning/unsupervised/clustering/index.html create mode 100644 algorithms/machine-learning/unsupervised/clustering/kmeans-clustering/index.html create mode 100644 algorithms/machine-learning/unsupervised/dimensionality-reduction/index.html create mode 100644 algorithms/machine-learning/unsupervised/index.html create mode 100644 algorithms/natural-language-processing/Bag_Of_Words/index.html create mode 100644 algorithms/natural-language-processing/Fast_Text/index.html create mode 100644 algorithms/natural-language-processing/GloVe/index.html create mode 100644 algorithms/natural-language-processing/NLTK_Setup/index.html create mode 100644 algorithms/natural-language-processing/N_L_P_Introduction/index.html create mode 100644 algorithms/natural-language-processing/Text_PreProcessing_Techniques/index.html create mode 100644 algorithms/natural-language-processing/Tf_Idf/index.html create mode 100644 algorithms/natural-language-processing/Transformers/index.html create mode 100644 algorithms/natural-language-processing/Word_2_Vec/index.html create mode 100644 algorithms/natural-language-processing/Word_Embeddings/index.html create mode 100644 algorithms/natural-language-processing/index.html create mode 100644 algorithms/statistics/descriptive/index.html create mode 100644 algorithms/statistics/index.html create mode 100644 algorithms/statistics/inferential/index.html create mode 100644 algorithms/statistics/metrics-and-losses/errors/Mean_Absolute_Error/index.html create mode 100644 algorithms/statistics/metrics-and-losses/errors/Mean_Squared_Error/index.html create mode 100644 algorithms/statistics/metrics-and-losses/errors/R2_Squared_Error/index.html create mode 100644 algorithms/statistics/metrics-and-losses/errors/Root_Mean_Squared_Error/index.html create mode 100644 algorithms/statistics/metrics-and-losses/index.html create mode 100644 algorithms/statistics/metrics-and-losses/loss-functions/Cross_Entropy_Loss/index.html create mode 100644 algorithms/statistics/metrics-and-losses/loss-functions/Hinge_Loss/index.html create mode 100644 algorithms/statistics/metrics-and-losses/loss-functions/Kullback_Leibler_Divergence_Loss/index.html create mode 100644 algorithms/statistics/metrics-and-losses/loss-functions/Ranking_Losses/index.html create mode 100644 algorithms/statistics/probability/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.60a45f97.min.js create mode 100644 assets/javascripts/bundle.60a45f97.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.f8cc74c7.min.js create mode 100644 assets/javascripts/workers/search.f8cc74c7.min.js.map create mode 100644 assets/stylesheets/main.a40c8224.min.css create mode 100644 assets/stylesheets/main.a40c8224.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 contribute/index.html create mode 100644 customs/extra.css create mode 100644 index.html create mode 100644 project-readme-template/index.html create mode 100644 projects/artificial-intelligence/index.html create mode 100644 projects/computer-vision/black_and_white_image_colorizer/index.html create mode 100644 projects/computer-vision/brightness-control/index.html create mode 100644 projects/computer-vision/counting-bicep-reps/index.html create mode 100644 projects/computer-vision/face-detection/index.html create mode 100644 projects/computer-vision/index.html create mode 100644 projects/computer-vision/music_genre_classification_model/index.html create mode 100644 projects/deep-learning/brain-tumor-detection-model/index.html create mode 100644 projects/deep-learning/index.html create mode 100644 projects/generative-adversarial-networks/index.html create mode 100644 projects/index.html create mode 100644 projects/large-language-models/index.html create mode 100644 projects/machine-learning/air-quality-prediction/index.html create mode 100644 projects/machine-learning/cardiovascular-disease-prediction/index.html create mode 100644 projects/machine-learning/health-insurance-cross-sell-prediction/index.html create mode 100644 projects/machine-learning/heart-disease-detection-model/index.html create mode 100644 projects/machine-learning/index.html create mode 100644 projects/machine-learning/poker-hand-prediction/index.html create mode 100644 projects/machine-learning/sleep-quality-prediction/index.html create mode 100644 projects/machine-learning/used-cars-price-prediction/index.html create mode 100644 projects/natural-language-processing/chatbot-project-implementation/index.html create mode 100644 projects/natural-language-processing/email_spam_detection/index.html create mode 100644 projects/natural-language-processing/index.html create mode 100644 projects/natural-language-processing/name_entity_recognition/index.html create mode 100644 projects/natural-language-processing/next-word-pred/index.html create mode 100644 projects/natural-language-processing/twitter_sentiment_analysis/index.html create mode 100644 projects/statistics/bangladesh-premier-league-analysis/index.html create mode 100644 projects/statistics/index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..afeab349 --- /dev/null +++ b/404.html @@ -0,0 +1,464 @@ + + + +
+ + + + + + + + + + + + + + +# Example: Bayesian Regression implementation
+
+import numpy as np
+from sklearn.linear_model import BayesianRidge
+import matplotlib.pyplot as plt
+
+# Generate Synthetic Data
+np.random.seed(42)
+X = np.random.rand(20, 1) * 10
+y = 3 * X.squeeze() + np.random.randn(20) * 2
+
+# Initialize and Train Bayesian Ridge Regression
+model = BayesianRidge(alpha_1=1e-6, lambda_1=1e-6, compute_score=True)
+model.fit(X, y)
+
+# Make Predictions
+X_test = np.linspace(0, 10, 100).reshape(-1, 1)
+y_pred, y_std = model.predict(X_test, return_std=True)
+
+# Display Results
+print("Coefficients:", model.coef_)
+print("Intercept:", model.intercept_)
+
+# Visualization
+plt.figure(figsize=(8, 5))
+plt.scatter(X, y, color="blue", label="Training Data")
+plt.plot(X_test, y_pred, color="red", label="Mean Prediction")
+plt.fill_between(
+ X_test.squeeze(),
+ y_pred - y_std,
+ y_pred + y_std,
+ color="orange",
+ alpha=0.3,
+ label="Predictive Uncertainty",
+)
+plt.title("Bayesian Regression with Predictive Uncertainty")
+plt.xlabel("X")
+plt.ylabel("y")
+plt.legend()
+plt.show()
+
Bayesian Regression is a probabilistic approach to linear regression that incorporates prior beliefs and updates these beliefs based on observed data to form posterior distributions of the model parameters. Below is a breakdown of the implementation, structured for clarity and understanding.
+class BayesianRegression:
+ def __init__(self, alpha=1, beta=1):
+ """
+ Constructor for the BayesianRegression class.
+
+ Parameters:
+ - alpha: Prior precision (controls the weight of the prior belief).
+ - beta: Noise precision (inverse of noise variance in the data).
+ """
+ self.alpha = alpha
+ self.beta = beta
+ self.w_mean = None
+ self.w_precision = None
+
alpha
(Prior precision, representing our belief in the model parameters' variability) and beta
(Precision of the noise in the data) hyperparameters are crucial to controlling the Bayesian framework. A higher alpha
means stronger prior belief in smaller weights, while beta
controls the confidence in the noise level of the observations.w_mean
- Posterior mean of weights (initialized as None)w_precision
- Posterior precision matrix (initialized as None)def fit(self, X, y):
+ """
+ Fit the Bayesian Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array of shape [n_samples, n_features]).
+ - y: Target values (numpy array of shape [n_samples]).
+ """
+ # Add a bias term to X for intercept handling.
+ X = np.c_[np.ones(X.shape[0]), X]
+
+ # Compute the posterior precision matrix.
+ self.w_precision = (
+ self.alpha * np.eye(X.shape[1]) # Prior contribution.
+ + self.beta * X.T @ X # Data contribution.
+ )
+
+ # Compute the posterior mean of the weights.
+ self.w_mean = np.linalg.solve(self.w_precision, self.beta * X.T @ y)
+
Key Steps in the Fitting Process
+X
to account for the intercept in the linear model.Posterior Precision Matrix: + $$ + \mathbf{S}_w^{-1} = \alpha \mathbf{I} + \beta \mathbf{X}^\top \mathbf{X} + $$
+Posterior Mean of Weights: + $$ + \mathbf{m}_w = \mathbf{S}_w \beta \mathbf{X}^\top \mathbf{y} + $$
+def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array of shape [n_samples, n_features]).
+
+ Returns:
+ - Predicted values (numpy array of shape [n_samples]).
+ """
+ # Add a bias term to X for intercept handling.
+ X = np.c_[np.ones(X.shape[0]), X]
+
+ # Compute the mean of the predictions using the posterior mean of weights.
+ y_pred = X @ self.w_mean
+
+ return y_pred
+
Key Prediction Details
+# Example Data
+X = np.array([[1.0], [2.0], [3.0]]) # Features
+y = np.array([2.0, 4.0, 6.0]) # Targets
+
+# Initialize and Train Model
+model = BayesianRegression(alpha=1.0, beta=1.0)
+model.fit(X, y)
+
+# Predict on New Data
+X_new = np.array([[4.0], [5.0]])
+y_pred = model.predict(X_new)
+
+print(f"Predictions: {y_pred}")
+
Explain your application
+Explain your application
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
+Convolutional Neural Networks (CNNs) are a type of deep learning algorithm specifically designed for processing structured grid data such as images. They are widely used in computer vision tasks like image classification, object detection, and image segmentation.
+CNNs are composed of the following layers: +- Convolutional Layers: Extract spatial features from the input data. +- Pooling Layers: Reduce the spatial dimensions of feature maps to lower computational costs. +- Fully Connected Layers: Perform high-level reasoning for final predictions.
+Here’s a Python example of a CNN using TensorFlow/Keras:
+from tensorflow.keras.models import Sequential
+from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
+
+# Build the CNN
+model = Sequential([
+ Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)),
+ MaxPooling2D(pool_size=(2, 2)),
+ Conv2D(64, (3, 3), activation='relu'),
+ MaxPooling2D(pool_size=(2, 2)),
+ Flatten(),
+ Dense(128, activation='relu'),
+ Dense(10, activation='softmax') # Replace 10 with the number of classes in your dataset
+])
+
+# Compile the model
+model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
+
+# Summary
+model.summary()
+
+ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
+Auxiliary Classifier Generative Adversarial Network (ACGAN) is an extension of the traditional GAN architecture. It incorporates class information into both the generator and discriminator, enabling controlled generation of samples with specific characteristics.
+ACGANs can: +- Generate high-quality images conditioned on specific classes. +- Predict class labels of generated images via the discriminator.
+This dual capability allows for more controlled and targeted image synthesis.
+Generator:
+Discriminator:
+Class Conditioning:
+Below is a high-level explanation of the ACGAN implementation:
+Dataset:
+Model Architecture:
+Training Process:
+Loss Functions:
+class Discriminator(nn.Module):
+ def __init__(self):
+ super(Discriminator, self).__init__()
+ self.label_emb = nn.Embedding(num_classes, num_classes)
+ self.model = nn.Sequential(
+ nn.Linear(image_size + num_classes, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Dropout(0.3),
+ nn.Linear(hidden_size, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Dropout(0.3),
+ nn.Linear(hidden_size, 1),
+ nn.Sigmoid()
+ )
+
+ def forward(self, x, labels):
+ x = x.view(x.size(0), image_size)
+ c = self.label_emb(labels)
+ x = torch.cat([x, c], 1)
+ return self.model(x)
+
class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.label_emb = nn.Embedding(num_classes, num_classes)
+ self.model = nn.Sequential(
+ nn.Linear(latent_size + num_classes, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z, labels):
+ z = z.view(z.size(0), latent_size)
+ c = self.label_emb(labels)
+ x = torch.cat([z, c], 1)
+ return self.model(x)
+
for epoch in range(num_epochs):
+ for i, (images, labels) in enumerate(train_loader):
+ batch_size = images.size(0)
+ images = images.to(device)
+ labels = labels.to(device)
+
+ # Real and fake labels
+ real_labels = torch.ones(batch_size, 1).to(device)
+ fake_labels = torch.zeros(batch_size, 1).to(device)
+
+ # Train Discriminator
+ outputs = D(images, labels)
+ d_loss_real = criterion(outputs, real_labels)
+
+ z = create_noise(batch_size, latent_size)
+ fake_images = G(z, labels)
+ outputs = D(fake_images, labels)
+ d_loss_fake = criterion(outputs, fake_labels)
+
+ d_loss = d_loss_real + d_loss_fake
+ D.zero_grad()
+ d_loss.backward()
+ d_optimizer.step()
+
+ # Train Generator
+ z = create_noise(batch_size, latent_size)
+ fake_images = G(z, labels)
+ outputs = D(fake_images, labels)
+ g_loss = criterion(outputs, real_labels)
+
+ G.zero_grad()
+ g_loss.backward()
+ g_optimizer.step()
+
+ if (i+1) % 200 == 0:
+ print(f"Epoch [{epoch}/{num_epochs}], Step [{i+1}/{total_step}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}")
+
Image Synthesis:
+Data Augmentation:
+Creative Domains:
+Basic GAN stands for Basic Generative Adversarial Network
+
This folder contains a basic implementation of a Generative Adversarial Network (GAN) using PyTorch. GANs are a type of neural network architecture that consists of two networks: a generator and a discriminator. The generator learns to create realistic data samples (e.g., images) from random noise, while the discriminator learns to distinguish between real and generated samples.
+This project implements a simple GAN architecture to generate hand-written digits resembling those from the MNIST dataset. The generator network creates fake images, while the discriminator network tries to differentiate between real and generated images. The networks are trained simultaneously in a minimax game until the generator produces realistic images.
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torchvision.datasets as dsets
+import torchvision.transforms as transforms
+from torch.utils.data import DataLoader
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+image_size = 784 # 28x28
+hidden_size = 256
+latent_size = 64
+num_epochs = 200
+batch_size = 100
+learning_rate = 0.0002
+
+# MNIST dataset
+dataset = dsets.MNIST(root='../data/',
+ train=True,
+ transform=transforms.ToTensor(),
+ download=True)
+
+# Data loader
+data_loader = DataLoader(dataset=dataset,
+ batch_size=batch_size,
+ shuffle=True)
+
+# Discriminator
+D = nn.Sequential(
+ nn.Linear(image_size, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Linear(hidden_size, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Linear(hidden_size, 1),
+ nn.Sigmoid())
+
+# Generator
+G = nn.Sequential(
+ nn.Linear(latent_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh())
+
+# Device setting
+D = D.to(device)
+G = G.to(device)
+
+# Binary cross entropy loss and optimizer
+criterion = nn.BCELoss()
+d_optimizer = optim.Adam(D.parameters(), lr=learning_rate)
+g_optimizer = optim.Adam(G.parameters(), lr=learning_rate)
+
+# Utility function to create real and fake labels
+def create_real_labels(size):
+ data = torch.ones(size, 1)
+ return data.to(device)
+
+def create_fake_labels(size):
+ data = torch.zeros(size, 1)
+ return data.to(device)
+
+# Utility function to generate random noise
+def create_noise(size, latent_dim):
+ return torch.randn(size, latent_dim).to(device)
+
+# Training the GAN
+total_step = len(data_loader)
+for epoch in range(num_epochs):
+ for i, (images, _) in enumerate(data_loader):
+ batch_size = images.size(0)
+ images = images.reshape(batch_size, -1).to(device)
+
+ # Create the labels which are later used as input for the BCE loss
+ real_labels = create_real_labels(batch_size)
+ fake_labels = create_fake_labels(batch_size)
+
+ # ================================================================== #
+ # Train the discriminator #
+ # ================================================================== #
+ # Compute BCELoss using real images
+ # Second term of the loss is always zero since real_labels == 1
+ outputs = D(images)
+ d_loss_real = criterion(outputs, real_labels)
+ real_score = outputs
+
+ # Compute BCELoss using fake images
+ noise = create_noise(batch_size, latent_size)
+ fake_images = G(noise)
+ outputs = D(fake_images)
+ d_loss_fake = criterion(outputs, fake_labels)
+ fake_score = outputs
+
+ # Backprop and optimize
+ d_loss = d_loss_real + d_loss_fake
+ d_optimizer.zero_grad()
+ d_loss.backward()
+ d_optimizer.step()
+
+ # ================================================================== #
+ # Train the generator #
+ # ================================================================== #
+ # Compute loss with fake images
+ noise = create_noise(batch_size, latent_size)
+ fake_images = G(noise)
+ outputs = D(fake_images)
+
+ # We train G to maximize log(D(G(z)) instead of minimizing log(1-D(G(z)))
+ # For the reason, look at the last part of section 3 of the paper:
+ # https://arxiv.org/pdf/1406.2661.pdf
+ g_loss = criterion(outputs, real_labels)
+
+ # Backprop and optimize
+ g_optimizer.zero_grad()
+ g_loss.backward()
+ g_optimizer.step()
+
+ if (i+1) % 200 == 0:
+ print(f'Epoch [{epoch}/{num_epochs}], Step [{i+1}/{total_step}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}, D(x): {real_score.mean().item():.2f}, D(G(z)): {fake_score.mean().item():.2f}')
+
+# Save the trained models
+torch.save(G.state_dict(), 'G.pth')
+torch.save(D.state_dict(), 'D.pth')
+
+# Plot some generated images
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+G.eval()
+with torch.no_grad():
+ noise = create_noise(64, latent_size)
+ fake_images = G(noise)
+ fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
+ fake_images = denorm(fake_images)
+ grid = np.transpose(fake_images.cpu(), (0, 2, 3, 1)).numpy()
+
+ plt.figure(figsize=(8, 8))
+ for i in range(grid.shape[0]):
+ plt.subplot(8, 8, i+1)
+ plt.imshow(grid[i, :, :, 0], cmap='gray')
+ plt.axis('off')
+ plt.show()
+
BasicGAN.py
: Contains the implementation of the GAN model, training loop, and saving of trained models.import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+latent_size = 64
+hidden_size = 256
+image_size = 784 # 28x28
+
+# Generator
+G = nn.Sequential(
+ nn.Linear(latent_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh())
+
+# Load the trained generator model
+G.load_state_dict(torch.load('G.pth'))
+G.to(device)
+G.eval()
+
+# Utility function to generate random noise
+def create_noise(size, latent_dim):
+ return torch.randn(size, latent_dim).to(device)
+
+# Utility function to denormalize the images
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Generate images
+with torch.no_grad():
+ noise = create_noise(64, latent_size)
+ fake_images = G(noise)
+ fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
+ fake_images = denorm(fake_images)
+ grid = np.transpose(fake_images.cpu(), (0, 2, 3, 1)).numpy()
+
+ plt.figure(figsize=(8, 8))
+ for i in range(grid.shape[0]):
+ plt.subplot(8, 8, i+1)
+ plt.imshow(grid[i, :, :, 0], cmap='gray')
+ plt.axis('off')
+ plt.show()
+
test_BasicGAN.py
: Uses the trained generator to generate sample images after training.This folder contains an implementation of a Conditional Generative Adversarial Network (cGAN) using PyTorch. cGANs generate images conditioned on specific class labels, allowing for controlled image synthesis.
+cGANs extend the traditional GAN architecture by including class information in both the generator and discriminator. The generator learns to generate images conditioned on given class labels, while the discriminator not only distinguishes between real and fake images but also predicts the class labels of the generated images.
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torchvision.datasets as dsets
+import torchvision.transforms as transforms
+from torch.utils.data import DataLoader
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+image_size = 28 * 28
+num_classes = 10
+latent_size = 100
+hidden_size = 256
+num_epochs = 100
+batch_size = 64
+learning_rate = 0.0002
+
+# MNIST dataset
+transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Normalize(mean=(0.5,), std=(0.5,))
+])
+
+train_dataset = dsets.MNIST(root='../data/',
+ train=True,
+ transform=transform,
+ download=True)
+
+train_loader = DataLoader(dataset=train_dataset,
+ batch_size=batch_size,
+ shuffle=True)
+
+# Discriminator
+class Discriminator(nn.Module):
+ def __init__(self):
+ super(Discriminator, self).__init__()
+ self.label_emb = nn.Embedding(num_classes, num_classes)
+
+ self.model = nn.Sequential(
+ nn.Linear(image_size + num_classes, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Dropout(0.3),
+ nn.Linear(hidden_size, hidden_size),
+ nn.LeakyReLU(0.2),
+ nn.Dropout(0.3),
+ nn.Linear(hidden_size, 1),
+ nn.Sigmoid()
+ )
+
+ def forward(self, x, labels):
+ x = x.view(x.size(0), image_size)
+ c = self.label_emb(labels)
+ x = torch.cat([x, c], 1)
+ out = self.model(x)
+ return out
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.label_emb = nn.Embedding(num_classes, num_classes)
+
+ self.model = nn.Sequential(
+ nn.Linear(latent_size + num_classes, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z, labels):
+ z = z.view(z.size(0), latent_size)
+ c = self.label_emb(labels)
+ x = torch.cat([z, c], 1)
+ out = self.model(x)
+ return out
+
+# Initialize models
+D = Discriminator().to(device)
+G = Generator().to(device)
+
+# Loss function and optimizer
+criterion = nn.BCELoss()
+d_optimizer = optim.Adam(D.parameters(), lr=learning_rate)
+g_optimizer = optim.Adam(G.parameters(), lr=learning_rate)
+
+# Utility functions
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+def create_noise(batch_size, latent_size):
+ return torch.randn(batch_size, latent_size).to(device)
+
+def create_labels(batch_size):
+ return torch.randint(0, num_classes, (batch_size,)).to(device)
+
+# Training the cGAN
+total_step = len(train_loader)
+for epoch in range(num_epochs):
+ for i, (images, labels) in enumerate(train_loader):
+ batch_size = images.size(0)
+ images = images.to(device)
+ labels = labels.to(device)
+
+ # Create the labels which are later used as input for the discriminator
+ real_labels = torch.ones(batch_size, 1).to(device)
+ fake_labels = torch.zeros(batch_size, 1).to(device)
+
+ # ================================================================== #
+ # Train the discriminator #
+ # ================================================================== #
+
+ # Compute BCELoss using real images
+ outputs = D(images, labels)
+ d_loss_real = criterion(outputs, real_labels)
+ real_score = outputs
+
+ # Compute BCELoss using fake images
+ z = create_noise(batch_size, latent_size)
+ fake_images = G(z, labels)
+ outputs = D(fake_images, labels)
+ d_loss_fake = criterion(outputs, fake_labels)
+ fake_score = outputs
+
+ # Backprop and optimize
+ d_loss = d_loss_real + d_loss_fake
+ D.zero_grad()
+ d_loss.backward()
+ d_optimizer.step()
+
+ # ================================================================== #
+ # Train the generator #
+ # ================================================================== #
+
+ # Compute loss with fake images
+ z = create_noise(batch_size, latent_size)
+ fake_images = G(z, labels)
+ outputs = D(fake_images, labels)
+
+ # We train G to maximize log(D(G(z)))
+ g_loss = criterion(outputs, real_labels)
+
+ # Backprop and optimize
+ G.zero_grad()
+ g_loss.backward()
+ g_optimizer.step()
+
+ if (i+1) % 200 == 0:
+ print(f'Epoch [{epoch}/{num_epochs}], Step [{i+1}/{total_step}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}, D(x): {real_score.mean().item():.2f}, D(G(z)): {fake_score.mean().item():.2f}')
+
+# Save the trained models
+torch.save(G.state_dict(), 'G_cgan.pth')
+torch.save(D.state_dict(), 'D_cgan.pth')
+
cGAN.py
: Contains the implementation of the ACGAN model, training loop, and saving of trained models.import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+latent_size = 100
+num_classes = 10
+image_size = 28 * 28
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.label_emb = nn.Embedding(num_classes, num_classes)
+
+ self.model = nn.Sequential(
+ nn.Linear(latent_size + num_classes, 256),
+ nn.ReLU(),
+ nn.Linear(256, 512),
+ nn.ReLU(),
+ nn.Linear(512, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z, labels):
+ z = z.view(z.size(0), latent_size)
+ c = self.label_emb(labels)
+ x = torch.cat([z, c], 1)
+ out = self.model(x)
+ return out
+
+# Load the trained generator model
+G = Generator()
+G.load_state_dict(torch.load('G_cgan.pth', map_location=torch.device('cpu')))
+G.eval()
+
+# Utility function to generate random noise
+def create_noise(size, latent_dim):
+ return torch.randn(size, latent_dim)
+
+# Utility function to generate labels
+def create_labels(size):
+ return torch.randint(0, num_classes, (size,))
+
+# Utility function to denormalize the images
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Generate images
+with torch.no_grad():
+ noise = create_noise(64, latent_size)
+ labels = create_labels(64)
+ fake_images = G(noise, labels)
+ fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
+ fake_images = denorm(fake_images)
+ grid = np.transpose(fake_images, (0, 2, 3, 1)).numpy()
+
+ plt.figure(figsize=(8, 8))
+ for i in range(grid.shape[0]):
+ plt.subplot(8, 8, i+1)
+ plt.imshow(grid[i, :, :, 0], cmap='gray')
+ plt.axis('off')
+ plt.show()
+
test_cGAN.py
: Uses the trained generator to generate sample images after training.This folder contains an implementation of an Energy-Based Generative Adversarial Network (EBGAN) using PyTorch. EBGAN focuses on matching the energy distribution of generated samples to that of real data, optimizing both a discriminator and a generator network.
+EBGAN introduces an energy function that is used to measure the quality of generated samples. The discriminator (autoencoder-like) network tries to minimize this energy function while the generator tries to maximize it. This results in a more stable training process compared to traditional GANs.
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torchvision.datasets as dsets
+import torchvision.transforms as transforms
+from torch.utils.data import DataLoader
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+image_size = 28 * 28
+latent_size = 64
+hidden_size = 256
+num_epochs = 100
+batch_size = 64
+learning_rate = 0.0002
+k = 3 # Number of iterations for optimizing D
+
+# MNIST dataset
+transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Normalize(mean=(0.5,), std=(0.5,))
+])
+
+train_dataset = dsets.MNIST(root='../data/',
+ train=True,
+ transform=transform,
+ download=True)
+
+train_loader = DataLoader(dataset=train_dataset,
+ batch_size=batch_size,
+ shuffle=True)
+
+# Discriminator
+class Discriminator(nn.Module):
+ def __init__(self):
+ super(Discriminator, self).__init__()
+ self.encoder = nn.Sequential(
+ nn.Linear(image_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, latent_size)
+ )
+ self.decoder = nn.Sequential(
+ nn.Linear(latent_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, x):
+ encoded = self.encoder(x)
+ decoded = self.decoder(encoded)
+ return decoded, encoded
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.model = nn.Sequential(
+ nn.Linear(latent_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, hidden_size),
+ nn.ReLU(),
+ nn.Linear(hidden_size, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z):
+ out = self.model(z)
+ return out
+
+# Initialize models
+D = Discriminator().to(device)
+G = Generator().to(device)
+
+# Loss function and optimizer
+criterion_rec = nn.MSELoss()
+d_optimizer = optim.Adam(D.parameters(), lr=learning_rate)
+g_optimizer = optim.Adam(G.parameters(), lr=learning_rate)
+
+# Utility functions
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Training the EBGAN
+total_step = len(train_loader)
+for epoch in range(num_epochs):
+ for i, (images, _) in enumerate(train_loader):
+ batch_size = images.size(0)
+ images = images.view(-1, image_size).to(device)
+
+ # ================================================================== #
+ # Train the discriminator #
+ # ================================================================== #
+
+ encoded_real, _ = D(images)
+ decoded_real = D.decoder(encoded_real)
+
+ rec_loss_real = criterion_rec(decoded_real, images)
+
+ z = torch.randn(batch_size, latent_size).to(device)
+ fake_images = G(z)
+ encoded_fake, _ = D(fake_images.detach())
+ decoded_fake = D.decoder(encoded_fake)
+
+ rec_loss_fake = criterion_rec(decoded_fake, fake_images.detach())
+
+ d_loss = rec_loss_real + torch.max(torch.zeros(1).to(device), k * rec_loss_real - rec_loss_fake)
+
+ D.zero_grad()
+ d_loss.backward()
+ d_optimizer.step()
+
+ # ================================================================== #
+ # Train the generator #
+ # ================================================================== #
+
+ z = torch.randn(batch_size, latent_size).to(device)
+ fake_images = G(z)
+ encoded_fake, _ = D(fake_images)
+ decoded_fake = D.decoder(encoded_fake)
+
+ rec_loss_fake = criterion_rec(decoded_fake, fake_images)
+
+ g_loss = rec_loss_fake
+
+ G.zero_grad()
+ g_loss.backward()
+ g_optimizer.step()
+
+ if (i+1) % 200 == 0:
+ print(f'Epoch [{epoch}/{num_epochs}], Step [{i+1}/{total_step}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}, Rec_loss_real: {rec_loss_real.item():.4f}, Rec_loss_fake: {rec_loss_fake.item():.4f}')
+
+# Save the trained models
+torch.save(G.state_dict(), 'G_ebgan.pth')
+torch.save(D.state_dict(), 'D_ebgan.pth')
+
EBGAN.py
: Contains the implementation of the ACGAN model, training loop, and saving of trained models.import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+latent_size = 64
+image_size = 28 * 28
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.model = nn.Sequential(
+ nn.Linear(latent_size, 256),
+ nn.ReLU(),
+ nn.Linear(256, 512),
+ nn.ReLU(),
+ nn.Linear(512, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z):
+ out = self.model(z)
+ return out
+
+# Load the trained generator model
+G = Generator()
+G.load_state_dict(torch.load('G_ebgan.pth', map_location=torch.device('cpu')))
+G.eval()
+
+# Utility function to generate random noise
+def create_noise(size, latent_dim):
+ return torch.randn(size, latent_dim)
+
+# Utility function to denormalize the images
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Generate images
+with torch.no_grad():
+ noise = create_noise(64, latent_size)
+ fake_images = G(noise)
+ fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
+ fake_images = denorm(fake_images)
+ grid = np.transpose(fake_images, (0, 2, 3, 1)).numpy()
+
+ plt.figure(figsize=(8, 8))
+ for i in range(grid.shape[0]):
+ plt.subplot(8, 8, i+1)
+ plt.imshow(grid[i, :, :, 0], cmap='gray')
+ plt.axis('off')
+ plt.show()
+
test_EBGAN.py
: Uses the trained generator to generate sample images after training.Information Maximizing Generative Adversarial Network
+
This folder contains an implementation of InfoGAN using PyTorch. InfoGAN extends the traditional GAN framework by incorporating unsupervised learning of interpretable and disentangled representations.
+InfoGAN introduces latent codes that can be split into categorical and continuous variables, allowing for more control over the generated outputs. The generator is conditioned on these latent codes, which are learned in an unsupervised manner during training.
+import torch
+import torch.nn as nn
+import torch.optim as optim
+import torchvision.datasets as dsets
+import torchvision.transforms as transforms
+from torch.utils.data import DataLoader
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+image_size = 28 * 28
+num_epochs = 50
+batch_size = 100
+latent_size = 62
+num_continuous = 2
+num_categories = 10
+learning_rate = 0.0002
+
+# MNIST dataset
+transform = transforms.Compose([
+ transforms.ToTensor(),
+ transforms.Normalize(mean=(0.5,), std=(0.5,))
+])
+
+train_dataset = dsets.MNIST(root='../data/',
+ train=True,
+ transform=transform,
+ download=True)
+
+train_loader = DataLoader(dataset=train_dataset,
+ batch_size=batch_size,
+ shuffle=True)
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.fc = nn.Sequential(
+ nn.Linear(latent_size + num_categories + num_continuous, 256),
+ nn.ReLU(),
+ nn.Linear(256, 512),
+ nn.ReLU(),
+ nn.Linear(512, 1024),
+ nn.ReLU(),
+ nn.Linear(1024, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z, c_cat, c_cont):
+ inputs = torch.cat([z, c_cat, c_cont], dim=1)
+ return self.fc(inputs)
+
+
+# Discriminator
+class Discriminator(nn.Module):
+ def __init__(self):
+ super(Discriminator, self).__init__()
+ self.fc = nn.Sequential(
+ nn.Linear(image_size, 1024),
+ nn.ReLU(),
+ nn.Dropout(0.3),
+ nn.Linear(1024, 512),
+ nn.ReLU(),
+ nn.Dropout(0.3),
+ )
+
+ self.fc_disc = nn.Linear(512, num_categories)
+ self.fc_mu = nn.Linear(512, num_continuous)
+ self.fc_var = nn.Linear(512, num_continuous)
+
+ def forward(self, x):
+ x = self.fc(x)
+ disc_logits = self.fc_disc(x)
+ mu = self.fc_mu(x)
+ var = torch.exp(self.fc_var(x))
+ return disc_logits, mu, var
+
+
+# Initialize networks
+G = Generator().to(device)
+D = Discriminator().to(device)
+
+# Loss functions
+criterion_cat = nn.CrossEntropyLoss()
+criterion_cont = nn.MSELoss()
+
+# Optimizers
+g_optimizer = optim.Adam(G.parameters(), lr=learning_rate)
+d_optimizer = optim.Adam(D.parameters(), lr=learning_rate)
+
+# Utility functions
+def sample_noise(batch_size, latent_size):
+ return torch.randn(batch_size, latent_size).to(device)
+
+def sample_categorical(batch_size, num_categories):
+ return torch.randint(0, num_categories, (batch_size,)).to(device)
+
+def sample_continuous(batch_size, num_continuous):
+ return torch.rand(batch_size, num_continuous).to(device)
+
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Training InfoGAN
+total_step = len(train_loader)
+for epoch in range(num_epochs):
+ for i, (images, labels) in enumerate(train_loader):
+ batch_size = images.size(0)
+ images = images.view(-1, image_size).to(device)
+
+ # Create labels for discriminator
+ real_labels = torch.ones(batch_size, dtype=torch.long, device=device)
+ fake_labels = torch.zeros(batch_size, dtype=torch.long, device=device)
+
+ # Sample noise, categorical, and continuous latent codes
+ z = sample_noise(batch_size, latent_size)
+ c_cat = sample_categorical(batch_size, num_categories)
+ c_cont = sample_continuous(batch_size, num_continuous)
+
+ # Generate fake images
+ fake_images = G(z, c_cat, c_cont)
+
+ # Train discriminator
+ d_optimizer.zero_grad()
+ d_real_cat, d_real_mu, d_real_var = D(images)
+ d_real_loss_cat = criterion_cat(d_real_cat, labels)
+ d_fake_cat, d_fake_mu, d_fake_var = D(fake_images.detach())
+ d_fake_loss_cat = criterion_cat(d_fake_cat, c_cat)
+
+ d_loss_cat = d_real_loss_cat + d_fake_loss_cat
+
+ d_real_loss_cont = torch.mean(0.5 * torch.sum(torch.div((d_real_mu - c_cont)**2, d_real_var), dim=1))
+ d_fake_loss_cont = torch.mean(0.5 * torch.sum(torch.div((d_fake_mu - c_cont)**2, d_fake_var), dim=1))
+
+ d_loss_cont = d_real_loss_cont + d_fake_loss_cont
+
+ d_loss = d_loss_cat + d_loss_cont
+ d_loss.backward()
+ d_optimizer.step()
+
+ # Train generator
+ g_optimizer.zero_grad()
+ _, d_fake_mu, d_fake_var = D(fake_images)
+
+ g_loss_cat = criterion_cat(_, c_cat)
+ g_loss_cont = torch.mean(0.5 * torch.sum(torch.div((d_fake_mu - c_cont)**2, d_fake_var), dim=1))
+
+ g_loss = g_loss_cat + g_loss_cont
+ g_loss.backward()
+ g_optimizer.step()
+
+ if (i+1) % 200 == 0:
+ print(f'Epoch [{epoch}/{num_epochs}], Step [{i+1}/{total_step}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}')
+
+# Save the trained models
+torch.save(G.state_dict(), 'G_infogan.pth')
+torch.save(D.state_dict(), 'D_infogan.pth')
+
InfoGAN.py
: Contains the implementation of the ACGAN model, training loop, and saving of trained models.import torch
+import torch.nn as nn
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Device configuration
+device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+
+# Hyper-parameters
+latent_size = 62
+num_categories = 10
+num_continuous = 2
+image_size = 28 * 28
+
+# Generator
+class Generator(nn.Module):
+ def __init__(self):
+ super(Generator, self).__init__()
+ self.fc = nn.Sequential(
+ nn.Linear(latent_size + num_categories + num_continuous, 256),
+ nn.ReLU(),
+ nn.Linear(256, 512),
+ nn.ReLU(),
+ nn.Linear(512, 1024),
+ nn.ReLU(),
+ nn.Linear(1024, image_size),
+ nn.Tanh()
+ )
+
+ def forward(self, z, c_cat, c_cont):
+ inputs = torch.cat([z, c_cat, c_cont], dim=1)
+ return self.fc(inputs)
+
+# Load the trained generator model
+G = Generator().to(device)
+G.load_state_dict(torch.load('G_infogan.pth', map_location=torch.device('cpu')))
+G.eval()
+
+# Utility functions to generate samples
+def sample_noise(batch_size, latent_size):
+ return torch.randn(batch_size, latent_size).to(device)
+
+def sample_categorical(batch_size, num_categories):
+ return torch.randint(0, num_categories, (batch_size,)).to(device)
+
+def sample_continuous(batch_size, num_continuous):
+ return torch.rand(batch_size, num_continuous).to(device)
+
+def denorm(x):
+ out = (x + 1) / 2
+ return out.clamp(0, 1)
+
+# Generate images
+with torch.no_grad():
+ noise = sample_noise(64, latent_size)
+ c_cat = sample_categorical(64, num_categories)
+ c_cont = sample_continuous(64, num_continuous)
+ fake_images = G(noise, c_cat, c_cont)
+ fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
+ fake_images = denorm(fake_images)
+ grid = np.transpose(fake_images, (0, 2, 3, 1)).numpy()
+
+ plt.figure(figsize=(8, 8))
+ for i in range(grid.shape[0]):
+ plt.subplot(8, 8, i+1)
+ plt.imshow(grid[i, :, :, 0], cmap='gray')
+ plt.axis('off')
+ plt.show()
+
test_InfoGAN.py
: Uses the trained generator to generate sample images after training.+ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
+Overview:
+LightGBM (Light Gradient Boosting Machine) is an advanced gradient boosting framework that efficiently handles large datasets. Unlike traditional boosting methods, LightGBM uses leaf-wise tree growth, which improves accuracy and reduces computation time.
Example Visualization:
+
File: lightgbm_model.py
+
import lightgbm as lgb
+from sklearn.model_selection import train_test_split
+from sklearn.metrics import mean_squared_error
+
+class LightGBMModel:
+ def __init__(self, params=None):
+ self.params = params if params else {
+ 'objective': 'regression',
+ 'metric': 'rmse',
+ 'boosting_type': 'gbdt',
+ 'num_leaves': 31,
+ 'learning_rate': 0.05,
+ 'n_estimators': 100
+ }
+ self.model = None
+
+ def fit(self, X_train, y_train):
+ d_train = lgb.Dataset(X_train, label=y_train)
+ self.model = lgb.train(self.params, d_train)
+
+ def predict(self, X_test):
+ return self.model.predict(X_test)
+
File: lightgbm_model_test.py
+
import unittest
+import numpy as np
+from sklearn.datasets import load_diabetes
+from sklearn.model_selection import train_test_split
+from lightgbm_model import LightGBMModel
+
+class TestLightGBMModel(unittest.TestCase):
+
+ def test_lightgbm(self):
+ # Load Dataset
+ data = load_diabetes()
+ X_train, X_test, y_train, y_test = train_test_split(
+ data.data, data.target, test_size=0.2, random_state=42)
+
+ # Train Model
+ model = LightGBMModel()
+ model.fit(X_train, y_train)
+
+ # Predict and Evaluate
+ predictions = model.predict(X_test)
+ mse = mean_squared_error(y_test, predictions)
+ self.assertTrue(mse < 3500, "MSE is too high, LightGBM not performing well")
+
+if __name__ == '__main__':
+ unittest.main()
+
Use sklearn
datasets to validate the implementation. Compare performance with other boosting models to highlight LightGBM’s efficiency.
A custom implementation of an OrdinalEncoder class for encoding categorical data into ordinal integers using a pandas DataFrame. The class maps each unique category to an integer based on the order of appearance.
+__init__(self)
fit(self, data)
transform(self, data)
fit_transform(self, data)
import pandas as pd
+
+class OrdinalEncoding:
+ def __init__(self):
+ self.category_mapping = {}
+
+ def fit(self, data):
+ # Fit the encoder to the data (pandas DataFrame).
+ # type check
+ if not type(data)==pd.DataFrame:
+ raise f"Type of data should be Pandas.DataFrame; {type(data)} found"
+ for column in data.columns:
+ unique_categories = sorted(set(data[column]))
+ self.category_mapping[column] = {category: idx for idx, category in enumerate(unique_categories)}
+
+ def transform(self, data):
+ # Transform the data (pandas DataFrame) to ordinal integers.
+ # checking for empty mapping
+ if not self.category_mapping:
+ raise "Catrgorical Mapping not found. Call OrdinalExcoding.fit() method or call OrdinalEncoding.fit_transform() method"
+
+ data_transformed = data.copy()
+ for column in data.columns:
+ data_transformed[column] = data[column].map(self.category_mapping[column])
+ return data_transformed
+
+ def fit_transform(self, data):
+ # Fit the encoder and transform the data in one step.
+ self.fit(data)
+ return self.transform(data)
+
import os
+import sys
+# for resolving any path conflict
+current = os.path.dirname(os.path.realpath("ordinal_encoder.py"))
+parent = os.path.dirname(current)
+sys.path.append(current)
+
+import pandas as pd
+
+from Ordinal_Encoder.ordinal_encoder import OrdinalEncoding
+
+# Example usage
+data = {
+ 'Category1': ['low', 'medium', 'high', 'medium', 'low', 'high', 'medium'],
+ 'Category2': ['A', 'B', 'A', 'B', 'A', 'B', 'A'],
+ 'Category3': ['X', 'Y', 'X', 'Y', 'X', 'Y', 'X']
+}
+df = pd.DataFrame(data)
+
+encoder = OrdinalEncoding()
+encoded_df = encoder.fit_transform(df)
+
+print("Original DataFrame:")
+print(df)
+print("\nEncoded DataFrame:")
+print(encoded_df)
+
+ There are no items available at this time. Check back again later. +
+A custom implementation of a MinMaxScaler class for scaling numerical data in a pandas DataFrame. The class scales the features to a specified range, typically between 0 and 1.
+__init__(self, feature_range=(0, 1))
fit(self, data)
transform(self, data)
fit_transform(self, data)
get_params(self)
import pandas as pd
+
+# Custom MinMaxScaler class
+class MinMaxScaling:
+ # init function
+ def __init__(self, feature_range=(0, 1)): # feature range can be specified by the user else it takes (0,1)
+ self.min = feature_range[0]
+ self.max = feature_range[1]
+ self.data_min_ = None
+ self.data_max_ = None
+
+ # fit function to calculate min and max value of the data
+ def fit(self, data):
+ # type check
+ if not type(data)==pd.DataFrame:
+ raise f"TypeError : parameter should be a Pandas.DataFrame; {type(data)} found"
+ else:
+ self.data_min_ = data.min()
+ self.data_max_ = data.max()
+
+ # transform function
+ def transform(self, data):
+ if self.data_max_ is None or self.data_min_ is None:
+ raise "Call MinMaxScaling.fit() first or call MinMaxScaling.fit_transform() as the required params not found"
+ else:
+ data_scaled = (data - self.data_min_) / (self.data_max_ - self.data_min_)
+ data_scaled = data_scaled * (self.max - self.min) + self.min
+ return data_scaled
+
+ # fit_tranform function
+ def fit_transform(self, data):
+ self.fit(data)
+ return self.transform(data)
+
+ # get_params function
+ def get_params(self):
+ if self.data_max_ is None or self.data_min_ is None:
+ raise "Params not found! Call MinMaxScaling.fit() first"
+ else:
+ return {"Min" : self.data_min_,
+ "Max" : self.data_max_}
+
import os
+import sys
+# for resolving any path conflict
+current = os.path.dirname(os.path.realpath("min_max_scaler.py"))
+parent = os.path.dirname(current)
+sys.path.append(current)
+
+import pandas as pd
+
+from Min_Max_Scaler.min_max_scaler import MinMaxScaling
+
+# Example DataFrame
+data = {
+ 'A': [1, 2, 3, 4, 5],
+ 'B': [10, 20, 30, 40, 50],
+ 'C': [100, 200, 300, 400, 500]
+}
+
+df = pd.DataFrame(data)
+
+# Initialize the CustomMinMaxScaler
+scaler = MinMaxScaling()
+
+# Fit the scaler to the data and transform the data
+scaled_df = scaler.fit_transform(df)
+
+print("Original DataFrame:")
+print(df)
+print("\nScaled DataFrame:")
+print(scaled_df)
+
A custom implementation of a StandardScaler class for scaling numerical data in a pandas DataFrame or NumPy array. The class scales the features to have zero mean and unit variance.
+__init__(self)
fit(self, data)
transform(self, data)
fit_transform(self, data)
get_params(self)
import pandas as pd
+import numpy as np
+
+# Custom MinMaxScaler class
+class StandardScaling:
+ # init function
+ def __init__(self):
+ self.data_mean_ = None
+ self.data_std_ = None
+
+ # fit function to calculate min and max value of the data
+ def fit(self, data):
+ # type check
+ if not (type(data)==pd.DataFrame or type(data)==np.ndarray):
+ raise f"TypeError : parameter should be a Pandas.DataFrame or Numpy.ndarray; {type(data)} found"
+ elif type(data)==pd.DataFrame:
+ data = data.to_numpy()
+
+ self.data_mean_ = np.mean(data, axis=0)
+ self.data_std_ = np.sqrt(np.var(data, axis=0))
+
+ # transform function
+ def transform(self, data):
+ if self.data_mean_ is None or self.data_std_ is None:
+ raise "Call StandardScaling.fit() first or call StandardScaling.fit_transform() as the required params not found"
+ else:
+ data_scaled = (data - self.data_mean_) / (self.data_std_)
+ return data_scaled
+
+ # fit_tranform function
+ def fit_transform(self, data):
+ self.fit(data)
+ return self.transform(data)
+
+ # get_params function
+ def get_params(self):
+ if self.data_mean_ is None or self.data_std_ is None:
+ raise "Params not found! Call StandardScaling.fit() first"
+ else:
+ return {"Mean" : self.data_mean_,
+ "Standard Deviation" : self.data_std_}
+
import os
+import sys
+# for resolving any path conflict
+current = os.path.dirname(os.path.realpath("standard_scaler.py"))
+parent = os.path.dirname(current)
+sys.path.append(current)
+
+import pandas as pd
+
+from Standard_Scaler.standard_scaler import StandardScaling
+
+# Example DataFrame
+data = {
+ 'A': [1, 2, 3, 4, 5],
+ 'B': [10, 20, 30, 40, 50],
+ 'C': [100, 200, 300, 400, 500]
+}
+
+df = pd.DataFrame(data)
+
+# Initialize the CustomMinMaxScaler
+scaler = StandardScaling()
+
+# Fit the scaler to the data and transform the data
+scaled_df = scaler.fit_transform(df)
+
+print("Original DataFrame:")
+print(df)
+print("\nScaled DataFrame:")
+print(scaled_df)
+print("\nAssociated Parameters:")
+print(scaler.get_params())
+
+ There are no items available at this time. Check back again later. +
+Overview:
+AdaBoost (Adaptive Boosting) is one of the most popular ensemble methods for boosting weak learners to create a strong learner. It works by combining multiple "weak" models, typically decision stumps, and focusing more on the errors from previous models. This iterative process improves accuracy and reduces bias.
Visualization:
+
Iteration 1: Train weak model -> Update weights
+Iteration 2: Train weak model -> Update weights
+...
+Final Model: Combine weak models with weighted contributions
+
DecisionTreeRegressor
or DecisionTreeClassifier
). File: adaboost_model.py
+
import numpy as np
+from sklearn.tree import DecisionTreeRegressor
+
+class AdaBoostRegressor:
+ def __init__(self, n_estimators=50, learning_rate=1.0):
+ self.n_estimators = n_estimators
+ self.learning_rate = learning_rate
+ self.models = []
+ self.model_weights = []
+
+ def fit(self, X, y):
+ n_samples = X.shape[0]
+ # Initialize weights
+ sample_weights = np.ones(n_samples) / n_samples
+
+ for _ in range(self.n_estimators):
+ # Train weak model
+ model = DecisionTreeRegressor(max_depth=1)
+ model.fit(X, y, sample_weight=sample_weights)
+ predictions = model.predict(X)
+
+ # Calculate weighted error
+ error = np.sum(sample_weights * (y != predictions)) / np.sum(sample_weights)
+ if error > 0.5:
+ break
+
+ # Calculate model weight
+ model_weight = self.learning_rate * np.log((1 - error) / error)
+
+ # Update sample weights
+ sample_weights *= np.exp(model_weight * (y != predictions))
+ sample_weights /= np.sum(sample_weights)
+
+ self.models.append(model)
+ self.model_weights.append(model_weight)
+
+ def predict(self, X):
+ # Combine predictions from all models
+ final_prediction = sum(weight * model.predict(X) for model, weight in zip(self.models, self.model_weights))
+ return np.sign(final_prediction)
+
File: adaboost_model_test.py
+
import unittest
+import numpy as np
+from sklearn.datasets import make_regression
+from sklearn.metrics import mean_squared_error
+from adaboost_model import AdaBoostRegressor
+
+class TestAdaBoostRegressor(unittest.TestCase):
+
+ def test_adaboost(self):
+ # Generate synthetic dataset
+ X, y = make_regression(n_samples=100, n_features=1, noise=15, random_state=42)
+ y = np.sign(y) # Convert to classification-like regression
+
+ # Train AdaBoost Regressor
+ model = AdaBoostRegressor(n_estimators=10)
+ model.fit(X, y)
+
+ # Predict and Evaluate
+ predictions = model.predict(X)
+ mse = mean_squared_error(y, predictions)
+ self.assertTrue(mse < 0.5, "MSE is too high, AdaBoost not performing well")
+
+if __name__ == '__main__':
+ unittest.main()
+
Use datasets from sklearn
(e.g., make_regression
) to validate the implementation. Compare AdaBoost with other boosting models like Gradient Boosting and LightGBM to analyze performance differences.
This module contains an implementation of Decision Tree Regression, a versatile algorithm for predicting a continuous outcome based on input features.
+max_depth
: Maximum depth of the decision tree. Controls the complexity of the model.import numpy as np
+
+class DecisionTreeRegression:
+
+ def __init__(self, max_depth=None):
+ """
+ Constructor for the DecisionTreeRegression class.
+
+ Parameters:
+ - max_depth: Maximum depth of the decision tree.
+ """
+ self.max_depth = max_depth
+ self.tree = None
+
+ def _calculate_variance(self, y):
+ """
+ Calculate the variance of a set of target values.
+
+ Parameters:
+ - y: Target values (numpy array).
+
+ Returns:
+ - Variance of the target values.
+ """
+ return np.var(y)
+
+ def _split_dataset(self, X, y, feature_index, threshold):
+ """
+ Split the dataset based on a feature and threshold.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - feature_index: Index of the feature to split on.
+ - threshold: Threshold value for the split.
+
+ Returns:
+ - Left and right subsets of the dataset.
+ """
+ left_mask = X[:, feature_index] <= threshold
+ right_mask = ~left_mask
+ return X[left_mask], X[right_mask], y[left_mask], y[right_mask]
+
+ def _find_best_split(self, X, y):
+ """
+ Find the best split for the dataset.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+
+ Returns:
+ - Index of the best feature and the corresponding threshold.
+ """
+ m, n = X.shape
+ best_feature_index = None
+ best_threshold = None
+ best_variance_reduction = 0
+
+ initial_variance = self._calculate_variance(y)
+
+ for feature_index in range(n):
+ thresholds = np.unique(X[:, feature_index])
+
+ for threshold in thresholds:
+ # Split the dataset
+ _, _, y_left, y_right = self._split_dataset(X, y, feature_index, threshold)
+
+ # Calculate variance reduction
+ left_weight = len(y_left) / m
+ right_weight = len(y_right) / m
+ variance_reduction = initial_variance - (left_weight * self._calculate_variance(y_left) + right_weight * self._calculate_variance(y_right))
+
+ # Update the best split if variance reduction is greater
+ if variance_reduction > best_variance_reduction:
+ best_feature_index = feature_index
+ best_threshold = threshold
+ best_variance_reduction = variance_reduction
+
+ return best_feature_index, best_threshold
+
+ def _build_tree(self, X, y, depth):
+ """
+ Recursively build the decision tree.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - depth: Current depth of the tree.
+
+ Returns:
+ - Node of the decision tree.
+ """
+ # Check if max depth is reached or if all target values are the same
+ if depth == self.max_depth or np.all(y == y[0]):
+ return {'value': np.mean(y)}
+
+ # Find the best split
+ feature_index, threshold = self._find_best_split(X, y)
+
+ if feature_index is not None:
+ # Split the dataset
+ X_left, X_right, y_left, y_right = self._split_dataset(X, y, feature_index, threshold)
+
+ # Recursively build left and right subtrees
+ left_subtree = self._build_tree(X_left, y_left, depth + 1)
+ right_subtree = self._build_tree(X_right, y_right, depth + 1)
+
+ return {'feature_index': feature_index,
+ 'threshold': threshold,
+ 'left': left_subtree,
+ 'right': right_subtree}
+ else:
+ # If no split is found, return a leaf node
+ return {'value': np.mean(y)}
+
+ def fit(self, X, y):
+ """
+ Fit the Decision Tree Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ self.tree = self._build_tree(X, y, depth=0)
+
+ def _predict_single(self, node, x):
+ """
+ Recursively predict a single data point.
+
+ Parameters:
+ - node: Current node in the decision tree.
+ - x: Input features for prediction.
+
+ Returns:
+ - Predicted value.
+ """
+ if 'value' in node:
+ return node['value']
+ else:
+ if x[node['feature_index']] <= node['threshold']:
+ return self._predict_single(node['left'], x)
+ else:
+ return self._predict_single(node['right'], x)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ return np.array([self._predict_single(self.tree, x) for x in X])
+
import unittest
+import numpy as np
+from DecisionTreeRegressor import DecisionTreeRegression
+
+class TestDecisionTreeRegressor(unittest.TestCase):
+
+ def setUp(self):
+ # Create sample data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 2)
+ self.y_train = 2 * self.X_train[:, 0] + 3 * self.X_train[:, 1] + np.random.normal(0, 0.1, 100)
+
+ self.X_test = np.random.rand(10, 2)
+
+ def test_fit_predict(self):
+ # Test if the model can be fitted and predictions are made
+ dt_model = DecisionTreeRegression(max_depth=3)
+ dt_model.fit(self.X_train, self.y_train)
+
+ # Ensure predictions are made without errors
+ predictions = dt_model.predict(self.X_test)
+
+ # Add your specific assertions based on the expected behavior of your model
+ self.assertIsInstance(predictions, np.ndarray)
+ self.assertEqual(predictions.shape, (10,))
+
+ # Add more test cases as needed
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Elastic Net Regression, a powerful linear regression technique that combines both L1 (Lasso) and L2 (Ridge) regularization. Elastic Net is particularly useful when dealing with high-dimensional datasets and can effectively handle correlated features.
+alpha
: The regularization strength. A positive float value.l1_ratio
: The ratio of L1 regularization to L2 regularization. Should be between 0 and 1.max_iter
: The maximum number of iterations to run the optimization algorithm.tol
: The tolerance for the optimization. If the updates are smaller than this value, the optimization will stop.import numpy as np
+
+class ElasticNetRegression:
+ def __init__(self, alpha=1.0, l1_ratio=0.5, max_iter=1000, tol=1e-4):
+ self.alpha = alpha
+ self.l1_ratio = l1_ratio
+ self.max_iter = max_iter
+ self.tol = tol
+ self.coef_ = None
+ self.intercept_ = None
+
+ def fit(self, X, y):
+ n_samples, n_features = X.shape
+ self.coef_ = np.zeros(n_features)
+ self.intercept_ = 0
+ learning_rate = 0.01
+
+ for iteration in range(self.max_iter):
+ y_pred = np.dot(X, self.coef_) + self.intercept_
+ error = y - y_pred
+
+ gradient_w = (-2 / n_samples) * (X.T.dot(error)) + self.alpha * (self.l1_ratio * np.sign(self.coef_) + (1 - self.l1_ratio) * 2 * self.coef_)
+ gradient_b = (-2 / n_samples) * np.sum(error)
+
+ new_coef = self.coef_ - learning_rate * gradient_w
+ new_intercept = self.intercept_ - learning_rate * gradient_b
+
+ if np.all(np.abs(new_coef - self.coef_) < self.tol) and np.abs(new_intercept - self.intercept_) < self.tol:
+ break
+
+ self.coef_ = new_coef
+ self.intercept_ = new_intercept
+
+ def predict(self, X):
+ return np.dot(X, self.coef_) + self.intercept_
+
import unittest
+import numpy as np
+from sklearn.linear_model import ElasticNet
+from ElasticNetRegression import ElasticNetRegression
+
+class TestElasticNetRegression(unittest.TestCase):
+
+ def test_elastic_net_regression(self):
+ np.random.seed(42)
+ X_train = np.random.rand(100, 1) * 10
+ y_train = 2 * X_train.squeeze() + np.random.randn(100) * 2
+
+ X_test = np.array([[2.5], [5.0], [7.5]])
+
+ custom_model = ElasticNetRegression(alpha=1.0, l1_ratio=0.5)
+ custom_model.fit(X_train, y_train)
+ custom_predictions = custom_model.predict(X_test)
+
+ sklearn_model = ElasticNet(alpha=1.0, l1_ratio=0.5, max_iter=1000, tol=1e-4)
+ sklearn_model.fit(X_train, y_train)
+ sklearn_predictions = sklearn_model.predict(X_test)
+
+ np.testing.assert_allclose(custom_predictions, sklearn_predictions, rtol=1e-1)
+
+ train_predictions_custom = custom_model.predict(X_train)
+ train_predictions_sklearn = sklearn_model.predict(X_train)
+
+ custom_mse = np.mean((y_train - train_predictions_custom) ** 2)
+ sklearn_mse = np.mean((y_train - train_predictions_sklearn) ** 2)
+
+ print(f"Custom Model MSE: {custom_mse}")
+ print(f"Scikit-learn Model MSE: {sklearn_mse}")
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Gradient Boosting Regression, an ensemble learning method that combines multiple weak learners (typically decision trees) to create a more robust and accurate model for predicting continuous outcomes based on input features.
+n_estimators
: Number of boosting stages (trees) to be run.learning_rate
: Step size shrinkage to prevent overfitting.max_depth
: Maximum depth of each decision tree.import numpy as np
+
+class GradientBoostingRegression:
+ def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
+ """
+ Constructor for the GradientBoostingRegression class.
+
+ Parameters:
+ - n_estimators: Number of trees in the ensemble.
+ - learning_rate: Step size for each tree's contribution.
+ - max_depth: Maximum depth of each decision tree.
+ """
+ self.n_estimators = n_estimators
+ self.learning_rate = learning_rate
+ self.max_depth = max_depth
+ self.trees = []
+
+ def fit(self, X, y):
+ """
+ Fit the gradient boosting regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Initialize predictions with the mean of the target values
+ predictions = np.mean(y) * np.ones_like(y)
+
+ for _ in range(self.n_estimators):
+ # Compute residuals
+ residuals = y - predictions
+
+ # Fit a decision tree to the residuals
+ tree = self._fit_tree(X, residuals, depth=0)
+
+ # Update predictions using the tree's contribution scaled by the learning rate
+ predictions += self.learning_rate * self._predict_tree(X, tree)
+
+ # Save the tree in the ensemble
+ self.trees.append(tree)
+
+ def _fit_tree(self, X, y, depth):
+ """
+ Fit a decision tree to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - depth: Current depth of the tree.
+
+ Returns:
+ - Tree structure (dictionary).
+ """
+ if depth == self.max_depth:
+ # If the maximum depth is reached, return the mean of the target values
+ return np.mean(y)
+
+ # Find the best split point
+ feature_index, threshold = self._find_best_split(X, y)
+
+ if feature_index is None:
+ # If no split improves the purity, return the mean of the target values
+ return np.mean(y)
+
+ # Split the data
+ mask = X[:, feature_index] < threshold
+ left_tree = self._fit_tree(X[mask], y[mask], depth + 1)
+ right_tree = self._fit_tree(X[~mask], y[~mask], depth + 1)
+
+ # Return the tree structure
+ return {'feature_index': feature_index, 'threshold': threshold,
+ 'left_tree': left_tree, 'right_tree': right_tree}
+
+ def _find_best_split(self, X, y):
+ """
+ Find the best split point for a decision tree.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+
+ Returns:
+ - Best feature index and threshold for the split.
+ """
+ m, n = X.shape
+ if m <= 1:
+ return None, None # No split is possible
+
+ # Calculate the initial impurity
+ initial_impurity = self._calculate_impurity(y)
+
+ # Initialize variables to store the best split parameters
+ best_feature_index, best_threshold, best_impurity_reduction = None, None, 0
+
+ for feature_index in range(n):
+ # Sort the feature values and corresponding target values
+ sorted_indices = np.argsort(X[:, feature_index])
+ sorted_X = X[sorted_indices, feature_index]
+ sorted_y = y[sorted_indices]
+
+ # Initialize variables to keep track of impurity and counts for the left and right nodes
+ left_impurity, left_count = 0, 0
+ right_impurity, right_count = initial_impurity, m
+
+ for i in range(1, m):
+ # Update impurity and counts for the left and right nodes
+ value = sorted_X[i]
+ left_impurity += (i / m) * self._calculate_impurity(sorted_y[i-1:i+1])
+ left_count += 1
+ right_impurity -= ((i-1) / m) * self._calculate_impurity(sorted_y[i-1:i+1])
+ right_count -= 1
+
+ # Calculate impurity reduction
+ impurity_reduction = initial_impurity - (left_count / m * left_impurity + right_count / m * right_impurity)
+
+ # Check if this is the best split so far
+ if impurity_reduction > best_impurity_reduction:
+ best_feature_index = feature_index
+ best_threshold = value
+ best_impurity_reduction = impurity_reduction
+
+ return best_feature_index, best_threshold
+
+ def _calculate_impurity(self, y):
+ """
+ Calculate the impurity of a node.
+
+ Parameters:
+ - y: Target values (numpy array).
+
+ Returns:
+ - Impurity.
+ """
+ # For regression, impurity is the variance of the target values
+ return np.var(y)
+
+ def _predict_tree(self, X, tree):
+ """
+ Make predictions using a decision tree.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - tree: Tree structure (dictionary).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ if 'feature_index' not in tree:
+ # If the node is a leaf, return the constant value
+ return tree
+ else:
+ # Recursively traverse the tree
+ mask = X[:, tree['feature_index']] < tree['threshold']
+ return np.where(mask, self._predict_tree(X, tree['left_tree']), self._predict_tree(X, tree['right_tree']))
+
+ def predict(self, X):
+ """
+ Make predictions on new data using the Gradient Boosting Regression.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ predictions = np.sum(self.learning_rate * self._predict_tree(X, tree) for tree in self.trees)
+ return predictions
+
import unittest
+import numpy as np
+from GradientBoostingRegressor import GradientBoostingRegression
+
+class TestGradientBoostingRegressor(unittest.TestCase):
+
+ def setUp(self):
+ # Create sample data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 2)
+ self.y_train = 2 * self.X_train[:, 0] + 3 * self.X_train[:, 1] + np.random.normal(0, 0.1, 100)
+
+ self.X_test = np.random.rand(10, 2)
+
+ def test_fit_predict(self):
+ # Test if the model can be fitted and predictions are made
+ gbr_model = GradientBoostingRegression(n_estimators=5, learning_rate=0.1, max_depth=3)
+ gbr_model.fit(self.X_train, self.y_train)
+
+ # Ensure predictions are made without errors
+ predictions = gbr_model.predict(self.X_test)
+
+ # Add your specific assertions based on the expected behavior of your model
+ self.assertIsInstance(predictions, np.ndarray)
+ self.assertEqual(predictions.shape, (10,))
+
+ # Add more test cases as needed
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Huber Regression, a robust linear regression technique that combines the properties of both least squares and absolute error loss functions. Huber Regression is particularly useful when dealing with datasets that have outliers, as it is less sensitive to outliers compared to standard linear regression.
+Huber Regression is a regression algorithm that adds a penalty based on the Huber loss function. This loss function is quadratic for small errors and linear for large errors, providing robustness against outliers.
+alpha
: The regularization strength. A positive float value.epsilon
: The threshold for the Huber loss function. A positive float value.max_iter
: The maximum number of iterations to run the optimization algorithm.tol
: The tolerance for the optimization. If the updates are smaller than this value, the optimization will stop.import numpy as np
+
+class HuberRegression:
+ def __init__(self, alpha=1.0, epsilon=1.35, max_iter=1000, tol=1e-4):
+ self.alpha = alpha
+ self.epsilon = epsilon
+ self.max_iter = max_iter
+ self.tol = tol
+ self.coef_ = None
+ self.intercept_ = None
+
+ def fit(self, X, y):
+ n_samples, n_features = X.shape
+ self.coef_ = np.zeros(n_features)
+ self.intercept_ = 0
+ learning_rate = 0.01
+
+ for iteration in range(self.max_iter):
+ y_pred = np.dot(X, self.coef_) + self.intercept_
+ error = y - y_pred
+
+ # Compute Huber gradient
+ mask = np.abs(error) <= self.epsilon
+ gradient_w = (-2 / n_samples) * (X.T.dot(error * mask) + self.epsilon * np.sign(error) * (~mask)) + self.alpha * self.coef_
+ gradient_b = (-2 / n_samples) * (np.sum(error * mask) + self.epsilon * np.sign(error) * (~mask))
+
+ new_coef = self.coef_ - learning_rate * gradient_w
+ new_intercept = self.intercept_ - learning_rate * gradient_b
+
+ if np.all(np.abs(new_coef - self.coef_) < self.tol) and np.abs(new_intercept - self.intercept_) < self.tol:
+ break
+
+ self.coef_ = new_coef
+ self.intercept_ = new_intercept
+
+ def predict(self, X):
+ return np.dot(X, self.coef_) + self.intercept_
+
import unittest
+import numpy as np
+from sklearn.linear_model import HuberRegressor
+from HuberRegression import HuberRegression
+
+class TestHuberRegression(unittest.TestCase):
+
+ def test_huber_regression(self):
+ np.random.seed(42)
+ X_train = np.random.rand(100, 1) * 10
+ y_train = 2 * X_train.squeeze() + np.random.randn(100) * 2
+
+ X_test = np.array([[2.5], [5.0], [7.5]])
+
+ huber_model = HuberRegression(alpha=1.0, epsilon=1.35)
+ huber_model.fit(X_train, y_train)
+ huber_predictions = huber_model.predict(X_test)
+
+ sklearn_model = HuberRegressor(alpha=1.0, epsilon=1.35, max_iter=1000, tol=1e-4)
+ sklearn_model.fit(X_train, y_train)
+ sklearn_predictions = sklearn_model.predict(X_test)
+
+ np.testing.assert_allclose(huber_predictions, sklearn_predictions, rtol=1e-1)
+
+ train_predictions_huber = huber_model.predict(X_train)
+ train_predictions_sklearn = sklearn_model.predict(X_train)
+
+ huber_mse = np.mean((y_train - train_predictions_huber) ** 2)
+ sklearn_mse = np.mean((y_train - train_predictions_sklearn) ** 2)
+
+ print(f"Huber Model MSE: {huber_mse}")
+ print(f"Scikit-learn Model MSE: {sklearn_mse}")
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of K-Nearest Neighbors Regression, a simple yet effective algorithm for predicting continuous outcomes based on input features.
+k
: Number of neighbors to consider for prediction.import numpy as np
+
+class KNNRegression:
+ def __init__(self, k=5):
+ """
+ Constructor for the KNNRegression class.
+
+ Parameters:
+ - k: Number of neighbors to consider.
+ """
+ self.k = k
+ self.X_train = None
+ self.y_train = None
+
+ def fit(self, X, y):
+ """
+ Fit the KNN model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ self.X_train = X
+ self.y_train = y
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ predictions = []
+ for x in X:
+ # Calculate Euclidean distances between the input point and all training points
+ distances = np.linalg.norm(self.X_train - x, axis=1)
+
+ # Get indices of k-nearest neighbors
+ indices = np.argsort(distances)[:self.k]
+
+ # Average the target values of k-nearest neighbors
+ predicted_value = np.mean(self.y_train[indices])
+ predictions.append(predicted_value)
+
+ return np.array(predictions)
+
import unittest
+import numpy as np
+from KNearestNeighborsRegression import KNNRegression
+
+class TestKNNRegression(unittest.TestCase):
+
+ def test_knn_regression(self):
+ # Create synthetic data
+ np.random.seed(42)
+ X_train = np.random.rand(100, 1) * 10
+ y_train = 2 * X_train.squeeze() + np.random.randn(100) * 2 # Linear relationship with noise
+
+ X_test = np.array([[2.5], [5.0], [7.5]])
+
+ # Initialize and fit the KNN Regression model
+ knn_model = KNNRegression(k=3)
+ knn_model.fit(X_train, y_train)
+
+ # Test predictions
+ predictions = knn_model.predict(X_test)
+ expected_predictions = [2 * 2.5, 2 * 5.0, 2 * 7.5] # Assuming a linear relationship
+
+ # Check if predictions are close to the expected values
+ np.testing.assert_allclose(predictions, expected_predictions, rtol=1e-5)
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Lasso Regression, a linear regression technique with L1 regularization.
+Lasso Regression is a regression algorithm that adds a penalty term based on the absolute values of the coefficients. This penalty term helps in feature selection by driving some of the coefficients to exactly zero, effectively ignoring certain features.
+learning_rate
: The step size for gradient descent.lambda_param
: Regularization strength (L1 penalty).n_iterations
: The number of iterations for gradient descent.import numpy as np
+
+class LassoRegression:
+ def __init__(self, learning_rate=0.01, lambda_param=0.01, n_iterations=1000):
+ """
+ Constructor for the LassoRegression class.
+
+ Parameters:
+ - learning_rate: The step size for gradient descent.
+ - lambda_param: Regularization strength.
+ - n_iterations: The number of iterations for gradient descent.
+ """
+ self.learning_rate = learning_rate
+ self.lambda_param = lambda_param
+ self.n_iterations = n_iterations
+ self.weights = None
+ self.bias = None
+
+ def fit(self, X, y):
+ """
+ Fit the Lasso Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Initialize weights and bias
+ num_samples, num_features = X.shape
+ self.weights = np.zeros(num_features)
+ self.bias = 0
+
+ # Perform gradient descent
+ for _ in range(self.n_iterations):
+ predictions = np.dot(X, self.weights) + self.bias
+ errors = y - predictions
+
+ # Update weights and bias
+ self.weights += self.learning_rate * (1/num_samples) * (np.dot(X.T, errors) - self.lambda_param * np.sign(self.weights))
+ self.bias += self.learning_rate * (1/num_samples) * np.sum(errors)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ return np.dot(X, self.weights) + self.bias
+
import unittest
+import numpy as np
+from LassoRegression import LassoRegression
+
+class TestLassoRegression(unittest.TestCase):
+ def setUp(self):
+ # Create a sample dataset
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 2)
+ self.y_train = 3 * self.X_train[:, 0] + 2 * self.X_train[:, 1] + np.random.randn(100)
+
+ self.X_test = np.random.rand(10, 2)
+
+ def test_fit_predict(self):
+ # Test the fit and predict methods
+ model = LassoRegression(learning_rate=0.01, lambda_param=0.1, n_iterations=1000)
+ model.fit(self.X_train, self.y_train)
+ predictions = model.predict(self.X_test)
+
+ # Ensure predictions are of the correct shape
+ self.assertEqual(predictions.shape, (10,))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Logistic Regression, a popular algorithm for binary classification.
+learning_rate
: Step size for gradient descent.n_iterations
: Number of iterations for gradient descent.import numpy as np
+
+class LogisticRegression:
+ def __init__(self, learning_rate=0.01, n_iterations=1000):
+ """
+ Constructor for the LogisticRegression class.
+
+ Parameters:
+ - learning_rate: The step size for gradient descent.
+ - n_iterations: The number of iterations for gradient descent.
+ """
+ self.learning_rate = learning_rate
+ self.n_iterations = n_iterations
+ self.weights = None
+ self.bias = None
+
+ def _sigmoid(self, z):
+ """
+ Sigmoid activation function.
+
+ Parameters:
+ - z: Linear combination of input features and weights.
+
+ Returns:
+ - Sigmoid of z.
+ """
+ return 1 / (1 + np.exp(-z))
+
+ def _initialize_parameters(self, n_features):
+ """
+ Initialize weights and bias.
+
+ Parameters:
+ - n_features: Number of input features.
+
+ Returns:
+ - Initialized weights and bias.
+ """
+ self.weights = np.zeros(n_features)
+ self.bias = 0
+
+ def fit(self, X, y):
+ """
+ Fit the Logistic Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target labels (numpy array).
+ """
+ n_samples, n_features = X.shape
+ self._initialize_parameters(n_features)
+
+ for _ in range(self.n_iterations):
+ # Linear combination of features and weights
+ linear_combination = np.dot(X, self.weights) + self.bias
+
+ # Predictions using the sigmoid function
+ predictions = self._sigmoid(linear_combination)
+
+ # Update weights and bias using gradient descent
+ dw = (1 / n_samples) * np.dot(X.T, (predictions - y))
+ db = (1 / n_samples) * np.sum(predictions - y)
+
+ self.weights -= self.learning_rate * dw
+ self.bias -= self.learning_rate * db
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted labels (numpy array).
+ """
+ linear_combination = np.dot(X, self.weights) + self.bias
+ predictions = self._sigmoid(linear_combination)
+
+ # Convert probabilities to binary predictions (0 or 1)
+ return np.round(predictions)
+
import numpy as np
+import unittest
+from LogisticRegression import LogisticRegression
+
+class TestLogisticRegression(unittest.TestCase):
+ def setUp(self):
+ # Generate synthetic data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 2)
+ self.y_train = (np.random.rand(100) > 0.5).astype(int)
+
+ self.X_test = np.random.rand(20, 2)
+
+ def test_fit_predict(self):
+ model = LogisticRegression(learning_rate=0.01, n_iterations=1000)
+ model.fit(self.X_train, self.y_train)
+ predictions = model.predict(self.X_test)
+
+ self.assertEqual(predictions.shape, (20,))
+ self.assertTrue(np.all(predictions == 0) or np.all(predictions == 1))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Neural Network Regression, a powerful algorithm for predicting continuous outcomes based on input features.
+input_size
: Number of features in the input data.hidden_size
: Number of neurons in the hidden layer.output_size
: Number of output neurons.learning_rate
: Step size for updating weights during training.n_iterations
: Number of iterations for training the neural network.import numpy as np
+
+class NeuralNetworkRegression:
+ def __init__(self, input_size, hidden_size, output_size, learning_rate=0.01, n_iterations=1000):
+ """
+ Constructor for the NeuralNetworkRegression class.
+
+ Parameters:
+ - input_size: Number of input features.
+ - hidden_size: Number of neurons in the hidden layer.
+ - output_size: Number of output neurons.
+ - learning_rate: Step size for gradient descent.
+ - n_iterations: Number of iterations for gradient descent.
+ """
+ self.input_size = input_size
+ self.hidden_size = hidden_size
+ self.output_size = output_size
+ self.learning_rate = learning_rate
+ self.n_iterations = n_iterations
+
+ # Initialize weights and biases
+ self.weights_input_hidden = np.random.rand(self.input_size, self.hidden_size)
+ self.bias_hidden = np.zeros((1, self.hidden_size))
+ self.weights_hidden_output = np.random.rand(self.hidden_size, self.output_size)
+ self.bias_output = np.zeros((1, self.output_size))
+
+ def sigmoid(self, x):
+ """Sigmoid activation function."""
+ return 1 / (1 + np.exp(-x))
+
+ def sigmoid_derivative(self, x):
+ """Derivative of the sigmoid function."""
+ return x * (1 - x)
+
+ def fit(self, X, y):
+ """
+ Fit the Neural Network model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ for _ in range(self.n_iterations):
+ # Forward pass
+ hidden_layer_input = np.dot(X, self.weights_input_hidden) + self.bias_hidden
+ hidden_layer_output = self.sigmoid(hidden_layer_input)
+
+ output_layer_input = np.dot(hidden_layer_output, self.weights_hidden_output) + self.bias_output
+ predicted_output = self.sigmoid(output_layer_input)
+
+ # Backpropagation
+ error = y - predicted_output
+ output_delta = error * self.sigmoid_derivative(predicted_output)
+
+ hidden_layer_error = output_delta.dot(self.weights_hidden_output.T)
+ hidden_layer_delta = hidden_layer_error * self.sigmoid_derivative(hidden_layer_output)
+
+ # Update weights and biases
+ self.weights_hidden_output += hidden_layer_output.T.dot(output_delta) * self.learning_rate
+ self.bias_output += np.sum(output_delta, axis=0, keepdims=True) * self.learning_rate
+
+ self.weights_input_hidden += X.T.dot(hidden_layer_delta) * self.learning_rate
+ self.bias_hidden += np.sum(hidden_layer_delta, axis=0, keepdims=True) * self.learning_rate
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ hidden_layer_input = np.dot(X, self.weights_input_hidden) + self.bias_hidden
+ hidden_layer_output = self.sigmoid(hidden_layer_input)
+
+ output_layer_input = np.dot(hidden_layer_output, self.weights_hidden_output) + self.bias_output
+ predicted_output = self.sigmoid(output_layer_input)
+
+ return predicted_output
+
import numpy as np
+import unittest
+from NeuralNetworkRegression import NeuralNetworkRegression
+
+class TestNeuralNetworkRegression(unittest.TestCase):
+ def setUp(self):
+ # Generate synthetic data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 3)
+ self.y_train = np.random.rand(100, 1)
+
+ self.X_test = np.random.rand(10, 3)
+
+ def test_fit_predict(self):
+ # Initialize and fit the model
+ model = NeuralNetworkRegression(input_size=3, hidden_size=4, output_size=1, learning_rate=0.01, n_iterations=1000)
+ model.fit(self.X_train, self.y_train)
+
+ # Ensure predictions have the correct shape
+ predictions = model.predict(self.X_test)
+ self.assertEqual(predictions.shape, (10, 1))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Polynomial Regression, an extension of Linear Regression that models the relationship between the independent variable and the dependent variable as a polynomial.
+degree
: Degree of the polynomial.learning_rate
: The step size for gradient descent.n_iterations
: The number of iterations for gradient descent.import numpy as np
+
+# Polynomial regression implementation
+class PolynomialRegression:
+ def __init__(self, degree=2, learning_rate=0.01, n_iterations=1000):
+ """
+ Constructor for the PolynomialRegression class.
+
+ Parameters:
+ - degree: Degree of the polynomial.
+ - learning_rate: The step size for gradient descent.
+ - n_iterations: The number of iterations for gradient descent.
+ """
+ self.degree = degree
+ self.learning_rate = learning_rate
+ self.n_iterations = n_iterations
+ self.weights = None
+ self.bias = None
+
+ def _polynomial_features(self, X):
+ """
+ Create polynomial features up to the specified degree.
+
+ Parameters:
+ - X: Input features (numpy array).
+
+ Returns:
+ - Polynomial features (numpy array).
+ """
+ return np.column_stack([X ** i for i in range(1, self.degree + 1)])
+
+ def fit(self, X, y):
+ """
+ Fit the polynomial regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ X_poly = self._polynomial_features(X)
+ self.weights = np.zeros((X_poly.shape[1], 1))
+ self.bias = 0
+
+ for _ in range(self.n_iterations):
+ predictions = np.dot(X_poly, self.weights) + self.bias
+ errors = predictions - y
+
+ self.weights -= self.learning_rate * (1 / len(X_poly)) * np.dot(X_poly.T, errors)
+ self.bias -= self.learning_rate * (1 / len(X_poly)) * np.sum(errors)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ X_poly = self._polynomial_features(X)
+ return np.dot(X_poly, self.weights) + self.bias
+
import unittest
+import numpy as np
+from PolynomialRegression import PolynomialFeatures
+
+class TestPolynomialRegression(unittest.TestCase):
+
+ def setUp(self):
+ # Create synthetic data for testing
+ np.random.seed(42)
+ self.X_train = 2 * np.random.rand(100, 1)
+ self.y_train = 4 + 3 * self.X_train + np.random.randn(100, 1)
+
+ def test_fit_predict(self):
+ # Test the fit and predict methods
+ poly_model = PolynomialFeatures(degree=2)
+ poly_model.fit(self.X_train, self.y_train)
+
+ # Create test data
+ X_test = np.array([[1.5], [2.0]])
+
+ # Make predictions
+ predictions = poly_model.predict(X_test)
+
+ # Assert that the predictions are NumPy arrays
+ self.assertTrue(isinstance(predictions, np.ndarray))
+
+ # Assert that the shape of predictions is as expected
+ self.assertEqual(predictions.shape, (X_test.shape[0], 1))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Random Forest Regression, an ensemble learning method that combines multiple decision trees to create a more robust and accurate model for predicting continuous outcomes based on input features.
+n_trees
: Number of trees in the random forest.max_depth
: Maximum depth of each decision tree.max_features
: Maximum number of features to consider for each split.import numpy as np
+
+class RandomForestRegression:
+
+ def __init__(self, n_trees=100, max_depth=None, max_features=None):
+ """
+ Constructor for the RandomForestRegression class.
+
+ Parameters:
+ - n_trees: Number of trees in the random forest.
+ - max_depth: Maximum depth of each decision tree.
+ - max_features: Maximum number of features to consider for each split.
+ """
+ self.n_trees = n_trees
+ self.max_depth = max_depth
+ self.max_features = max_features
+ self.trees = []
+
+ def _bootstrap_sample(self, X, y):
+ """
+ Create a bootstrap sample of the dataset.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+
+ Returns:
+ - Bootstrap sample of X and y.
+ """
+ indices = np.random.choice(len(X), len(X), replace=True)
+ return X[indices], y[indices]
+
+ def _build_tree(self, X, y, depth):
+ """
+ Recursively build a decision tree.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - depth: Current depth of the tree.
+
+ Returns:
+ - Node of the decision tree.
+ """
+ if depth == self.max_depth or np.all(y == y[0]):
+ return {'value': np.mean(y)}
+
+ n_features = X.shape[1]
+ if self.max_features is None:
+ subset_features = np.arange(n_features)
+ else:
+ subset_features = np.random.choice(n_features, self.max_features, replace=False)
+
+ # Create a random subset of features for this tree
+ X_subset = X[:, subset_features]
+
+ # Create a bootstrap sample
+ X_bootstrap, y_bootstrap = self._bootstrap_sample(X_subset, y)
+
+ # Find the best split using the selected subset of features
+ feature_index, threshold = self._find_best_split(X_bootstrap, y_bootstrap, subset_features)
+
+ if feature_index is not None:
+ # Split the dataset
+ X_left, X_right, y_left, y_right = self._split_dataset(X, y, feature_index, threshold)
+
+ # Recursively build left and right subtrees
+ left_subtree = self._build_tree(X_left, y_left, depth + 1)
+ right_subtree = self._build_tree(X_right, y_right, depth + 1)
+
+ return {'feature_index': feature_index,
+ 'threshold': threshold,
+ 'left': left_subtree,
+ 'right': right_subtree}
+ else:
+ # If no split is found, return a leaf node
+ return {'value': np.mean(y)}
+
+ def _find_best_split(self, X, y, subset_features):
+ """
+ Find the best split for a subset of features.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - subset_features: Subset of features to consider.
+
+ Returns:
+ - Index of the best feature and the corresponding threshold.
+ """
+ m, n = X.shape
+ best_feature_index = None
+ best_threshold = None
+ best_variance_reduction = 0
+
+ initial_variance = self._calculate_variance(y)
+
+ for feature_index in subset_features:
+ thresholds = np.unique(X[:, feature_index])
+
+ for threshold in thresholds:
+ # Split the dataset
+ _, _, y_left, y_right = self._split_dataset(X, y, feature_index, threshold)
+
+ # Calculate variance reduction
+ left_weight = len(y_left) / m
+ right_weight = len(y_right) / m
+ variance_reduction = initial_variance - (left_weight * self._calculate_variance(y_left) + right_weight * self._calculate_variance(y_right))
+
+ # Update the best split if variance reduction is greater
+ if variance_reduction > best_variance_reduction:
+ best_feature_index = feature_index
+ best_threshold = threshold
+ best_variance_reduction = variance_reduction
+
+ return best_feature_index, best_threshold
+
+ def _calculate_variance(self, y):
+ """
+ Calculate the variance of a set of target values.
+
+ Parameters:
+ - y: Target values (numpy array).
+
+ Returns:
+ - Variance of the target values.
+ """
+ return np.var(y)
+
+ def _split_dataset(self, X, y, feature_index, threshold):
+ """
+ Split the dataset based on a feature and threshold.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ - feature_index: Index of the feature to split on.
+ - threshold: Threshold value for the split.
+
+ Returns:
+ - Left and right subsets of the dataset.
+ """
+ left_mask = X[:, feature_index] <= threshold
+ right_mask = ~left_mask
+ return X[left_mask], X[right_mask], y[left_mask], y[right_mask]
+
+ def fit(self, X, y):
+ """
+ Fit the Random Forest Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ self.trees = []
+ for _ in range(self.n_trees):
+ # Create a bootstrap sample for each tree
+ X_bootstrap, y_bootstrap = self._bootstrap_sample(X, y)
+
+ # Build a decision tree and add it to the forest
+ tree = self._build_tree(X_bootstrap, y_bootstrap, depth=0)
+ self.trees.append(tree)
+
+ def _predict_single(self, tree, x):
+ """
+ Recursively predict a single data point using a decision tree.
+
+ Parameters:
+ - tree: Decision tree node.
+ - x: Input features for prediction.
+
+ Returns:
+ - Predicted value.
+ """
+ if 'value' in tree:
+ return tree['value']
+ else:
+ if x[tree['feature_index']] <= tree['threshold']:
+ return self._predict_single(tree['left'], x)
+ else:
+ return self._predict_single(tree['right'], x)
+
+ def predict(self, X):
+ """
+ Make predictions on new data using the Random Forest.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ predictions = np.array([self._predict_single(tree, x) for x in X for tree in self.trees])
+ return np.mean(predictions.reshape(-1, len(self.trees)), axis=1)
+
import unittest
+import numpy as np
+from RandomForestRegressor import RandomForestRegression
+
+class TestRandomForestRegressor(unittest.TestCase):
+ def setUp(self):
+ # Create sample data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 2)
+ self.y_train = 2 * self.X_train[:, 0] + 3 * self.X_train[:, 1] + np.random.normal(0, 0.1, 100)
+
+ self.X_test = np.random.rand(10, 2)
+
+ def test_fit_predict(self):
+ # Test if the model can be fitted and predictions are made
+ rfr_model = RandomForestRegression(n_trees=5, max_depth=3, max_features=2)
+ rfr_model.fit(self.X_train, self.y_train)
+
+ # Ensure predictions are made without errors
+ predictions = rfr_model.predict(self.X_test)
+
+ # Add your specific assertions based on the expected behavior of your model
+ self.assertIsInstance(predictions, np.ndarray)
+ self.assertEqual(predictions.shape, (10,))
+
+ # Add more test cases as needed
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Ridge Regression, a linear regression variant that includes regularization to prevent overfitting.
+Ridge Regression is a linear regression technique with an added regularization term to handle multicollinearity and prevent the model from becoming too complex.
+alpha
: Regularization strength. A higher alpha increases the penalty for large coefficients.import numpy as np
+
+class RidgeRegression:
+ def __init__(self, alpha=1.0):
+ """
+ Constructor for the Ridge Regression class.
+
+ Parameters:
+ - alpha: Regularization strength. Higher values specify stronger regularization.
+ """
+ self.alpha = alpha
+ self.weights = None
+
+ def fit(self, X, y):
+ """
+ Fit the Ridge Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Add a column of ones to the input features for the bias term
+ X_bias = np.c_[np.ones(X.shape[0]), X]
+
+ # Compute the closed-form solution for Ridge Regression
+ identity_matrix = np.identity(X_bias.shape[1])
+ self.weights = np.linalg.inv(X_bias.T @ X_bias + self.alpha * identity_matrix) @ X_bias.T @ y
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ # Add a column of ones to the input features for the bias term
+ X_bias = np.c_[np.ones(X.shape[0]), X]
+
+ # Make predictions using the learned weights
+ predictions = X_bias @ self.weights
+
+ return predictions
+
import numpy as np
+import unittest
+from RidgeRegression import RidgeRegression # Assuming your RidgeRegression class is in a separate file
+
+class TestRidgeRegression(unittest.TestCase):
+ def test_fit_predict(self):
+ # Generate synthetic data for testing
+ np.random.seed(42)
+ X_train = np.random.rand(100, 2)
+ y_train = 3 * X_train[:, 0] + 5 * X_train[:, 1] + 2 + 0.1 * np.random.randn(100)
+ X_test = np.random.rand(20, 2)
+
+ # Create a Ridge Regression model
+ ridge_model = RidgeRegression(alpha=0.1)
+
+ # Fit the model to training data
+ ridge_model.fit(X_train, y_train)
+
+ # Make predictions on test data
+ predictions = ridge_model.predict(X_test)
+
+ # Ensure the predictions have the correct shape
+ self.assertEqual(predictions.shape, (20,))
+
+ def test_invalid_alpha(self):
+ # Check if an exception is raised for an invalid alpha value
+ with self.assertRaises(ValueError):
+ RidgeRegression(alpha=-1)
+
+ # Add more test cases as needed
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Support Vector Regression (SVR), a regression technique using Support Vector Machines (SVM) principles.
+epsilon
: Epsilon in the epsilon-SVR model. It specifies the epsilon-tube within which no penalty is associated in the training loss function.C
: Regularization parameter. The strength of the regularization is inversely proportional to C.import numpy as np
+
+class SupportVectorRegression:
+
+ def __init__(self, epsilon=0.1, C=1.0):
+ """
+ Constructor for the SupportVectorRegression class.
+
+ Parameters:
+ - epsilon: Epsilon in the epsilon-SVR model. It specifies the epsilon-tube within which no penalty is associated in the training loss function.
+ - C: Regularization parameter. The strength of the regularization is inversely proportional to C.
+ """
+ self.epsilon = epsilon
+ self.C = C
+ self.weights = None
+ self.bias = None
+
+ def _linear_kernel(self, X1, X2):
+ """
+ Linear kernel function.
+
+ Parameters:
+ - X1, X2: Input data (numpy arrays).
+
+ Returns:
+ - Linear kernel result (numpy array).
+ """
+ return np.dot(X1, X2.T)
+
+ def _compute_kernel_matrix(self, X):
+ """
+ Compute the kernel matrix for the linear kernel.
+
+ Parameters:
+ - X: Input data (numpy array).
+
+ Returns:
+ - Kernel matrix (numpy array).
+ """
+ m = X.shape[0]
+ kernel_matrix = np.zeros((m, m))
+
+ for i in range(m):
+ for j in range(m):
+ kernel_matrix[i, j] = self._linear_kernel(X[i, :], X[j, :])
+
+ return kernel_matrix
+
+ def fit(self, X, y):
+ """
+ Fit the Support Vector Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ m, n = X.shape
+
+ # Create the kernel matrix
+ kernel_matrix = self._compute_kernel_matrix(X)
+
+ # Quadratic programming problem coefficients
+ P = np.vstack([np.hstack([kernel_matrix, -kernel_matrix]),
+ np.hstack([-kernel_matrix, kernel_matrix])])
+ q = np.vstack([self.epsilon * np.ones((m, 1)) - y, self.epsilon * np.ones((m, 1)) + y])
+
+ # Constraints matrix
+ G = np.vstack([np.eye(2 * m), -np.eye(2 * m)])
+ h = np.vstack([self.C * np.ones((2 * m, 1)), np.zeros((2 * m, 1))])
+
+ # Solve the quadratic programming problem
+ solution = np.linalg.solve(P, q)
+
+ # Extract weights and bias
+ self.weights = solution[:n]
+ self.bias = solution[n]
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ predictions = np.dot(X, self.weights) + self.bias
+ return predictions
+
import unittest
+import numpy as np
+from SVR import SupportVectorRegression
+
+class TestSupportVectorRegression(unittest.TestCase):
+
+ def setUp(self):
+ # Create synthetic data for testing
+ np.random.seed(42)
+ self.X_train = 2 * np.random.rand(100, 1)
+ self.y_train = 4 + 3 * self.X_train + np.random.randn(100, 1)
+
+ def test_fit_predict(self):
+ # Test the fit and predict methods
+ svr_model = SupportVectorRegression(epsilon=0.1, C=1.0)
+ svr_model.fit(self.X_train, self.y_train)
+
+ # Create test data
+ X_test = np.array([[1.5], [2.0]])
+
+ # Make predictions
+ predictions = svr_model.predict(X_test)
+
+ # Assert that the predictions are NumPy arrays
+ self.assertTrue(isinstance(predictions, np.ndarray))
+
+ # Assert that the shape of predictions is as expected
+ self.assertEqual(predictions.shape, (X_test.shape[0], 1))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of the XGBoost Regressor, a popular ensemble learning algorithm that combines the predictions from multiple decision trees to create a more robust and accurate model for regression tasks.
+n_estimators
: Number of boosting rounds (trees).learning_rate
: Step size shrinkage to prevent overfitting.max_depth
: Maximum depth of each tree.gamma
: Minimum loss reduction required to make a further partition.import numpy as np
+from sklearn.tree import DecisionTreeRegressor
+
+class XGBoostRegressor:
+
+ def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3, gamma=0):
+ """
+ Constructor for the XGBoostRegressor class.
+
+ Parameters:
+ - n_estimators: Number of boosting rounds (trees).
+ - learning_rate: Step size shrinkage to prevent overfitting.
+ - max_depth: Maximum depth of each tree.
+ - gamma: Minimum loss reduction required to make a further partition.
+ """
+ self.n_estimators = n_estimators
+ self.learning_rate = learning_rate
+ self.max_depth = max_depth
+ self.gamma = gamma
+ self.trees = []
+
+ def fit(self, X, y):
+ """
+ Fit the XGBoost model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Initialize residuals
+ residuals = np.copy(y)
+
+ for _ in range(self.n_estimators):
+ # Fit a weak learner (decision tree) to the residuals
+ tree = DecisionTreeRegressor(max_depth=self.max_depth, min_samples_split=self.gamma)
+ tree.fit(X, residuals)
+
+ # Compute predictions from the weak learner
+ predictions = tree.predict(X)
+
+ # Update residuals with the weighted sum of previous residuals and predictions
+ residuals -= self.learning_rate * predictions
+
+ # Store the tree in the list
+ self.trees.append(tree)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ # Initialize predictions with zeros
+ predictions = np.zeros(X.shape[0])
+
+ # Make predictions using each tree and update the overall prediction
+ for tree in self.trees:
+ predictions += self.learning_rate * tree.predict(X)
+
+ return predictions
+
import unittest
+import numpy as np
+from XGBoostRegressor import XGBoostRegressor
+
+class TestXGBoostRegressor(unittest.TestCase):
+
+ def setUp(self):
+ # Generate synthetic data for testing
+ np.random.seed(42)
+ self.X_train = np.random.rand(100, 5)
+ self.y_train = np.random.rand(100)
+ self.X_test = np.random.rand(20, 5)
+
+ def test_fit_predict(self):
+ # Test the fit and predict methods
+ xgb_model = XGBoostRegressor(n_estimators=50, learning_rate=0.1, max_depth=3, gamma=0.1)
+ xgb_model.fit(self.X_train, self.y_train)
+ predictions = xgb_model.predict(self.X_test)
+
+ # Ensure predictions have the correct shape
+ self.assertEqual(predictions.shape, (20,))
+
+ def test_invalid_parameters(self):
+ # Test invalid parameter values
+ with self.assertRaises(ValueError):
+ XGBoostRegressor(n_estimators=-1, learning_rate=0.1, max_depth=3, gamma=0.1)
+
+ with self.assertRaises(ValueError):
+ XGBoostRegressor(n_estimators=50, learning_rate=-0.1, max_depth=3, gamma=0.1)
+
+ with self.assertRaises(ValueError):
+ XGBoostRegressor(n_estimators=50, learning_rate=0.1, max_depth=-3, gamma=0.1)
+
+ def test_invalid_fit(self):
+ # Test fitting with mismatched X_train and y_train shapes
+ xgb_model = XGBoostRegressor(n_estimators=50, learning_rate=0.1, max_depth=3, gamma=0.1)
+ with self.assertRaises(ValueError):
+ xgb_model.fit(self.X_train, np.random.rand(50))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of Bayesian Regression, a probabilistic approach to linear regression that provides uncertainty estimates for predictions.
+Bayesian Regression is an extension of traditional linear regression that models the distribution of coefficients, allowing for uncertainty in the model parameters. It's particularly useful when dealing with limited data and provides a full probability distribution over the possible values of the regression coefficients.
+alpha
: Prior precision for the coefficients.beta
: Precision of the noise in the observations.import numpy as np
+
+class BayesianRegression:
+ def __init__(self, alpha=1, beta=1):
+ """
+ Constructor for the BayesianRegression class.
+
+ Parameters:
+ - alpha: Prior precision.
+ - beta: Noise precision.
+ """
+ self.alpha = alpha
+ self.beta = beta
+ self.w_mean = None
+ self.w_precision = None
+
+ def fit(self, X, y):
+ """
+ Fit the Bayesian Regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Add a bias term to X
+ X = np.c_[np.ones(X.shape[0]), X]
+
+ # Compute posterior precision and mean
+ self.w_precision = self.alpha * np.eye(X.shape[1]) + self.beta * X.T @ X
+ self.w_mean = self.beta * np.linalg.solve(self.w_precision, X.T @ y)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ # Add a bias term to X
+ X = np.c_[np.ones(X.shape[0]), X]
+
+ # Compute predicted mean
+ y_pred = X @ self.w_mean
+
+ return y_pred
+
import unittest
+import numpy as np
+from BayesianRegression import BayesianRegression
+
+class TestBayesianRegression(unittest.TestCase):
+ def setUp(self):
+ # Generate synthetic data for testing
+ np.random.seed(42)
+ self.X_train = 2 * np.random.rand(100, 1)
+ self.y_train = 4 + 3 * self.X_train + np.random.randn(100, 1)
+
+ self.X_test = 2 * np.random.rand(20, 1)
+
+ def test_fit_predict(self):
+ blr = BayesianRegression()
+ blr.fit(self.X_train, self.y_train)
+ y_pred = blr.predict(self.X_test)
+
+ self.assertTrue(y_pred.shape == (20, 1))
+
+if __name__ == '__main__':
+ unittest.main()
+
This module contains an implementation of the Linear Regression algorithm, a fundamental technique in machine learning for predicting a continuous outcome based on input features.
+learning_rate
: The step size for gradient descent.n_iterations
: The number of iterations for gradient descent.import numpy as np
+
+# Linear regression implementation
+class LinearRegression:
+ def __init__(self, learning_rate=0.01, n_iterations=1000):
+ """
+ Constructor for the LinearRegression class.
+
+ Parameters:
+ - learning_rate: The step size for gradient descent.
+ - n_iterations: The number of iterations for gradient descent.
+ - n_iterations: n_epochs.
+ """
+ self.learning_rate = learning_rate
+ self.n_iterations = n_iterations
+ self.weights = None
+ self.bias = None
+
+ def fit(self, X, y):
+ """
+ Fit the linear regression model to the input data.
+
+ Parameters:
+ - X: Input features (numpy array).
+ - y: Target values (numpy array).
+ """
+ # Initialize weights and bias
+ self.weights = np.zeros((X.shape[1], 1))
+ self.bias = 0
+
+ # Gradient Descent
+ for _ in range(self.n_iterations):
+ # Compute predictions
+ predictions = np.dot(X, self.weights) + self.bias
+
+ # Calculate errors
+ errors = predictions - y
+
+ # Update weights and bias
+ self.weights -= self.learning_rate * (1 / len(X)) * np.dot(X.T, errors)
+ self.bias -= self.learning_rate * (1 / len(X)) * np.sum(errors)
+
+ def predict(self, X):
+ """
+ Make predictions on new data.
+
+ Parameters:
+ - X: Input features for prediction (numpy array).
+
+ Returns:
+ - Predicted values (numpy array).
+ """
+ return np.dot(X, self.weights) + self.bias
+
import unittest
+import numpy as np
+from LinearRegression import LinearRegression
+
+class TestLinearRegression(unittest.TestCase):
+
+ def setUp(self):
+ # Set up some common data for testing
+ np.random.seed(42)
+ self.X_train = 2 * np.random.rand(100, 1)
+ self.y_train = 4 + 3 * self.X_train + np.random.randn(100, 1)
+
+ self.X_test = 2 * np.random.rand(20, 1)
+ self.y_test = 4 + 3 * self.X_test + np.random.randn(20, 1)
+
+ def test_fit_predict(self):
+ # Test the fit and predict methods
+
+ # Create a LinearRegression model
+ lr_model = LinearRegression()
+
+ # Fit the model to the training data
+ lr_model.fit(self.X_train, self.y_train)
+
+ # Make predictions on the test data
+ predictions = lr_model.predict(self.X_test)
+
+ # Check that the predictions are of the correct shape
+ self.assertEqual(predictions.shape, self.y_test.shape)
+
+ def test_predict_with_unfitted_model(self):
+ # Test predicting with an unfitted model
+
+ # Create a LinearRegression model (not fitted)
+ lr_model = LinearRegression()
+
+ # Attempt to make predictions without fitting the model
+ with self.assertRaises(ValueError):
+ _ = lr_model.predict(self.X_test)
+
+if __name__ == '__main__':
+ unittest.main()
+
Overview:
+K-means clustering is an unsupervised machine learning algorithm for grouping similar data points together into clusters based on their features.
How K-means Works (Scratch Implementation Guide):
+Choose k
initial centroids randomly from the dataset.
Iterative Process:
+Check for Convergence: If the centroids do not change significantly between iterations (i.e., they converge), stop. Otherwise, repeat the process.
+Termination:
+The algorithm terminates either when the centroids have converged or when the maximum number of iterations is reached.
+Output:
+num_clusters
: Number of clusters to form.max_iterations
: Maximum number of iterations before stopping.show_steps
: Whether to visualize the clustering process step by step (Boolean).import numpy as np
+import matplotlib.pyplot as plt
+
+def euclidean_distance(point1, point2):
+ """
+ Calculate the Euclidean distance between two points in space.
+ """
+ return np.sqrt(np.sum((point1 - point2) ** 2))
+
+class KMeansClustering:
+ def __init__(self, num_clusters=5, max_iterations=100, show_steps=False):
+ """
+ Initialize the KMeans clustering model with the following parameters:
+ - num_clusters: Number of clusters we want to form
+ - max_iterations: Maximum number of iterations for the algorithm
+ - show_steps: Boolean flag to visualize the clustering process step by step
+ """
+ self.num_clusters = num_clusters
+ self.max_iterations = max_iterations
+ self.show_steps = show_steps
+ self.clusters = [[] for _ in range(self.num_clusters)] # Initialize empty clusters
+ self.centroids = [] # List to store the centroids of clusters
+
+ def fit_predict(self, data):
+ """
+ Fit the KMeans model on the data and predict the cluster labels for each data point.
+ """
+ self.data = data
+ self.num_samples, self.num_features = data.shape # Get number of samples and features
+ initial_sample_indices = np.random.choice(self.num_samples, self.num_clusters, replace=False)
+ self.centroids = [self.data[idx] for idx in initial_sample_indices]
+
+ for _ in range(self.max_iterations):
+ # Step 1: Assign each data point to the closest centroid to form clusters
+ self.clusters = self._assign_to_clusters(self.centroids)
+ if self.show_steps:
+ self._plot_clusters()
+
+ # Step 2: Calculate new centroids by averaging the data points in each cluster
+ old_centroids = self.centroids
+ self.centroids = self._calculate_new_centroids(self.clusters)
+
+ # Step 3: Check for convergence
+ if self._has_converged(old_centroids, self.centroids):
+ break
+ if self.show_steps:
+ self._plot_clusters()
+
+ return self._get_cluster_labels(self.clusters)
+
+ def _assign_to_clusters(self, centroids):
+ """
+ Assign each data point to the closest centroid based on Euclidean distance.
+ """
+ clusters = [[] for _ in range(self.num_clusters)]
+ for sample_idx, sample in enumerate(self.data):
+ closest_centroid_idx = self._find_closest_centroid(sample, centroids)
+ clusters[closest_centroid_idx].append(sample_idx)
+ return clusters
+
+ def _find_closest_centroid(self, sample, centroids):
+ """
+ Find the index of the closest centroid to the given data point (sample).
+ """
+ distances = [euclidean_distance(sample, centroid) for centroid in centroids]
+ closest_idx = np.argmin(distances) # Index of the closest centroid
+ return closest_idx
+
+ def _calculate_new_centroids(self, clusters):
+ """
+ Calculate new centroids by averaging the data points in each cluster.
+ """
+ centroids = np.zeros((self.num_clusters, self.num_features))
+ for cluster_idx, cluster in enumerate(clusters):
+ cluster_mean = np.mean(self.data[cluster], axis=0)
+ centroids[cluster_idx] = cluster_mean
+ return centroids
+
+ def _has_converged(self, old_centroids, new_centroids):
+ """
+ Check if the centroids have converged
+ """
+ distances = [euclidean_distance(old_centroids[i], new_centroids[i]) for i in range(self.num_clusters)]
+ return sum(distances) == 0 # If centroids haven't moved, they are converged
+
+ def _get_cluster_labels(self, clusters):
+ """
+ Get the cluster labels for each data point based on the final clusters.
+ """
+ labels = np.empty(self.num_samples)
+ for cluster_idx, cluster in enumerate(clusters):
+ for sample_idx in cluster:
+ labels[sample_idx] = cluster_idx
+ return labels
+
+ def _plot_clusters(self):
+ """
+ Visualize the clusters and centroids in a 2D plot using matplotlib.
+ """
+ fig, ax = plt.subplots(figsize=(12, 8))
+ for i, cluster in enumerate(self.clusters):
+ cluster_points = self.data[cluster]
+ ax.scatter(cluster_points[:, 0], cluster_points[:, 1])
+
+ for centroid in self.centroids:
+ ax.scatter(centroid[0], centroid[1], marker="x", color="black", linewidth=2)
+
+ plt.show()
+
```py +import unittest +import numpy as np +from kmeans_scratch import KMeansClustering
+class TestKMeansClustering(unittest.TestCase):
+def setUp(self):
+ np.random.seed(42)
+ self.X_train = np.vstack([
+ np.random.randn(100, 2) + np.array([5, 5]),
+ np.random.randn(100, 2) + np.array([-5, -5]),
+ np.random.randn(100, 2) + np.array([5, -5]),
+ np.random.randn(100, 2) + np.array([-5, 5])
+ ])
+
+def test_kmeans(self):
+ """Test the basic KMeans clustering functionality"""
+ kmeans = KMeansClustering(num_clusters=4, max_iterations=100, show_steps=False)
+
+ cluster_labels = kmeans.fit_predict(self.X_train)
+
+ unique_labels = np.unique(cluster_labels)
+ self.assertEqual(len(unique_labels), 4)
+ self.assertEqual(cluster_labels.shape, (self.X_train.shape[0],))
+ print("Cluster labels for the data points:")
+ print(cluster_labels)
+
if name == 'main': + unittest.main()
+ + + + + + + + + + + + + ++ There are no items available at this time. Check back again later. +
+import re
+import pandas as pd
+from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
+
+#data collection
+data = [
+ 'Fashion is an art form and expression.',
+ 'Style is a way to say who you are without having to speak.',
+ 'Fashion is what you buy, style is what you do with it.',
+ 'With fashion, you convey a message about yourself without uttering a single word'
+]
+
+#text processing
+
+def preprocess_text(text):
+ text = text.lower()
+ text = re.sub(r'[^a-zs]',' ',text)
+ return text
+
+preprocessed_data = [preprocess_text(doc) for doc in data]
+
+for i, doc in enumerate(preprocessed_data, 1):
+ print(f'Data-{i} {doc}')
+
+
+
+# removing words like the, is, are, and as they usually do not carry much useful information for the analysis.
+vectorizer = CountVectorizer(stop_words='english')
+X=vectorizer.fit_transform(preprocessed_data)
+Word=vectorizer.get_feature_names_out()
+
+bow_df = pd.DataFrame(X.toarray(),columns=Word)
+bow_df.index =[f'Data {i}' for i in range(1, len(data) + 1)]
+
+tfidf_transformer = TfidfTransformer()
+X_tfidf=tfidf_transformer.fit_transform(X)
+tfidf_df=pd.DataFrame(X_tfidf.toarray(), columns=Word)
+tfidf_df.index=[f'Data {i}' for i in range(1, len(data) + 1)]
+
+
+print()
+print("--------------------------------BoW Represention----------------------------")
+print(bow_df)
+
+print()
+print("--------------------------------TF-IDF Value----------------------------")
+print(tfidf_df)
+
The FastText
class implements a word representation and classification tool developed by Facebook's AI Research (FAIR) lab. FastText extends the Word2Vec model by representing each word as a bag of character n-grams. This approach helps capture subword information and improves the handling of rare words.
vocab_size
: Size of the vocabulary.embedding_dim
: Dimension of the word embeddings.n_gram_size
: Size of character n-grams.learning_rate
: Learning rate for updating embeddings.epochs
: Number of training epochs.build_vocab()
: Constructs the vocabulary from the input sentences and creates a reverse mapping of words to indices.get_ngrams()
: Generates character n-grams for a given word. It pads the word with <
and >
symbols to handle edge cases effectively.train()
: Updates word and context embeddings using a simple Stochastic Gradient Descent (SGD) approach. The loss is computed as the squared error between the predicted and actual values.predict()
: Calculates the dot product between the target word and context embeddings to predict word vectors.get_word_vector()
: Retrieves the embedding for a specific word from the trained model.get_embedding_matrix()
: Returns the normalized embedding matrix for better performance and stability.For more advanced implementations, consider using optimized libraries like the FastText library by Facebook or other frameworks that offer additional features and efficiency improvements.
+from fasttext import FastText
+
+# Example sentences
+sentences = [
+ "fast text is a library for efficient text classification",
+ "word embeddings are useful for NLP tasks",
+ "fasttext models can handle out-of-vocabulary words"
+]
+
+# Initialize and train FastText model
+fasttext_model = FastText(vocab_size=100, embedding_dim=50)
+fasttext_model.build_vocab(sentences)
+fasttext_model.train(sentences)
+
+# Get the vector for a word
+vector = fasttext_model.get_word_vector("fast")
+print(f"Vector for 'fast': {vector}")
+
import numpy as np
+from collections import defaultdict
+from sklearn.preprocessing import normalize
+
+class FastText:
+ def __init__(self, vocab_size, embedding_dim, n_gram_size=3, learning_rate=0.01, epochs=10):
+ self.vocab_size = vocab_size
+ self.embedding_dim = embedding_dim
+ self.n_gram_size = n_gram_size
+ self.learning_rate = learning_rate
+ self.epochs = epochs
+ self.word_embeddings = np.random.uniform(-0.1, 0.1, (vocab_size, embedding_dim))
+ self.context_embeddings = np.random.uniform(-0.1, 0.1, (vocab_size, embedding_dim))
+ self.vocab = {}
+ self.rev_vocab = {}
+
+ def build_vocab(self, sentences):
+ """
+ Build vocabulary from sentences.
+
+ Args:
+ sentences (list): List of sentences (strings).
+ """
+ word_count = defaultdict(int)
+ for sentence in sentences:
+ words = sentence.split()
+ for word in words:
+ word_count[word] += 1
+ self.vocab = {word: idx for idx, (word, _) in enumerate(word_count.items())}
+ self.rev_vocab = {idx: word for word, idx in self.vocab.items()}
+
+ def get_ngrams(self, word):
+ """
+ Get n-grams for a given word.
+
+ Args:
+ word (str): Input word.
+
+ Returns:
+ set: Set of n-grams.
+ """
+ ngrams = set()
+ word = '<' * (self.n_gram_size - 1) + word + '>' * (self.n_gram_size - 1)
+ for i in range(len(word) - self.n_gram_size + 1):
+ ngrams.add(word[i:i + self.n_gram_size])
+ return ngrams
+
+ def train(self, sentences):
+ """
+ Train the FastText model using the given sentences.
+
+ Args:
+ sentences (list): List of sentences (strings).
+ """
+ for epoch in range(self.epochs):
+ loss = 0
+ for sentence in sentences:
+ words = sentence.split()
+ for i, word in enumerate(words):
+ if word not in self.vocab:
+ continue
+ word_idx = self.vocab[word]
+ target_ngrams = self.get_ngrams(word)
+ for j in range(max(0, i - 1), min(len(words), i + 2)):
+ if i != j and words[j] in self.vocab:
+ context_idx = self.vocab[words[j]]
+ prediction = self.predict(word_idx, context_idx)
+ error = prediction - 1 if j == i + 1 else prediction
+ loss += error**2
+ self.word_embeddings[word_idx] -= self.learning_rate * error * self.context_embeddings[context_idx]
+ self.context_embeddings[context_idx] -= self.learning_rate * error * self.word_embeddings[word_idx]
+ print(f'Epoch {epoch + 1}/{self.epochs}, Loss: {loss}')
+
+ def predict(self, word_idx, context_idx):
+ """
+ Predict the dot product of the word and context embeddings.
+
+ Args:
+ word_idx (int): Index of the word.
+ context_idx (int): Index of the context word.
+
+ Returns:
+ float: Dot product.
+ """
+ return np.dot(self.word_embeddings[word_idx], self.context_embeddings[context_idx])
+
+ def get_word_vector(self, word):
+ """
+ Get the word vector for the specified word.
+
+ Args:
+ word (str): Input word.
+
+ Returns:
+ np.ndarray: Word vector.
+ """
+ if word in self.vocab:
+ return self.word_embeddings[self.vocab[word]]
+ else:
+ raise ValueError(f"Word '{word}' not found in vocabulary")
+
+ def get_embedding_matrix(self):
+ """
+ Get the normalized embedding matrix.
+
+ Returns:
+ np.ndarray: Normalized word embeddings.
+ """
+ return normalize(self.word_embeddings, axis=1)
+
The GloVe
class implements the Global Vectors for Word Representation algorithm, developed by Stanford researchers. GloVe generates dense vector representations of words, capturing semantic relationships between them. Unlike traditional one-hot encoding, GloVe produces low-dimensional, continuous vectors that convey meaningful information about words and their contexts.
Co-occurrence Matrix: GloVe starts by creating a co-occurrence matrix from a large corpus of text. This matrix counts how often words appear together within a given context window, capturing the frequency of word pairs.
+Weighted Least Squares: The main idea behind GloVe is to factorize this co-occurrence matrix to find word vectors that capture the relationships between words. It aims to represent words that frequently appear together in similar contexts with similar vectors.
+Weighting Function: To ensure that the optimization process doesn't get overwhelmed by very frequent co-occurrences, GloVe uses a weighting function. This function reduces the influence of extremely common word pairs.
+Training Objective: The goal is to adjust the word vectors so that their dot products align with the observed co-occurrence counts. This helps in capturing the similarity between words based on their contexts.
+GloVe’s training involves adjusting word vectors so that their interactions match the observed co-occurrence data. It focuses on ensuring that words appearing together often have similar vector representations.
+For more advanced implementations, consider using libraries like TensorFlow or PyTorch, which offer enhanced functionalities and optimizations.
+import numpy as np
+from preprocess import preprocess
+from vocab_and_matrix import build_vocab, build_cooccurrence_matrix
+from glove_model import GloVe
+
+# Example text corpus
+corpus = ["I love NLP", "NLP is a fascinating field", "Natural language processing with GloVe"]
+
+# Preprocess the corpus
+tokens = [token for sentence in corpus for token in preprocess(sentence)]
+
+# Build vocabulary and co-occurrence matrix
+word_to_index = build_vocab(tokens)
+cooccurrence_matrix = build_cooccurrence_matrix(tokens, word_to_index)
+
+# Initialize and train the GloVe model
+glove = GloVe(vocab_size=len(word_to_index), embedding_dim=50)
+glove.train(cooccurrence_matrix, epochs=100)
+
+# Get the word vector for 'nlp'
+word_vector = glove.get_word_vector('nlp', word_to_index)
+print(word_vector)
+
import numpy as np
+
+class GloVe:
+ def __init__(self, vocab_size, embedding_dim=50, x_max=100, alpha=0.75):
+ self.vocab_size = vocab_size
+ self.embedding_dim = embedding_dim
+ self.x_max = x_max
+ self.alpha = alpha
+ self.W = np.random.rand(vocab_size, embedding_dim)
+ self.W_tilde = np.random.rand(vocab_size, embedding_dim)
+ self.b = np.random.rand(vocab_size)
+ self.b_tilde = np.random.rand(vocab_size)
+ self.gradsq_W = np.ones((vocab_size, embedding_dim))
+ self.gradsq_W_tilde = np.ones((vocab_size, embedding_dim))
+ self.gradsq_b = np.ones(vocab_size)
+ self.gradsq_b_tilde = np.ones(vocab_size)
+
+ def weighting_function(self, x):
+ if x < self.x_max:
+ return (x / self.x_max) ** self.alpha
+ return 1.0
+
+ def train(self, cooccurrence_matrix, epochs=100, learning_rate=0.05):
+ for epoch in range(epochs):
+ total_cost = 0
+ for i in range(self.vocab_size):
+ for j in range(self.vocab_size):
+ if cooccurrence_matrix[i, j] == 0:
+ continue
+ X_ij = cooccurrence_matrix[i, j]
+ weight = self.weighting_function(X_ij)
+ cost = weight * (np.dot(self.W[i], self.W_tilde[j]) + self.b[i] + self.b_tilde[j] - np.log(X_ij)) ** 2
+ total_cost += cost
+
+ grad_common = weight * (np.dot(self.W[i], self.W_tilde[j]) + self.b[i] + self.b_tilde[j] - np.log(X_ij))
+ grad_W = grad_common * self.W_tilde[j]
+ grad_W_tilde = grad_common * self.W[i]
+ grad_b = grad_common
+ grad_b_tilde = grad_common
+
+ self.W[i] -= learning_rate * grad_W / np.sqrt(self.gradsq_W[i])
+ self.W_tilde[j] -= learning_rate * grad_W_tilde / np.sqrt(self.gradsq_W_tilde[j])
+ self.b[i] -= learning_rate * grad_b / np.sqrt(self.gradsq_b[i])
+ self.b_tilde[j] -= learning_rate * grad_b_tilde / np.sqrt(self.gradsq_b_tilde[j])
+
+ self.gradsq_W[i] += grad_W ** 2
+ self.gradsq_W_tilde[j] += grad_W_tilde ** 2
+ self.gradsq_b[i] += grad_b ** 2
+ self.gradsq_b_tilde[j] += grad_b_tilde ** 2
+
+ if epoch % 10 == 0:
+ print(f'Epoch: {epoch}, Cost: {total_cost}')
+
+ def get_word_vector(self, word, word_to_index):
+ if word in word_to_index:
+ word_index = word_to_index[word]
+ return self.W[word_index]
+ return None
+
import string
+
+def preprocess(text):
+ """
+ Preprocess the text by removing punctuation, converting to lowercase, and splitting into words.
+
+ Args:
+ text (str): Input text string.
+
+ Returns:
+ list: List of words (tokens).
+ """
+ text = text.translate(str.maketrans('', '', string.punctuation)).lower()
+ tokens = text.split()
+ return tokens
+
import numpy as np
+from collections import Counter
+
+def build_vocab(tokens):
+ """
+ Build vocabulary from tokens and create a word-to-index mapping.
+
+ Args:
+ tokens (list): List of words (tokens).
+
+ Returns:
+ dict: Word-to-index mapping.
+ """
+ vocab = Counter(tokens)
+ word_to_index = {word: i for i, word in enumerate(vocab)}
+ return word_to_index
+
+def build_cooccurrence_matrix(tokens, word_to_index, window_size=2):
+ """
+ Build the co-occurrence matrix from tokens using a specified window size.
+
+ Args:
+ tokens (list): List of words (tokens).
+ word_to_index (dict): Word-to-index mapping.
+ window_size (int): Context window size.
+
+ Returns:
+ np.ndarray: Co-occurrence matrix.
+ """
+ vocab_size = len(word_to_index)
+ cooccurrence_matrix = np.zeros((vocab_size, vocab_size))
+
+ for i, word in enumerate(tokens):
+ word_index = word_to_index[word]
+ context_start = max(0, i - window_size)
+ context_end = min(len(tokens), i + window_size + 1)
+
+ for j in range(context_start, context_end):
+ if i != j:
+ context_word = tokens[j]
+ context_word_index = word_to_index[context_word]
+ cooccurrence_matrix[word_index, context_word_index] += 1
+
+ return cooccurrence_matrix
+
Hello there! 🌟 Welcome to your first step into the fascinating world of Natural Language Processing (NLP) with the Natural Language Toolkit (NLTK). This guide is designed to be super beginner-friendly. We’ll cover everything from installation to basic operations with lots of explanations along the way. Let's get started!
+The Natural Language Toolkit (NLTK) is a comprehensive Python library for working with human language data (text). It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning. It also includes wrappers for industrial-strength NLP libraries.
+Key Features of NLTK:
+1.Corpora and Lexical Resources: NLTK includes access to a variety of text corpora and lexical resources, such as WordNet, the Brown Corpus, the Gutenberg Corpus, and many more.
+2.Text Processing Libraries: It provides tools for a wide range of text processing tasks:
+Tokenization (splitting text into words, sentences, etc.)
+Part-of-Speech (POS) tagging
+Named Entity Recognition (NER)
+Stemming and Lemmatization
+Parsing (syntax analysis)
+Semantic reasoning
+3.Classification and Machine Learning: NLTK includes various classifiers and machine learning algorithms that can be used for text classification tasks.
+4.Visualization and Demonstrations: It offers visualization tools for trees, graphs, and other linguistic structures. It also includes a number of interactive demonstrations and sample data.
+First, we need to install NLTK. Make sure you have Python installed on your system. If not, you can download it from python.org. Once you have Python, open your command prompt (or terminal) and type the following command: +
+To verify that NLTK is installed correctly, open a Python shell and import the library: +import nltk +If no errors occur, NLTK is successfully installed. +NLTK requires additional data packages for various functionalities. To download all the data packages, open a python shell and run : +
+Alternatively you can download specific data packages using : +nltk.download ('punkt') # Tokenizer for splitting sentences into words +nltk.download ('averaged_perceptron_tagger') # Part-of-speech tagger for tagging words with their parts of speech +nltk.download ('maxent_ne_chunker') # Named entity chunker for recognizing named entities in text +nltk.download ('words') # Corpus of English words required for many NLTK functions +Now that we have everything set up, let’s dive into some basic NLP operations with NLTK.
+Tokenization is the process of breaking down text into smaller pieces, like words or sentences. It's like cutting a big cake into smaller slices. +
from nltk.tokenize import word_tokenize, sent_tokenize
+
+#Sample text to work with
+text = "Natural Language Processing with NLTK is fun and educational."
+
+#Tokenize into words
+words = word_tokenize(text)
+print("Word Tokenization:", words)
+
+#Tokenize into sentences
+sentences = sent_tokenize(text)
+print("Sentence Tokenization:", sentences)
+
Sentence Tokenization: ['Natural Language Processing with NLTK is fun and educational.']
+Stopwords are common words that don’t carry much meaning on their own. In many NLP tasks, we remove these words to focus on the important ones. +
from nltk.corpus import stopwords
+
+# Get the list of stopwords in English
+stop_words = set(stopwords.words('english'))
+
+# Remove stopwords from our list of words
+filtered_words = [word for word in words if word.lower() not in stop_words]
+
+print("Filtered Words:", filtered_words)
+
stopwords.words('english'): This gives us a list of common English stopwords.
+[word for word in words if word.lower() not in stop_words]: This is a list comprehension that filters out the stopwords from our list of words.
+Stemming is the process of reducing words to their root form. It’s like finding the 'stem' of a word. +
from nltk.stem import PorterStemmer
+
+# Create a PorterStemmer object
+ps = PorterStemmer()
+
+# Stem each word in our list of words
+stemmed_words = [ps.stem(word) for word in words]
+
+print("Stemmed Words:", stemmed_words)
+
PorterStemmer(): This creates a PorterStemmer object, which is a popular stemming algorithm.
+[ps.stem(word) for word in words]: This applies the stemming algorithm to each word in our list.
+Lemmatization is similar to stemming but it uses a dictionary to find the base form of a word. It’s more accurate than stemming. +
from nltk.stem import WordNetLemmatizer
+
+# Create a WordNetLemmatizer object
+lemmatizer = WordNetLemmatizer()
+
+# Lemmatize each word in our list of words
+lemmatized_words = [lemmatizer.lemmatize(word) for word in words]
+
+print("Lemmatized Words:", lemmatized_words)
+
WordNetLemmatizer(): This creates a lemmatizer object.
+[lemmatizer.lemmatize(word) for word in words]: This applies the lemmatization process to each word in our list.
+Part-of-speech tagging is the process of labeling each word in a sentence with its corresponding part of speech, such as noun, verb, adjective, etc. NLTK provides functionality to perform POS tagging easily. +
# Import the word_tokenize function from nltk.tokenize module
+# Import the pos_tag function from nltk module
+from nltk.tokenize import word_tokenize
+from nltk import pos_tag
+
+# Sample text to work with
+text = "NLTK is a powerful tool for natural language processing."
+
+# Tokenize the text into individual words
+# The word_tokenize function splits the text into a list of words
+words = word_tokenize(text)
+
+# Perform Part-of-Speech (POS) tagging
+# The pos_tag function takes a list of words and assigns a part-of-speech tag to each word
+pos_tags = pos_tag(words)
+
+# Print the part-of-speech tags
+print("Part-of-speech tags:")
+print(pos_tags)
+
pos_tags = pos_tag(words): The pos_tag function takes the list of words and assigns a part-of-speech tag to each word. For example, it might tag 'NLTK' as a proper noun (NNP), 'is' as a verb (VBZ), and so on.
+Here is a list of common POS tags used in the Penn Treebank tag set, along with explanations and examples:
+CC: Coordinating conjunction (e.g., and, but, or)
+CD: Cardinal number (e.g., one, two)
+DT: Determiner (e.g., the, a, an)
+EX: Existential there (e.g., there is)
+FW: Foreign word (e.g., en route)
+IN: Preposition or subordinating conjunction (e.g., in, of, like)
+JJ: Adjective (e.g., big, blue, fast)
+JJR: Adjective, comparative (e.g., bigger, faster)
+JJS: Adjective, superlative (e.g., biggest, fastest)
+LS: List item marker (e.g., 1, 2, One)
+MD: Modal (e.g., can, will, must)
+NN: Noun, singular or mass (e.g., dog, city, music)
+NNS: Noun, plural (e.g., dogs, cities)
+NNP: Proper noun, singular (e.g., John, London)
+NNPS: Proper noun, plural (e.g., Americans, Sundays)
+PDT: Predeterminer (e.g., all, both, half)
+POS: Possessive ending (e.g., 's, s')
+PRP: Personal pronoun (e.g., I, you, he)
+PRP$: Possessive pronoun (e.g., my, your, his)
+RB: Adverb (e.g., quickly, softly)
+RBR: Adverb, comparative (e.g., faster, harder)
+RBS: Adverb, superlative (e.g., fastest, hardest)
+RP: Particle (e.g., up, off)
+SYM: Symbol (e.g., $, %, &)
+TO: to (e.g., to go, to read)
+UH: Interjection (e.g., uh, well, wow)
+VB: Verb, base form (e.g., run, eat)
+VBD: Verb, past tense (e.g., ran, ate)
+VBG: Verb, gerund or present participle (e.g., running, eating)
+VBN: Verb, past participle (e.g., run, eaten)
+VBP: Verb, non-3rd person singular present (e.g., run, eat)
+VBZ: Verb, 3rd person singular present (e.g., runs, eats)
+WDT: Wh-determiner (e.g., which, that)
+WP: Wh-pronoun (e.g., who, what)
+WP$: Possessive wh-pronoun (e.g., whose)
+WRB: Wh-adverb (e.g., where, when)
+ + + + + + + + + + + + + +Natural Language Processing (NLP) is a field of artificial intelligence that enables computers to understand, interpret, and respond to human language. It bridges the gap between human communication and machine understanding, making it possible for computers to interact with us in a natural and intuitive way.
+NLP is essential for various applications that we use daily, such as:
+Voice assistants like Siri and Alexa use NLP to understand and respond to user commands. For example, when you ask, "What's the weather today?", NLP helps the assistant interpret your query and provide the relevant weather information.
+Many companies use chatbots to handle customer inquiries. NLP enables these bots to understand customer questions and provide accurate responses, improving customer satisfaction and reducing response time.
+NLP powers translation services like Google Translate, which can translate text from one language to another. This helps break down language barriers and facilitates global communication.
+Businesses use sentiment analysis to monitor social media and understand public opinion about their products or services. NLP analyzes text to determine whether the sentiment expressed is positive, negative, or neutral.
+NLP algorithms can summarize long articles into concise summaries, making it easier for readers to grasp the main points quickly. This is particularly useful for news articles and research papers.
+NLP is a dynamic and rapidly evolving field that plays a crucial role in how we interact with technology. By understanding its basics and key concepts, you can start exploring the fascinating world of language and machines.
+++ + + + + + + + + + + + + +This README provides a brief introduction to NLP. For a deeper dive, explore more resources and start building your own NLP projects!
+
Tokenization is the process of splitting text into individual words or sentences.
+import nltk
+nltk.download('punkt')
+from nltk.tokenize import sent_tokenize
+
+text = "Hello World. This is NLTK. It is great for text processing."
+sentences = sent_tokenize(text)
+print(sentences)
+
Stop words are common words that may not be useful for text analysis (e.g., "is", "the", "and").
+from nltk.corpus import stopwords
+nltk.download('stopwords')
+
+stop_words = set(stopwords.words('english'))
+filtered_words = [word for word in words if word.lower() not in stop_words]
+print(filtered_words)
+
Stemming reduces words to their root form by chopping off the ends. +
from nltk.stem import PorterStemmer
+stemmer = PorterStemmer()
+stemmed_words = [stemmer.stem(word) for word in filtered_words]
+print(stemmed_words)
+
Lemmatization reduces words to their base form (lemma), taking into account the meaning of the word. +
from nltk.stem import WordNetLemmatizer
+nltk.download('wordnet')
+
+lemmatizer = WordNetLemmatizer()
+lemmatized_words = [lemmatizer.lemmatize(word) for word in filtered_words]
+print(lemmatized_words)
+
Tagging words with their parts of speech (POS) helps understand the grammatical structure.
+The complete POS tag list can be accessed from the Installation and set-up notebook. +
nltk.download('averaged_perceptron_tagger')
+
+pos_tags = nltk.pos_tag(lemmatized_words)
+print(pos_tags)
+
Identify named entities such as names of people, organizations, locations, etc.
+# Numpy is required to run this
+%pip install numpy
+
+nltk.download('maxent_ne_chunker')
+nltk.download('words')
+from nltk.chunk import ne_chunk
+
+named_entities = ne_chunk(pos_tags)
+print(named_entities)
+
Count the frequency of each word in the text.
+from nltk.probability import FreqDist
+
+freq_dist = FreqDist(lemmatized_words)
+print(freq_dist.most_common(5))
+
Remove punctuation from the text.
+import string
+
+no_punct = [word for word in lemmatized_words if word not in string.punctuation]
+print(no_punct)
+
Convert all words to lowercase.
+ +Correct the spelling of words.
+%pip install pyspellchecker
+
+from nltk.corpus import wordnet
+from spellchecker import SpellChecker
+
+spell = SpellChecker()
+
+def correct_spelling(word):
+ if not wordnet.synsets(word):
+ return spell.correction(word)
+ return word
+
+lemmatized_words = ['hello', 'world', '.', 'klown', 'taxt', 'procass', '.']
+words_with_corrected_spelling = [correct_spelling(word) for word in lemmatized_words]
+print(words_with_corrected_spelling)
+
Remove numerical values from the text.
+lemmatized_words = ['hello', 'world', '88', 'text', 'process', '.']
+
+no_numbers = [word for word in lemmatized_words if not word.isdigit()]
+print(no_numbers)
+
Replace specific words with other words (e.g., replacing slang with formal words).
+lemmatized_words = ['hello', 'world', 'gr8', 'text', 'NLTK', '.']
+replacements = {'NLTK': 'Natural Language Toolkit', 'gr8' : 'great'}
+
+replaced_words = [replacements.get(word, word) for word in lemmatized_words]
+print(replaced_words)
+
Replace words with their synonyms.
+from nltk.corpus import wordnet
+lemmatized_words = ['hello', 'world', 'awesome', 'text', 'great', '.']
+
+def get_synonym(word):
+ synonyms = wordnet.synsets(word)
+ if synonyms:
+ return synonyms[0].lemmas()[0].name()
+ return word
+
+synonym_replaced = [get_synonym(word) for word in lemmatized_words]
+print(synonym_replaced)
+
Extract bigrams (pairs of consecutive words) and trigrams (triplets of consecutive words).
+from nltk import bigrams
+
+bigrams_list = list(bigrams(lemmatized_words))
+print(bigrams_list)
+
+from nltk import trigrams
+
+trigrams_list = list(trigrams(lemmatized_words))
+print(trigrams_list)
+
Split text into sentences while considering abbreviations and other punctuation complexities.
+import nltk.data
+
+text = 'Hello World. This is NLTK. It is great for text preprocessing.'
+
+# Load the sentence tokenizer
+tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
+
+# Tokenize the text into sentences
+sentences = tokenizer.tokenize(text)
+
+# Print the tokenized sentences
+print(sentences)
+
Identify and display the frequency of words in a text.
+from nltk.probability import FreqDist
+
+lemmatized_words = ['hello', 'hello', 'awesome', 'text', 'great', '.', '.', '.']
+
+
+word_freq = FreqDist(lemmatized_words)
+for word, freq in word_freq.items():
+ print(f"{word}: {freq}")
+
Remove HTML tags from the text. +
%pip install bs4
+
+from bs4 import BeautifulSoup
+
+html_text = "<p>Hello World. This is NLTK.</p>"
+soup = BeautifulSoup(html_text, "html.parser")
+cleaned_text = soup.get_text()
+print(cleaned_text)
+
Detect the language of the text. +
%pip install langdetect
+
+from langdetect import detect
+
+language = detect(text)
+print(language) #`en` (for English)
+
Use Regular Expressions to tokenize text. +
text = 'Hello World. This is NLTK. It is great for text preprocessing.'
+
+from nltk.tokenize import regexp_tokenize
+
+pattern = r'\w+'
+regex_tokens = regexp_tokenize(text, pattern)
+print(regex_tokens)
+
Removes frequent words (also known as “high-frequency words”) from a list of tokens using NLTK, you can use the nltk.FreqDist() function to calculate the frequency of each word and filter out the most common ones. +
import nltk
+
+# input text
+text = "Natural language processing is a field of AI. I love AI."
+
+# tokenize the text
+tokens = nltk.word_tokenize(text)
+
+# calculate the frequency of each word
+fdist = nltk.FreqDist(tokens)
+
+# remove the most common words (e.g., the top 10% of words by frequency)
+filtered_tokens = [token for token in tokens if fdist[token] < fdist.N() * 0.1]
+
+print("Tokens without frequent words:", filtered_tokens)
+
Tokenizes the input string into individual sentences and remove any leading or trailing whitespace from each sentence. +
import nltk.data
+
+# Text data
+text = 'Hello World. This is NLTK. It is great for text preprocessing.'
+
+# Load the sentence tokenizer
+tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
+
+# Tokenize the text into sentences
+sentences = tokenizer.tokenize(text)
+
+# Remove extra whitespace from each sentence
+sentences = [sentence.strip() for sentence in sentences]
+
+# Print the tokenized sentences
+print(sentences)
+
The TFIDF
class converts a collection of documents into their respective TF-IDF (Term Frequency-Inverse Document Frequency) representations. TF-IDF is a statistical measure used to evaluate the importance of a word in a document relative to a collection of documents (corpus).
The TFIDF
class is initialized with two main attributes:
self.vocabulary
: A dictionary that maps words to their indices in the TF-IDF matrix.self.idf_values
: A dictionary that stores the IDF (Inverse Document Frequency) values for each word.documents
(list of str): List of documents where each document is a string.Calculate the IDF values for all unique words in the corpus.
+documents
(list of str): A list where each entry is a document in the form of a string.Convert each document into a numerical representation that shows the importance of each word.
+Perform both fitting (computing IDF values) and transforming (converting documents to TF-IDF representation) in one step.
+The TFIDF
class includes methods for fitting the model to the data, transforming new data into the TF-IDF representation, and combining these steps. Here's a breakdown of the primary methods:
fit
Method: Calculates IDF values for all unique words in the corpus. It counts the number of documents containing each word and computes the IDF. The vocabulary is built with a word-to-index mapping.
transform
Method: Converts each document into a TF-IDF representation. It computes Term Frequency (TF) for each word in the document, calculates TF-IDF by multiplying TF with IDF, and stores these values in a matrix where each row corresponds to a document.
fit_transform
Method: Combines the fitting and transforming steps into a single method for efficient processing of documents.
import math
+from collections import Counter
+
+class TFIDF:
+ def __init__(self):
+ self.vocabulary = {} # Vocabulary to store word indices
+ self.idf_values = {} # IDF values for words
+
+ def fit(self, documents):
+ """
+ Compute IDF values based on the provided documents.
+
+ Args:
+ documents (list of str): List of documents where each document is a string.
+ """
+ doc_count = len(documents)
+ term_doc_count = Counter() # To count the number of documents containing each word
+
+ # Count occurrences of words in documents
+ for doc in documents:
+ words = set(doc.split()) # Unique words in the current document
+ for word in words:
+ term_doc_count[word] += 1
+
+ # Compute IDF values
+ self.idf_values = {
+ word: math.log(doc_count / (count + 1)) # +1 to avoid division by zero
+ for word, count in term_doc_count.items()
+ }
+
+ # Build vocabulary
+ self.vocabulary = {word: idx for idx, word in enumerate(self.idf_values.keys())}
+
+ def transform(self, documents):
+ """
+ Transform documents into TF-IDF representation.
+
+ Args:
+ documents (list of str): List of documents where each document is a string.
+
+ Returns:
+ list of list of float: TF-IDF matrix where each row corresponds to a document.
+ """
+ rows = []
+ for doc in documents:
+ words = doc.split()
+ word_count = Counter(words)
+ doc_length = len(words)
+ row = [0] * len(self.vocabulary)
+
+ for word, count in word_count.items():
+ if word in self.vocabulary:
+ tf = count / doc_length
+ idf = self.idf_values[word]
+ index = self.vocabulary[word]
+ row[index] = tf * idf
+ rows.append(row)
+ return rows
+
+ def fit_transform(self, documents):
+ """
+ Compute IDF values and transform documents into TF-IDF representation.
+
+ Args:
+ documents (list of str): List of documents where each document is a string.
+
+ Returns:
+ list of list of float: TF-IDF matrix where each row corresponds to a document.
+ """
+ self.fit(documents)
+ return self.transform(documents)
+# Example usage
+if __name__ == "__main__":
+ documents = [
+ "the cat sat on the mat",
+ "the dog ate my homework",
+ "the cat ate the dog food",
+ "I love programming in Python",
+ "Machine learning is fun",
+ "Python is a versatile language",
+ "Learning new skills is always beneficial"
+ ]
+
+ # Initialize the TF-IDF model
+ tfidf = TFIDF()
+
+ # Fit the model and transform the documents
+ tfidf_matrix = tfidf.fit_transform(documents)
+
+ # Print the vocabulary
+ print("Vocabulary:", tfidf.vocabulary)
+
+ # Print the TF-IDF representation
+ print("TF-IDF Representation:")
+ for i, vector in enumerate(tfidf_matrix):
+ print(f"Document {i + 1}: {vector}")
+
+ # More example documents with mixed content
+ more_documents = [
+ "the quick brown fox jumps over the lazy dog",
+ "a journey of a thousand miles begins with a single step",
+ "to be or not to be that is the question",
+ "the rain in Spain stays mainly in the plain",
+ "all human beings are born free and equal in dignity and rights"
+ ]
+
+ # Fit the model and transform the new set of documents
+ tfidf_more = TFIDF()
+ tfidf_matrix_more = tfidf_more.fit_transform(more_documents)
+
+ # Print the vocabulary for the new documents
+ print("\nVocabulary for new documents:", tfidf_more.vocabulary)
+
+ # Print the TF-IDF representation for the new documents
+ print("TF-IDF Representation for new documents:")
+ for i, vector in enumerate(tfidf_matrix_more):
+ print(f"Document {i + 1}: {vector}")
+
Welcome to the official documentation for the Transformers library! 🚀 This library, developed by Hugging Face, is designed to provide state-of-the-art natural language processing (NLP) models and tools. It's widely used for a variety of NLP tasks, including text classification, translation, summarization, and more.
+Transformers are a type of deep learning model that excel in handling sequential data, like text. They rely on mechanisms such as attention to process and generate text in a way that captures long-range dependencies and contextual information.
+To get started with the Transformers library, you need to install it via pip:
+ +Here's a basic example to demonstrate how to use the library for sentiment classification:
+from transformers import pipeline
+
+# Initialize the pipeline for sentiment analysis
+classifier = pipeline('sentiment-analysis')
+
+# Analyze sentiment of a sample text
+result = classifier("Transformers are amazing for NLP tasks! 🌟")
+
+print(result)
+
For comprehensive guides, tutorials, and API references, check out the following resources:
+Join the vibrant community of Transformers users and contributors to get support, share your work, and stay updated:
+Q: What are the main differences between BERT and GPT?
+A: BERT (Bidirectional Encoder Representations from Transformers) is designed for understanding the context of words in both directions (left and right). GPT (Generative Pre-trained Transformer), on the other hand, is designed for generating text and understanding context in a left-to-right manner.
+Q: Can I fine-tune a model on my own data?
+A: Yes, the Transformers library provides tools for fine-tuning pre-trained models on your custom datasets. Check out the fine-tuning guide for more details.
+Happy Transforming! 🌟
+ + + + + + + + + + + + + +Word2Vec is a technique to learn word embeddings using neural networks. The primary goal is to represent words in a continuous vector space where semantically similar words are mapped to nearby points. Word2Vec can be implemented using two main architectures:
+In this example, we focus on the Skip-gram approach, which is more commonly used in practice. The Skip-gram model tries to maximize the probability of context words given a target word.
+Ensure you have Python installed. You can install the necessary dependencies using pip:
+ +Define the parameters for the Word2Vec model:
+window_size
: Defines the size of the context window around the target word.embedding_dim
: Dimension of the word vectors (embedding space).learning_rate
: Rate at which weights are updated.The tokenize
method creates a vocabulary from the documents and builds mappings between words and their indices.
The generate_training_data
method creates pairs of target words and context words based on the window size.
The train
method initializes the weight matrices and updates them using gradient descent.
For each word-context pair, it computes the hidden layer representation, predicts context probabilities, calculates the error, and updates the weights.
+The get_word_vector
method retrieves the embedding of a specific word.
window_size
: Size of the context window around the target word.embedding_dim
: Dimension of the word vectors (embedding space).learning_rate
: Rate at which weights are updated.tokenize
method creates a vocabulary from the documents.generate_training_data
method creates pairs of target words and context words based on the window size.train
method initializes the weight matrices.softmax
function converts the output layer scores into probabilities.get_word_vector
method retrieves the embedding of a specific word.import numpy as np
+
+class Word2Vec:
+ def __init__(self, window_size=2, embedding_dim=10, learning_rate=0.01):
+ # Initialize parameters
+ self.window_size = window_size
+ self.embedding_dim = embedding_dim
+ self.learning_rate = learning_rate
+ self.vocabulary = {}
+ self.word_index = {}
+ self.index_word = {}
+ self.W1 = None
+ self.W2 = None
+
+ def tokenize(self, documents):
+ # Tokenize documents and build vocabulary
+ vocabulary = set()
+ for doc in documents:
+ words = doc.split()
+ vocabulary.update(words)
+
+ self.vocabulary = list(vocabulary)
+ self.word_index = {word: idx for idx, word in enumerate(self.vocabulary)}
+ self.index_word = {idx: word for idx, word in enumerate(self.vocabulary)}
+
+ def generate_training_data(self, documents):
+ # Generate training data for the Skip-gram model
+ training_data = []
+ for doc in documents:
+ words = doc.split()
+ for idx, word in enumerate(words):
+ target_word = self.word_index[word]
+ context = [self.word_index[words[i]] for i in range(max(0, idx - self.window_size), min(len(words), idx + self.window_size + 1)) if i != idx]
+ for context_word in context:
+ training_data.append((target_word, context_word))
+ return training_data
+
+ def train(self, documents, epochs=1000):
+ # Tokenize the documents and generate training data
+ self.tokenize(documents)
+ training_data = self.generate_training_data(documents)
+
+ # Initialize weight matrices with random values
+ vocab_size = len(self.vocabulary)
+ self.W1 = np.random.uniform(-1, 1, (vocab_size, self.embedding_dim))
+ self.W2 = np.random.uniform(-1, 1, (self.embedding_dim, vocab_size))
+
+ for epoch in range(epochs):
+ loss = 0
+ for target_word, context_word in training_data:
+ # Forward pass
+ h = self.W1[target_word] # Hidden layer representation of the target word
+ u = np.dot(h, self.W2) # Output layer scores
+ y_pred = self.softmax(u) # Predicted probabilities
+
+ # Calculate error
+ e = np.zeros(vocab_size)
+ e[context_word] = 1
+ error = y_pred - e
+
+ # Backpropagation
+ self.W1[target_word] -= self.learning_rate * np.dot(self.W2, error)
+ self.W2 -= self.learning_rate * np.outer(h, error)
+
+ # Calculate loss (cross-entropy)
+ loss -= np.log(y_pred[context_word])
+
+ if (epoch + 1) % 100 == 0:
+ print(f'Epoch {epoch + 1}, Loss: {loss}')
+
+ def softmax(self, x):
+ # Softmax function to convert scores into probabilities
+ e_x = np.exp(x - np.max(x))
+ return e_x / e_x.sum(axis=0)
+
+ def get_word_vector(self, word):
+ # Retrieve the vector representation of a word
+ return self.W1[self.word_index[word]]
+
+ def get_vocabulary(self):
+ # Retrieve the vocabulary
+ return self.vocabulary
+# Example usage
+if __name__ == "__main__":
+ # Basic example usage
+ documents = [
+ "the cat sat on the mat",
+ "the dog ate my homework",
+ "the cat ate the dog food",
+ "I love programming in Python",
+ "Machine learning is fun",
+ "Python is a versatile language",
+ "Learning new skills is always beneficial"
+ ]
+
+ # Initialize and train the Word2Vec model
+ word2vec = Word2Vec()
+ word2vec.train(documents)
+
+ # Print the vocabulary
+ print("Vocabulary:", word2vec.get_vocabulary())
+
+ # Print the word vectors for each word in the vocabulary
+ print("Word Vectors:")
+ for word in word2vec.get_vocabulary():
+ vector = word2vec.get_word_vector(word)
+ print(f"Vector for '{word}':", vector)
+
+ # More example documents with mixed content
+ more_documents = [
+ "the quick brown fox jumps over the lazy dog",
+ "a journey of a thousand miles begins with a single step",
+ "to be or not to be that is the question",
+ "the rain in Spain stays mainly in the plain",
+ "all human beings are born free and equal in dignity and rights"
+ ]
+
+ # Initialize and train the Word2Vec model on new documents
+ word2vec_more = Word2Vec()
+ word2vec_more.train(more_documents)
+
+ # Print the word vectors for selected words
+ print("\nWord Vectors for new documents:")
+ for word in ['quick', 'journey', 'be', 'rain', 'human']:
+ vector = word2vec_more.get_word_vector(word)
+ print(f"Vector for '{word}':", vector)
+
Word embeddings are a type of word representation that allows words to be represented as vectors in a continuous vector space. These embeddings capture semantic meanings of words based on their context and usage in a given corpus. Word embeddings have become a fundamental concept in Natural Language Processing (NLP) and are widely used for various NLP tasks such as sentiment analysis, machine translation, and more.
+Traditional word representations, such as one-hot encoding, have limitations: +- High Dimensionality: One-hot encoding results in very high-dimensional vectors, which are sparse (mostly zeros). +- Lack of Semantics: One-hot vectors do not capture any semantic relationships between words.
+Word embeddings address these issues by: +- Dimensionality Reduction: Representing words in a lower-dimensional space. +- Capturing Semantics: Encoding words such that similar words are closer together in the vector space.
+Developed by Mikolov et al., Word2Vec generates word embeddings using neural networks. There are two main models:
+Developed by Pennington et al., GloVe generates embeddings by factorizing the word co-occurrence matrix. The key idea is to use the global statistical information of the corpus.
+Developed by Facebook's AI Research (FAIR) lab, FastText is an extension of Word2Vec that represents words as bags of character n-grams. This allows FastText to generate embeddings for out-of-vocabulary words.
+Developed by Peters et al., ELMo generates embeddings using deep contextualized word representations based on a bidirectional LSTM.
+Developed by Devlin et al., BERT uses transformers to generate embeddings. BERT's embeddings are contextual and capture bidirectional context.
+Here's an example of using Word2Vec with the gensim
library in Python:
from gensim.models import Word2Vec
+from nltk.tokenize import word_tokenize
+import nltk
+
+nltk.download('punkt')
+
+# Sample corpus
+corpus = [
+ "This is a sample sentence",
+ "Word embeddings are useful in NLP",
+ "Natural Language Processing with embeddings"
+]
+
+# Tokenize the corpus
+tokenized_corpus = [word_tokenize(sentence.lower()) for sentence in corpus]
+
+# Train Word2Vec model
+model = Word2Vec(sentences=tokenized_corpus, vector_size=50, window=3, min_count=1, sg=1)
+
+# Get the embedding for the word 'word'
+word_embedding = model.wv['word']
+print("Embedding for 'word':", word_embedding)
+
Word embeddings are a powerful technique in NLP that provide a way to represent words in a dense, continuous vector space. By capturing semantic relationships and reducing dimensionality, embeddings improve the performance of various NLP tasks and models.
++ There are no items available at this time. Check back again later. +
++ There are no items available at this time. Check back again later. +
+import numpy as np
+
+def mean_absolute_error(y_true, y_pred):
+ """
+ Calculate the mean absolute error between true and predicted values.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - Mean absolute error (float).
+ """
+ return (np.absolute(y_true - y_pred)).mean()
+
import numpy as np
+
+def mean_squared_error(y_true, y_pred):
+ """
+ Calculate the mean squared error between true and predicted values.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - Mean squared error (float).
+ """
+ return np.mean((y_true - y_pred) ** 2)
+
import numpy as np
+
+def r_squared(y_true, y_pred):
+ """
+ Calculate the R-squared value between true and predicted values.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - R-squared value (float).
+ """
+ total_variance = np.sum((y_true - np.mean(y_true)) ** 2)
+ explained_variance = np.sum((y_pred - np.mean(y_true)) ** 2)
+ r2 = 1 - (explained_variance / total_variance)
+ return r2
+
import numpy as np
+import math as mt
+
+def root_mean_squared_error(y_true,y_pred):
+ """
+ Calculate the root mean squared error between true and predicted values.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - Root Mean squared error (float).
+ """
+ return mt.sqrt(np.mean((y_true - y_pred) ** 2))
+
import numpy as np
+
+def binary_cross_entropy_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list) -> float:
+ """
+ Calculate the binary cross entropy loss between true and predicted values.
+ It measures the difference between the predicted probability distribution and the actual binary label distribution.
+ The formula for binary cross-entropy loss is as follows:
+
+ L(y, ŷ) = -[y * log(ŷ) + (1 — y) * log(1 — ŷ)]
+
+ where y is the true binary label (0 or 1), ŷ is the predicted probability (ranging from 0 to 1), and log is the natural logarithm.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - Binary cross entropy loss (float).
+ """
+ if (y_true is not None) and (y_pred is not None):
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_true.shape == y_pred.shape, f"Shape of y_true ({y_true.shape}) does not match y_pred ({y_pred.shape})"
+ # calculate the binary cross-entropy loss
+ loss = -(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)).mean()
+ return loss
+ else:
+ return None
+
+def weighted_binary_cross_entropy_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list, w_pos: float, w_neg: float) -> float:
+ """
+ Calculates the weighted binary cross entropy loss between true and predicted values.
+ Weighted Binary Cross-Entropy loss is a variation of the binary cross-entropy loss that allows for assigning different weights to positive and negative examples. This can be useful when dealing with imbalanced datasets, where one class is significantly underrepresented compared to the other.
+ The formula for weighted binary cross-entropy loss is as follows:
+
+ L(y, ŷ) = -[w_pos * y * log(ŷ) + w_neg * (1 — y) * log(1 — ŷ)]
+
+ where y is the true binary label (0 or 1), ŷ is the predicted probability (ranging from 0 to 1), log is the natural logarithm, and w_pos and w_neg are the positive and negative weights, respectively.
+
+ Parameters:
+ - y_true: True target values (numpy array).
+ - y_pred: Predicted values (numpy array).
+
+ Returns:
+ - Weighted binary cross entropy loss (float).
+ """
+ if (y_true is not None) and (y_pred is not None):
+ assert w_pos != 0.0, f"Weight w_pos = {w_pos}"
+ assert w_neg != 0.0, f"Weight w_neg = {w_neg}"
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_true.shape == y_pred.shape, f"Shape of y_true ({y_true.shape}) does not match y_pred ({y_pred.shape})"
+ # calculate the binary cross-entropy loss
+ loss = -(w_pos * y_true * np.log(y_pred) + w_neg * (1 - y_true) * np.log(1 - y_pred)).mean()
+ return loss
+ else:
+ return None
+
+
+def categorical_cross_entropy_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list) -> float:
+ """
+ Calculate the categorical cross entropy loss between true and predicted values.
+ It measures the difference between the predicted probability distribution and the actual one-hot encoded label distribution.
+ The formula for categorical cross-entropy loss is as follows:
+
+ L(y, ŷ) = -1/N * Σ[Σ{y * log(ŷ)}]
+
+ where y is the true one-hot encoded label vector, ŷ is the predicted probability distribution, and log is the natural logarithm.
+
+ Parameters:
+ - y_true: True target values (numpy array) (one-hot encoded).
+ - y_pred: Predicted values (numpy array) (probabilities).
+
+ Returns:
+ - Categorical cross entropy loss (float).
+ """
+ if (y_true is not None) and (y_pred is not None):
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_pred.ndim == 2, f"Shape of y_pred should be (N, C), got {y_pred.shape}"
+ assert y_true.shape == y_pred.shape, f"Shape of y_true ({y_true.shape}) does not match y_pred ({y_pred.shape})"
+
+ # Ensure numerical stability
+ y_pred = np.clip(y_pred, 1e-15, 1 - 1e-15)
+
+ # calculate the categorical cross-entropy loss
+ loss = -1/len(y_true) * np.sum(np.sum(y_true * np.log(y_pred)))
+ return loss.mean()
+ else:
+ return None
+
+def sparse_categorical_cross_entropy_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list) -> float:
+ """
+ Calculate the sparse categorical cross entropy loss between true and predicted values.
+ It measures the difference between the predicted probability distribution and the actual class indices.
+ The formula for sparse categorical cross-entropy loss is as follows:
+
+ L(y, ŷ) = -Σ[log(ŷ[range(N), y])]
+
+ where y is the true class indices, ŷ is the predicted probability distribution, and log is the natural logarithm.
+
+ Parameters:
+ - y_true: True target values (numpy array) (class indices).
+ - y_pred: Predicted values (numpy array) (probabilities).
+
+ Returns:
+ - Sparse categorical cross entropy loss (float).
+ """
+ if (y_true is not None) and (y_pred is not None):
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_true.shape[0] == y_pred.shape[0], f"Batch size of y_true ({y_true.shape[0]}) does not match y_pred ({y_pred.shape[0]})"
+
+ # convert true labels to one-hot encoding
+ y_true_onehot = np.zeros_like(y_pred)
+ y_true_onehot[np.arange(len(y_true)), y_true] = 1
+
+ # Ensure numerical stability
+ y_pred = np.clip(y_pred, 1e-15, 1 - 1e-15)
+
+ # calculate loss
+ loss = -np.mean(np.sum(y_true_onehot * np.log(y_pred), axis=-1))
+ return loss
+ else:
+ return None
+
+
+if __name__ == "__main__":
+ # define true labels and predicted probabilities
+ y_true = np.array([0, 1, 1, 0])
+ y_pred = np.array([0.1, 0.9, 0.8, 0.3])
+
+ print("\nTesting Binary Cross Entropy Loss")
+ print("Y_True: ", y_true)
+ print("Y_Pred:", y_pred)
+ print("Binary Cross Entropy Loss: ", binary_cross_entropy_loss(y_true, y_pred))
+
+ positive_weight = 0.7
+ negative_weight = 0.3
+
+ print("\nTesting Weighted Binary Cross Entropy Loss")
+ print("Y_True: ", y_true)
+ print("Y_Pred:", y_pred)
+ print("Weighted Binary Cross Entropy Loss: ", weighted_binary_cross_entropy_loss(y_true, y_pred, positive_weight, negative_weight))
+
+ y_true = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]])
+ y_pred = np.array([[0.8, 0.1, 0.1], [0.2, 0.3, 0.5], [0.1, 0.6, 0.3]])
+ print("\nTesting Categorical Cross Entropy Loss")
+ print("Y_True: ", y_true)
+ print("Y_Pred:", y_pred)
+ print("Categorical Cross Entropy Loss: ", categorical_cross_entropy_loss(y_true, y_pred))
+
+ y_true = np.array([1, 2, 0])
+ y_pred = np.array([[0.1, 0.8, 0.1], [0.3, 0.2, 0.5], [0.4, 0.3, 0.3]])
+ print("\nTesting Sparse Categorical Cross Entropy Loss")
+ print("Y_True: ", y_true)
+ print("Y_Pred:", y_pred)
+ print("Sparse Categorical Cross Entropy Loss: ", sparse_categorical_cross_entropy_loss(y_true, y_pred))
+
import numpy as np
+
+def hinge_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list)-> float:
+ """
+ Calculates the hinge loss between true and predicted values.
+
+ The formula for hinge loss is as follows:
+
+ L(y, ŷ) = max(0, 1 - y * ŷ)
+
+ """
+ if (y_true is not None) and (y_pred is not None):
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_true.shape[0] == y_pred.shape[0], f"Batch size of y_true ({y_true.shape[0]}) does not match y_pred ({y_pred.shape[0]})"
+
+ # replacing 0 values to -1
+ y_pred = np.where(y_pred == 0, -1, 1)
+ y_true = np.where(y_true == 0, -1, 1)
+
+ # Calculate loss
+ loss = np.maximum(0, 1 - y_true * y_pred).mean()
+ return loss
+
+if __name__ == "__main__":
+ # define true labels and predicted probabilities
+ actual = np.array([1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1])
+ predicted = np.array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1])
+
+ print("\nTesting Hinge Loss")
+ print("Y_True: ", actual)
+ print("Y_Pred:", predicted)
+ print("Hinge Loss: ", hinge_loss(actual, predicted))
+
Kullback Leibler Divergence Loss
+
import numpy as np
+
+def kl_divergence_loss(y_true: np.ndarray | list, y_pred: np.ndarray | list) -> float:
+ """
+ Calculate the Kullback-Leibler (KL) divergence between two probability distributions.
+ KL divergence measures how one probability distribution diverges from another reference probability distribution.
+
+ The formula for KL divergence is:
+ D_KL(P || Q) = Σ P(x) * log(P(x) / Q(x))
+
+ where P is the true probability distribution and Q is the predicted probability distribution.
+
+ Parameters:
+ - y_true: True probability distribution (numpy array or list).
+ - y_pred: Predicted probability distribution (numpy array or list).
+
+ Returns:
+ - KL divergence loss (float).
+ """
+ if (y_true is not None) and (y_pred is not None):
+ if type(y_true) == list:
+ y_true = np.asarray(y_true)
+ if type(y_pred) == list:
+ y_pred = np.asarray(y_pred)
+ assert y_true.shape == y_pred.shape, f"Shape of p_true ({y_true.shape}) does not match q_pred ({y_pred.shape})"
+
+ # Ensure numerical stability by clipping the probabilities
+ y_true = np.clip(y_true, 1e-15, 1)
+ y_pred = np.clip(y_pred, 1e-15, 1)
+
+ # Normalize the distributions
+ y_true /= y_true.sum(axis=-1, keepdims=True)
+ y_pred /= y_pred.sum(axis=-1, keepdims=True)
+
+ # Calculate KL divergence
+ kl_div = np.sum(y_true * np.log(y_true / y_pred), axis=-1)
+ return kl_div.mean()
+ else:
+ return None
+
+if __name__ == "__main__":
+ y_true = np.array([[0.2, 0.5, 0.3], [0.1, 0.7, 0.2]]) # True probability distributions
+ y_pred = np.array([[0.1, 0.6, 0.3], [0.2, 0.5, 0.3]]) # Predicted probability distributions
+
+ print("\nTesting Kullback Leibler Divergence Loss")
+ print("Y_True: ", y_true)
+ print("Y_Pred:", y_pred)
+ print("Kullback Leibler Divergence Loss: ", kl_divergence_loss(y_true, y_pred))
+
import tensorflow as tf
+from typing import Tuple
+
+def pairwise_ranking_loss(y_true: tf.Tensor, y_pred: tf.Tensor, margin: float = 1.0) -> tf.Tensor:
+ """
+ Computes the pairwise ranking loss for a batch of pairs.
+
+ Args:
+ y_true: Tensor of true labels (0 for negative pairs, 1 for positive pairs).
+ y_pred: Tensor of predicted similarities/distances, expected to be a tensor of shape (batch_size, 2, embedding_dim) where
+ y_pred[:, 0] is the anchor and y_pred[:, 1] is the positive/negative.
+ margin: Margin parameter for the pairwise ranking loss.
+
+ Returns:
+ loss: Computed pairwise ranking loss as a scalar tensor.
+ """
+ anchor, positive_or_negative = y_pred[:, 0], y_pred[:, 1]
+
+ distances = tf.reduce_sum(tf.square(anchor - positive_or_negative), axis=-1)
+ positive_loss = y_true * distances
+ negative_loss = (1 - y_true) * tf.maximum(margin - distances, 0.0)
+
+ loss = positive_loss + negative_loss
+ return tf.reduce_mean(loss)
+
+# Example usage:
+# model.compile(optimizer='adam', loss=pairwise_ranking_loss)
+
import tensorflow as tf
+from typing import Tuple
+
+def triplet_loss_func(y_true: tf.Tensor, y_pred: tf.Tensor, alpha: float = 0.3) -> tf.Tensor:
+ """
+ Computes the triplet loss for a batch of triplets.
+
+ Args:
+ y_true: True values of classification (unused in this implementation, typically required for compatibility with Keras).
+ y_pred: Predicted values, expected to be a tensor of shape (batch_size, 3, embedding_dim) where
+ y_pred[:, 0] is the anchor, y_pred[:, 1] is the positive, and y_pred[:, 2] is the negative.
+ alpha: Margin parameter for the triplet loss.
+
+ Returns:
+ loss: Computed triplet loss as a scalar tensor.
+ """
+ anchor, positive, negative = y_pred[:, 0], y_pred[:, 1], y_pred[:, 2]
+
+ positive_dist = tf.reduce_sum(tf.square(anchor - positive), axis=-1)
+ negative_dist = tf.reduce_sum(tf.square(anchor - negative), axis=-1)
+
+ loss = tf.maximum(positive_dist - negative_dist + alpha, 0.0)
+ return tf.reduce_mean(loss)
+
+# Example usage:
+# model.compile(optimizer='adam', loss=triplet_loss_func)
+
+ There are no items available at this time. Check back again later. +
+