如何用Logistic Regression结合因子变量预测事件发生概率
结合多维度概率预测事件发生概率的实现方案
核心思路
你已经拥有4个可直接使用的概率特征:仅基于年龄的概率、年龄+季节的概率、年龄+地点的概率、年龄+星期的概率。我们可以把这些概率作为输入特征,通过模型学习每个特征的权重,融合所有维度的信息。同时针对周一样本严重不平衡的问题,通过类别权重调整或过采样方法优化模型效果。
具体实现方案
1. 数据预处理:合并数据集
首先将你提供的三个数据集合并为一个完整的训练集,方便后续建模。
2. 方法一:带类别权重的逻辑回归
逻辑回归是适合这类线性融合场景的模型之一,能自动学习各概率特征的权重,且输出天然是0-1之间的概率值。针对样本不平衡,使用class_weight='balanced'参数可自动为少数类(周一样本)赋予更高的训练权重。
3. 方法二:线性加权融合
如果你想要更直观的线性组合形式(类似你举例的公式),可以用线性回归模型学习权重,再将输出截断到0-1区间,确保结果符合概率定义。
4. 方法三:过采样处理不平衡样本
对于周一样本极少的情况,使用SMOTE过采样生成少数类的合成样本,平衡数据集后再训练模型,避免模型偏向多数类。
Python代码实现
第一步:生成并合并数据集
import pandas as pd import numpy as np from sklearn.linear_model import LogisticRegression, LinearRegression from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score from imblearn.over_sampling import SMOTE # 生成示例数据(与你提供的代码一致) num_rows = 100 seasons = np.random.randint(1, 5, num_rows) days_of_week = np.random.randint(1, 8, num_rows) locations = np.random.randint(1, 6, num_rows) df1 = pd.DataFrame({ 'Season': seasons, 'DayOfWeek': days_of_week, 'Location': locations }) probabilities = np.random.rand(num_rows, 3) df2 = pd.DataFrame(probabilities, columns=['SeasonProb', 'DayOfWeekProb', 'LocationProb']) p_alter = np.random.rand(num_rows) events = np.random.randint(0, 2, num_rows) df3 = pd.DataFrame({ 'P(Age)': p_alter, 'Event': events }) # 合并所有数据集 df = pd.concat([df1, df2, df3], axis=1) # 标记周一样本(假设DayOfWeek=1代表周一) df['is_monday'] = (df['DayOfWeek'] == 1).astype(int) print("周一样本数量:", df[df['is_monday'] == 1].shape[0]) print("非周一样本数量:", df[df['is_monday'] == 0].shape[0])
第二步:带类别权重的逻辑回归
# 定义特征与目标变量 X = df[['P(Age)', 'SeasonProb', 'DayOfWeekProb', 'LocationProb']] y = df['Event'] # 划分训练集与测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 训练带类别权重的逻辑回归 lr = LogisticRegression(class_weight='balanced', random_state=42) lr.fit(X_train, y_train) # 预测事件发生概率 y_pred_prob = lr.predict_proba(X_test)[:, 1] # 模型评估与权重输出 print(f"\n逻辑回归ROC-AUC分数:{roc_auc_score(y_test, y_pred_prob):.4f}") print("各特征权重:") for col, coef in zip(X.columns, lr.coef_[0]): print(f" {col}: {coef:.4f}") # 输出融合概率公式(逻辑回归使用sigmoid激活) print("\n融合概率公式:") formula = f"P(Event=1) = sigmoid({lr.intercept_[0]:.4f} " formula += " + ".join([f"+ {coef:.4f}*{col}" for col, coef in zip(X.columns, lr.coef_[0])]) print(formula + ")")
第三步:线性加权融合
# 训练线性回归模型 linear_reg = LinearRegression() linear_reg.fit(X_train, y_train) # 预测并截断结果到0-1区间 y_pred_linear = linear_reg.predict(X_test) y_pred_linear_clipped = np.clip(y_pred_linear, 0, 1) # 模型评估与权重输出 print(f"\n线性加权融合ROC-AUC分数:{roc_auc_score(y_test, y_pred_linear_clipped):.4f}") print("各特征权重:") for col, coef in zip(X.columns, linear_reg.coef_): print(f" {col}: {coef:.4f}") # 输出加权公式 print("\n加权融合公式:") formula = f"P(Event=1) = {linear_reg.intercept_:.4f} " formula += " + ".join([f"+ {coef:.4f}*{col}" for col, coef in zip(X.columns, linear_reg.coef_)]) print(formula + " (结果截断在0-1之间)")
第四步:SMOTE过采样优化不平衡问题
# 使用SMOTE生成少数类合成样本 smote = SMOTE(random_state=42) X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train) # 训练逻辑回归模型 lr_smote = LogisticRegression(random_state=42) lr_smote.fit(X_train_smote, y_train_smote) # 预测与评估 y_pred_prob_smote = lr_smote.predict_proba(X_test)[:, 1] print(f"\nSMOTE过采样后ROC-AUC分数:{roc_auc_score(y_test, y_pred_prob_smote):.4f}")
内容的提问来源于stack exchange,提问作者paule
相关产品推荐
相关产品推荐

