You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:17:47