CSV含数据却报n_samples=0错误,求排查及模型分析方案
问题与解决方案
错误原因分析
报错ValueError: Cannot have number of splits n_splits=7 greater than the number of samples: n_samples=0说明交叉验证时特征集X和标签集y无样本,核心原因如下:
- 文件加载失败:
pd.read_csv('datoscorto.csv')未正确读取文件——要么文件不在代码当前工作目录,要么文件名拼写错误,导致加载空DataFrame。 - 缺失值处理过度:
dropna()删除了所有行,因数据存在某列全为缺失值的情况,处理后datos变为空表。 - 标签列逻辑问题:若
sigdif_lect8b_rbd列无值等于-1,创建etiqueta后可能导致后续样本过滤,但不会直接引发n_samples=0,多为前两个原因导致。
修正步骤与代码优化
1. 验证文件加载与数据状态
添加数据状态检查,确认加载和预处理后的样本量:
import pandas as pd import numpy as np from sklearn.model_selection import cross_val_score, KFold from sklearn.preprocessing import StandardScaler from sklearn.dummy import DummyClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.svm import SVC from sklearn.metrics import accuracy_score, precision_score, recall_score # 加载数据(建议使用绝对路径避免路径问题) datos = pd.read_csv('datoscorto.csv', encoding='latin-1') print(f"加载后数据行数: {len(datos)}") # 确认是否加载到有效数据 print(datos.isnull().sum()) # 查看各列缺失值数量 # 替代直接删除:按数据类型填充缺失值 for col in datos.columns: if datos[col].dtype in ['int64', 'float64']: datos[col] = datos[col].fillna(datos[col].median()) else: datos[col] = datos[col].fillna(datos[col].mode()[0]) print(f"预处理后数据行数: {len(datos)}") # 确认仍有样本留存 # 创建标签并检查分布 datos['etiqueta'] = datos['sigdif_lect8b_rbd'].apply(lambda x: 1 if x == -1 else 0) print(datos['etiqueta'].value_counts()) # 变量选择与特征标准化(对LR、KNN、SVM模型至关重要) columnas_caracteristicas = ['nalu_lect8b_rbd', 'prom_lect8b_rbd', 'dif_lect8b_rbd'] scaler = StandardScaler() X = scaler.fit_transform(datos[columnas_caracteristicas]) y = datos['etiqueta'] # 动态设置交叉验证折数:避免折数超过样本量 kf = KFold(n_splits=min(5, len(datos)), shuffle=True, random_state=42) modelos = [ DummyClassifier(strategy='most_frequent'), DecisionTreeClassifier(random_state=42), LogisticRegression(random_state=42), RandomForestClassifier(random_state=42), KNeighborsClassifier(), SVC(random_state=42) ] # 模型评估(处理样本不平衡导致的评估报错) for modelo in modelos: print(f"\nModelo: {modelo.__class__.__name__}") try: scores = cross_val_score(modelo, X, y, scoring='accuracy', cv=kf) print(f"Accuracy: {scores.mean():.4f}") precision_scores = cross_val_score(modelo, X, y, scoring='precision', cv=kf) print(f"Precision: {precision_scores.mean():.4f}") recall_scores = cross_val_score(modelo, X, y, scoring='recall', cv=kf) print(f"Recall: {recall_scores.mean():.4f}") except ValueError as e: print(f"评估出错: {e}")
2. 寻找与sigdif_lect8b_rbd=-1相关的显著特征
- 树模型特征重要性:通过随机森林查看特征权重:
rf = RandomForestClassifier(random_state=42) rf.fit(X, y) feature_importance = pd.DataFrame({ '特征': columnas_caracteristicas, '重要性': rf.feature_importances_ }).sort_values(by='重要性', ascending=False) print(feature_importance)
- 逻辑回归系数:标准化后,系数绝对值越大,特征影响越显著:
lr = LogisticRegression(random_state=42) lr.fit(X, y) coef_df = pd.DataFrame({ '特征': columnas_caracteristicas, '系数': lr.coef_[0] }).sort_values(by='系数', ascending=False) print(coef_df)
- 统计检验:通过t检验判断特征在两类样本间的显著差异:
from scipy.stats import ttest_ind group1 = datos[datos['sigdif_lect8b_rbd'] == -1][columnas_caracteristicas] group2 = datos[datos['sigdif_lect8b_rbd'] != -1][columnas_caracteristicas] for col in columnas_caracteristicas: stat, p_value = ttest_ind(group1[col], group2[col], nan_policy='omit') print(f"特征 {col}: t值={stat:.4f}, p值={p_value:.4f}") # p值<0.05说明该特征在两组间存在显著差异
内容的提问来源于stack exchange,提问作者W_F
相关产品推荐
相关产品推荐

