Monday, May 27, 2024

Trend Analysis using linear and non-linear Regression

 If you want to show regression effect of two numerical variable with two different categorical or binary variable then you can use this style




import seaborn as sns

import matplotlib.pyplot as plt

import numpy as np

from sklearn.linear_model import LinearRegression

from sklearn.metrics import r2_score


sns.set_theme(style="ticks")


# Assuming df is your DataFrame

# Define the palette for the hue

hue_palette = sns.color_palette("husl", n_colors=df['g_type'].nunique())


# Initialize the relplot

plot = sns.relplot(

    data=df,

    x="n_veh", y="tit",

    hue="g_type", col="n_lane", 

    kind="line", palette=hue_palette,

    height=5, aspect=.75, facet_kws=dict(sharex=False),

)


# Set x-axis limit to ensure the time range is displayed correctly

plot.set(xlim=(2, 13))


# Calculate R^2 values and add annotations

for ax in plot.axes.flat:

    n_lane = ax.get_title().split('=')[-1].strip()

    subset = df[df['n_lane'] == int(n_lane)]

    for g_type in subset['g_type'].unique():

        sub_subset = subset[subset['g_type'] == g_type]

        X = sub_subset['n_veh'].values.reshape(-1, 1)

        y = sub_subset['tit'].values

        

        if len(X) > 1:  # LinearRegression requires at least two points

            model = LinearRegression().fit(X, y)

            y_pred = model.predict(X)

            r2 = r2_score(y, y_pred)

            

            ax.text(

                0.1, 0.9 - 0.1 * list(subset['g_type'].unique()).index(g_type), 

                f'{g_type} $R^2$ = {r2:.2f}', 

                transform=ax.transAxes, 

                fontsize=9

            )


# Set the title for each facet

plt.subplots_adjust(top=0.9)

plt.suptitle("TIT vs Number of Vehicles by Lane", fontsize=16)


plt.show()


 

import seaborn as sns

import matplotlib.pyplot as plt

import numpy as np

from sklearn.preprocessing import PolynomialFeatures

from sklearn.linear_model import LinearRegression

from sklearn.metrics import r2_score


# Assuming df is your DataFrame

# Calculate average TIT and standard deviation for each n_veh value

average_df = df.groupby(['g_type', 'n_lane', 'n_veh'])['tit'].agg(['mean', 'std']).reset_index()


# Rename the columns

average_df = average_df.rename(columns={'n_lane': 'Lane Number', 'g_type': 'Group Type'})


# Define the palette for the hue

hue_palette = sns.color_palette("husl", n_colors=average_df['Group Type'].nunique())


# Initialize the relplot

plot = sns.relplot(

    data=average_df,

    x="n_veh", y="mean",

    hue="Group Type", col="Lane Number", 

    kind="line", palette=hue_palette,

    height=5, aspect=.75, facet_kws=dict(sharex=False),

)


# Set x-axis and y-axis labels

plot.set_axis_labels("Vehicle Number", "Average TIT")


# Add upper and lower bounds

for ax in plot.axes.flat:

    n_lane = ax.get_title().split('=')[-1].strip()

    subset = average_df[average_df['Lane Number'] == int(n_lane)]

    for g_type in subset['Group Type'].unique():

        sub_subset = subset[subset['Group Type'] == g_type]

        x = sub_subset['n_veh']

        upper_bound = sub_subset['mean'] + sub_subset['std']

        lower_bound = sub_subset['mean'] - sub_subset['std']

        ax.fill_between(x, lower_bound, upper_bound, alpha=0.1)


# Calculate R^2 values and add annotations

for ax in plot.axes.flat:

    n_lane = ax.get_title().split('=')[-1].strip()

    subset = average_df[average_df['Lane Number'] == int(n_lane)]

    for g_type in subset['Group Type'].unique():

        sub_subset = subset[subset['Group Type'] == g_type]

        X = sub_subset['n_veh'].values.reshape(-1, 1)

        y = sub_subset['mean'].values

        

        if len(X) > 1:  # Polynomial regression requires at least two points

            poly = PolynomialFeatures(degree=2)  # You can adjust the degree as needed

            X_poly = poly.fit_transform(X)

            model = LinearRegression().fit(X_poly, y)

            y_pred = model.predict(X_poly)

            r2 = r2_score(y, y_pred)

            

            ax.text(

                0.1, 0.9 - 0.1 * list(subset['Group Type'].unique()).index(g_type), 

                f'{g_type} $R^2$ = {r2:.2f}', 

                transform=ax.transAxes, 

                fontsize=9

            )


# Set the title for each facet

plt.subplots_adjust(top=0.9)

plt.suptitle("", fontsize=16)


plt.show()


0 comments:

Post a Comment