基于营收与客户数的分支分类预测异常问题求助
看起来你是想构建模型判断同一城市中哪个分支(依据营收/客户数量)是默认分支,但代码里有几个关键问题导致预测失效,我帮你逐一拆解:
LabelEncoder的错误复用与预测编码不一致
你在训练时用同一个LabelEncoder处理所有object类型列,这本身就有问题——每个分类特征(比如City、State、Branch Code)的类别集合是不同的,共用一个编码器会导致编码混乱。更严重的是,预测时你又对输入重新执行le.fit_transform(),这会生成和训练时完全不同的编码映射!比如训练时Chennai可能被编码为2,但预测时因为输入只有这一个城市,会被编码为0,模型自然无法正确识别。正确的做法是为每个分类特征单独创建LabelEncoder,或者更推荐用
ColumnTransformer结合OneHotEncoder来处理分类特征(避免顺序编码带来的误导)。特征包含了“答案信息”,违背任务逻辑
你的特征列里包含了Branch Code,而目标y是默认分支(本质上就是某个Branch Code)。这相当于把要预测的答案直接放进了特征里,模型根本不会去学习“同一城市里营收/客户多的分支是默认”这个规则,只会机械记住Branch Code和y的映射,完全偏离了你的任务目标。你应该把
Branch Code从特征中移除,特征只保留City、State、Revenue、Customers,而目标y应该是该分支是否为默认分支(比如用0/1标记)——这样模型才会学习到“同一城市中,营收或客户数量更高的分支更可能是默认分支”的模式。分类特征的编码方式不合理
LabelEncoder生成的是顺序编码(比如City的不同值被编码为0、1、2...),但城市之间并没有数值大小关系,这种编码会让模型错误地认为类别之间有顺序,影响模型学习。对于这类无序分类特征,应该使用独热编码(OneHotEncoder),这样每个类别都是独立的特征,不会引入虚假的顺序关系。
修正后的示例代码
import pandas as pd from sklearn.preprocessing import OneHotEncoder from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.ensemble import ExtraTreesClassifier # 加载数据 data = pd.read_csv('train.csv') # 第一步:正确标记目标列——同一城市中,将营收最高的分支标记为默认(1),其余为0 # 你可以根据需求调整规则,比如结合客户数量加权 data['Is_Default'] = data.groupby('City')['Revenue'].rank(ascending=False, method='first') == 1 data['Is_Default'] = data['Is_Default'].astype(int) # 划分特征和目标:移除Branch Code,目标为是否默认 feature_cols = ['City', 'State', 'Revenue', 'Customers'] X = data[feature_cols] y = data['Is_Default'] # 构建预处理管道:对分类特征做独热编码,数值特征直接保留 preprocessor = ColumnTransformer( transformers=[ ('cat_features', OneHotEncoder(sparse_output=False, drop='first'), ['City', 'State']), ('num_features', 'passthrough', ['Revenue', 'Customers']) ]) # 组合预处理和模型的完整管道 model_pipeline = Pipeline(steps=[ ('preprocessor', preprocessor), ('classifier', ExtraTreesClassifier(n_estimators=10)) ]) # 训练模型 model_pipeline.fit(X, y) # 测试预测:判断给定分支是否为默认 test_input = pd.DataFrame([['Chennai','TN',15000,3]], columns=feature_cols) pred_result = model_pipeline.predict(test_input) print('Is Default Branch?', 'Yes' if pred_result[0] == 1 else 'No') print("Model Score", model_pipeline.score(X, y))
另外要注意:你需要确保训练数据的标签是完全符合规则的——也就是同一城市中,确实把营收/客户最多的分支标记为Is_Default=1。如果原始数据的标签本身不符合这个逻辑,模型从一开始就学不到正确模式,这也是常见的问题根源。
内容的提问来源于stack exchange,提问作者Dilip M D

