DEV Community

Talex Maxim
Talex Maxim

Posted on

Thinking Outside the Box: A Conceptual Framework for Machine Learning and Data Analysis

In the rapidly evolving field of machine learning and data analysis, the tools we create often begin with a specific purpose in mind. But as we push the boundaries of what’s possible, these tools can transcend their original scope, becoming more versatile, more powerful, and ultimately more impactful. Today, I want to introduce a conceptual framework that embodies this philosophy — an adaptable, reusable tool that started as a simple price predictor but has evolved into something much more.

The Genesis of the Framework

When I first developed the Price Predictor, the goal was straightforward: to predict prices based on historical data using machine learning algorithms. However, as I delved deeper into the intricacies of data preprocessing, feature engineering, and model evaluation, it became clear that this tool could serve a broader purpose.

The framework I built for the Price Predictor is not just about predicting prices; it’s a modular, flexible system designed to handle a wide range of data analysis tasks. From data cleaning to model training and evaluation, the components of this framework can be reused, adapted, and expanded to tackle various challenges in machine learning.

A Reusable Framework for Data Analysis

The beauty of this framework lies in its reusability. Whether you’re working on a classification problem, a regression task, or even exploring unsupervised learning techniques, the core structure remains the same. The framework is built around several key modules:

Data Processing: The DataProcessor Class

The DataProcessor class is a crucial component of the framework, handling the loading, cleaning, and preparation of data. Below is an example of how the DataProcessor class is structured:

import pandas as pd
from sklearn.model_selection import train_test_split
class DataProcessor:
    def __init__ (self, file_path):
        self.file_path = file_path
        self.dataset = None
    def load_data(self):
        # Load data from CSV file
        self.dataset = pd.read_csv(self.file_path)
        return self.dataset
    def clean_data(self):
        # Example cleaning step: removing null values
        self.dataset.dropna(inplace=True)
        return self.dataset
    def split_data(self, target_column, test_size=0.2, random_state=42):
        # Splitting the data into training and validation sets
        X = self.dataset.drop(columns=[target_column])
        Y = self.dataset[target_column]
        X_train, X_valid, Y_train, Y_valid = train_test_split(X, Y, test_size=test_size, random_state=random_state)
        return X_train, X_valid, Y_train, Y_valid
Enter fullscreen mode Exit fullscreen mode

Here’s how you can use the DataProcessor class in a project:

from dataProcessor import DataProcessor
# Initialize the DataProcessor with the path to your dataset
processor = DataProcessor('./data-sets/amazon_reviews.csv')
# Load and clean the data
data = processor.load_data()
cleaned_data = processor.clean_data()
# Split the data into training and validation sets
X_train, X_valid, Y_train, Y_valid = processor.split_data(target_column='price')
Enter fullscreen mode Exit fullscreen mode

Model Training and Evaluation: The ModelTrainer Class

In the Price Predictor framework, training machine learning models and evaluating them is straightforward. And the idea here is to be able to accept as much data-processing classes as needed with the same extended methods. Here’s how you can do it using the ModelTrainer class:

import joblib
import pandas as pd
from sklearn import svm
from sklearn.ensemble import RandomForestRegressor, HistGradientBoostingClassifier
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn import metrics
import numpy as np
from dataProcessor import DataProcessor
from dataProcessorGeneric import DataProcessorGeneric

DEFAULT_MODELS={
            'SVR': svm.SVR(),
            'RandomForest': RandomForestRegressor(random_state=42, n_estimators=10),
            'LinearRegression': LinearRegression()
        }

class ModelTrainer:
    def __init__ (self, models = DEFAULT_MODELS, file_path=None, url = None):
        if url is not None:
            self.data_processor = DataProcessor(url)
        else:
            self.data_processor = DataProcessorGeneric(file_path)
        self.dataset = None
        self.df_final = None
        self.X_train = None
        self.X_valid = None
        self.Y_train = None
        self.Y_valid = None
        self.models = models

    def load_and_preprocess_data(self):
        self.dataset = self.data_processor.load_data()
        self.df_final = self.data_processor.clean_data()
        self.X_train, self.X_valid, self.Y_train, self.Y_valid = self.data_processor.split_data()

    def train_models(self):
        for name, model in self.models.items():
            print(f"Training {name}...")
            if name == "LogisticsRegression":
                self.Y_train = self.Y_train.values.ravel()
            model.fit(self.X_train, self.Y_train)

    def evaluate_models(self):
        scores = {}
        for name, model in self.models.items():
            Y_pred = model.predict(self.X_valid)
            rmse = np.sqrt(metrics.mean_squared_error(self.Y_valid, Y_pred))
            scores[name] = rmse
        print(scores)
        return scores

    def best_performer(self):
        res = {}
        scores = self.evaluate_models()
        best_model_name = min(scores, key=scores.get)
        res[best_model_name] = scores[best_model_name]
        return res
    ###method will predict possible popularity of a product , based on influencer feedback
    def recommend_top_5_products(self):
        # Step 1: Identify the best-performing model
        best_model_info = self.best_performer()
        best_model_name = next(iter(best_model_info)) # Get the name of the best model
        best_model = self.models.get(best_model_name) # Retrieve the best model object

        # Step 2: Predict ratings using the best model
        predicted_ratings = best_model.predict(self.X_valid)

        # Step 3: Ensure X_valid is a DataFrame and has the correct index
        if not isinstance(self.X_valid, pd.DataFrame):
            recommendations = pd.DataFrame(self.X_valid)
        else:
            recommendations = self.X_valid.copy()

        # Step 4: Add predicted ratings to the recommendations DataFrame
        recommendations['predicted_rating'] = predicted_ratings

        # Step 5: Merge the original data with the recommendations to retain all columns
        # Reset indices to align them for merging
        recommendations.reset_index(drop=True, inplace=True)
        self.df_final.reset_index(drop=True, inplace=True)

        # `self.df_final` contains the original product information
        #merged_recommendations = pd.concat([self.df_final, recommendations['predicted_rating']], axis=1)
        merged_recommendations = pd.DataFrame({'itemName': self.df_final['itemName'],'vote':self.df_final['vote'],'predicted_rating': recommendations['predicted_rating']})

        # Save the result to a CSV file -my debug
        #merged_recommendations.to_csv('predicted_candidate_decisions.csv', index=False)

        # Step 6: Group by `itemName` to aggregate predicted ratings by product
        grouped_recommendations = merged_recommendations.groupby('itemName').agg({
            'predicted_rating': 'mean', # Aggregate predicted ratings
            #'userName': 'count', # Optionally, count the number of ratings
            #'verified': 'first', # Keep other columns as they are (you can choose how to aggregate)
            #'reviewText': 'first',
            'vote': 'sum' # Sum the number of votes
        }).reset_index()

        # Step 7: Sort by predicted rating and number of votes
        sorted_recommendations = grouped_recommendations.sort_values(
            by=['predicted_rating', 'vote'],
            ascending=[False, False]
        )

        # Step 8: Return the top 5 products based on sorted DataFrame
        top_5_products = sorted_recommendations.head(5)

        return top_5_products

Enter fullscreen mode Exit fullscreen mode

Thinking Beyond Price Prediction

As I continued to refine this tool, I realized that the name “Price Predictor” no longer captured the essence of what this framework represents. What started as a tool for predicting prices has grown into a comprehensive solution for machine learning and data analysis — an adaptable framework that can be molded to fit a variety of use cases.

This realization has led me to rethink the branding and scope of the project. While “Price Predictor” was an apt name for its initial purpose, it now feels outdated, a relic of the framework’s origins. As we move forward, I invite the community to join me in reimagining this tool, not just as a predictor but as a new wave of framework solutions for machine learning.

An Invitation to Collaborate

The current state of this framework is just the beginning. There is immense potential for it to evolve into something far greater with the input and creativity of the community. I invite developers, data scientists, and machine learning enthusiasts to explore the repository, borrow ideas, adjust components, and contribute to its growth.

Let’s work together to push the boundaries of what’s possible in machine learning and data analysis. Whether you’re interested in enhancing the existing modules, integrating new machine-learning techniques, or simply using the framework for your projects, your contributions are welcome.

The Future of This Framework

As we continue to develop and refine this tool, I believe it will become a cornerstone in the machine learning community — a versatile, powerful framework that adapts to the ever-changing landscape of data science.

The journey from a simple price predictor to a comprehensive machine-learning framework is a testament to the power of thinking outside the box. With your collaboration, I am confident that this framework will continue to evolve, setting the stage for the next generation of data analysis tools.

Join me on this journey and let’s create something extraordinary together. Explore the repository , and let’s make machine learning accessible, adaptable, and powerful for everyone.

Top comments (0)