When an outcome has ordered categories, such as a customer review score from 1 to 5, ordinal logistic regression can relate that outcome to explanatory variables. For reviews, those variables might include delivery time, price, product attributes, and payment details. section 3.4.3
Another ordered outcome
Medication adherence might range from “never adheres” through “always adheres.” Ordinal logistic regression could examine whether adherence levels differ with patient education, reported side effects, or follow-up consultations. Such findings would help identify questions worth investigating, not automatically prove what caused a change. section 4.7
A practical review-score workflow is:
- Merge the relevant order, review, product, customer, and other records; check for missing values and convert categorical predictors to numerical form. section 3.4.3
- Split predictors and review scores into training and test sets, then fit `mord.LogisticAT` on the training data. section 3.4.3
- Predict test-set scores; inspect accuracy and a confusion matrix, then connect coefficients to their predictor names. section 3.4.3
Listing 3.6 Preparation of the analysis_df DataFrame
# Merge df_products with df_product_category_translation products_merged = pd.merge( df_products, df_product_category_translation, on='product_category_name') # Merge df_orders with df_order_items order_items_merged = pd.merge(df_orders, df_order_items, on='order_id') # Merge the resulting DataFrame with df_customers order_customer_merged = pd.merge( order_items_merged, df_customers, on='customer_id') # Merge the resulting DataFrame with products_merged order_product_merged = pd.merge( order_customer_merged, products_merged, on='product_id') # Merge the resulting DataFrame with df_sellers order_seller_merged = pd.merge( order_product_merged, df_sellers, on='seller_id') # Merge the resulting DataFrame with df_order_reviews order_review_merged = pd.merge( order_seller_merged, df_order_reviews, on='order_id') # Merge the resulting DataFrame with df_order_payments analysis_df = pd.merge( order_review_merged, df_order_payments, on='order_id') # Calculate delivery time in days analysis_df['delivery_time'] = (analysis_df['order_delivered_customer_date'] – analysis_df['order_purchase_timestamp']).dt.days # Calculate the difference between actual vs. estimated delivery time analysis_df['delivery_time_misestimation'] = (pd.to_datetime(analysis_df['order_estimated_delivery_date']) – pd.to_datetime(analysis_df['order_delivered_customer_date'])).dt.days # Calculate product volume analysis_df['product_volume'] = analysis_df['product_length_cm'] * analysis_df['product_height_cm'] * analysis_df['product_width_cm'] # Apply one-hot encoding to the payment_type column payment_type_dummies = pd.get_dummies( analysis_df['payment_type'], prefix='payment_type') # Concatenate the one-hot encoded columns with analysis_df analysis_df = pd.concat([analysis_df, payment_type_dummies], axis=1) # Drop unnecessary columns analysis_df.drop(columns=['product_category_name', 'order_approved_at', 'order_delivered_carrier_date', 'order_estimated_delivery_date', 'shipping_limit_date', 'review_creation_date', 'review_answer_timestamp', 'order_id', 'customer_id', 'order_status', 'order_purchase_timestamp', 'order_delivered_customer_date', 'order_item_id','product_id', 'seller_id', 'product_category_name_english', 'seller_zip_code_prefix', 'seller_city', 'seller_state', 'review_comment_message', 'review_comment_title', 'review_id', 'product_length_cm', 'product_height_cm', 'product_width_cm', 'customer_unique_id', 'customer_zip_code_prefix', 'customer_city', 'customer_state', 'payment_type'], inplace=True) analysis_df = analysis_df.dropna()
The DataFrame must be assembled before fitting the model. Inspect the joins rather than accepting generated code that merely assumes `analysis_df` already exists. section 3.4.3
Listing 3.7 Connecting prediction results with variable names
# Assuming you have already fitted the model and have the `model` variable
as the instance of the fitted model, e.g.,
model = mord.LogisticAT().fit(X_train, y_train)
# Get the feature names from the analysis_df DataFrame
# Replace 'X' with the actual variable name containing your
independent variables
feature_names = X.columns
# Get the coefficients from the model
coefficients = model.coef_
# Create a dictionary to link the coefficients to the column names
coefficient_dict = dict(zip(feature_names, coefficients))
# Print the coefficients along with the corresponding column names
for feature, coef in coefficient_dict.items():
print(f"{feature}: {coef}")
Pairing each coefficient with its feature name makes the model output inspectable; an unlabeled array is easy to misread. section 3.4.3
One review-score run achieved about 43% accuracy, and its confusion matrix shows many predictions concentrated in higher score categories. Treat coefficients cautiously when model-fit statistics suggest the predictors do not adequately capture the outcome. Check the prepared records, prediction errors, and fit before using apparent relationships to guide decisions. section 3.4.3 section 4.7
