检测到数值特征: 1342个 检测到分类特征: 14个 Traceback (most recent call last): File "F:\Python_task\Lasso1.py", line 50, in <module> pipeline.fit(X, y) File "C:\Users\lenovo\anaconda3\envs\radi\lib\site-packages\sklearn\pipeline.py", line 394, in fit self._final_estimator.fit(Xt, y, **fit_params_last_step) File "C:\Users\lenovo\anaconda3\envs\radi\lib\site-packages\sklearn\linear_model\_coordinate_descent.py", line 1535, in fit X, y = self._validate_data( File "C:\Users\lenovo\anaconda3\envs\radi\lib\site-packages\sklearn\base.py", line 579, in _validate_data y = check_array(y, **check_y_params) File "C:\Users\lenovo\anaconda3\envs\radi\lib\site-packages\sklearn\utils\validation.py", line 800, in check_array _assert_all_finite(array, allow_nan=force_all_finite == "allow-nan") File "C:\Users\lenovo\anaconda3\envs\radi\lib\site-packages\sklearn\utils\validation.py", line 114, in _assert_all_finite raise ValueError( ValueError: Input contains NaN, infinity or a value too large for dtype('float64'). 报错,修正,并且我需要将结果文件输出为ENDING.xlsx
时间: 2025-07-21 19:54:47 浏览: 2
<think>我们遇到了新的错误:输入数据包含NaN、无穷大或超出float64范围的值。虽然我们之前已经使用了填充器,但可能是在处理过程中出现了问题。此外,我们需要将输出文件命名为ENDING.xlsx。
解决方案:
1. 在预处理之前,检查数据中是否包含无穷大或非常大的值,并进行处理。
2. 确保在管道中,缺失值和异常值都被正确处理。
3. 由于分类特征使用独热编码后特征数量会膨胀(特别是当分类特征有14个,且每个特征可能有多个类别时),可能会遇到内存或计算问题。但当前错误是数据中存在NaN或无穷大,所以我们要先解决数据清洗问题。
改进步骤:
- 在读取数据后,先检查数据中是否有无穷大或NaN,并替换为NaN,然后用填充器填充(但我们的管道已经包含填充器,所以可能是填充器之前的数据有非数值问题?)
- 由于我们有分类特征,在填充之前,我们可能需要对数值特征和分类特征分别进行清洗。
然而,错误发生在LassoCV拟合阶段,提示输入数据包含NaN或无穷大。这可能是由于预处理后仍然存在缺失值?或者数据中确实有非数值字符串(比如,数值特征列中混入了字符串)?
我们将采取以下措施:
1. 在构建管道前,先对原始数据进行检查和清理(确保数值特征列都是数值类型,如果不是,尝试转换或处理)。
2. 增加一个步骤:在分离X和y之后,将数值特征列中的非数值转换为NaN,这样我们的填充器就可以填充它们。
另外,由于分类特征有14个,数值特征有1342个,总特征数可能会很多(独热编码后更多),LassoCV可能会遇到计算问题。我们可以考虑:
- 增加LassoCV的`max_iter`(已经做了)
- 使用`tol`参数调整优化精度(默认1e-4,可以适当放宽以加速收敛)
- 如果特征过多,可以考虑使用特征选择方法(如方差过滤)先去除一些特征,但这里我们先解决数据清洗问题。
我们将修改代码:
步骤1:读取数据后,对数值特征列进行转换,将非数值转换为NaN(使用pd.to_numeric,errors='coerce')
步骤2:检查并替换无穷大值为NaN(这样填充器就会填充它们)
同时,我们将输出文件名改为'ENDING.xlsx'
修改后的代码:</think>您的数据中存在 NaN 或无限大值,这会导致 LassoCV 训练失败。我将修复这个问题并确保结果输出为 `ENDING.xlsx`。以下是完整的解决方案:
```python
import pandas as pd
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.linear_model import LassoCV
import openpyxl
from sklearn.exceptions import ConvergenceWarning
import warnings
# 忽略Lasso收敛警告
warnings.filterwarnings("ignore", category=ConvergenceWarning)
# 1. 读取数据
df = pd.read_excel('F.xlsx')
# 2. 分离特征和标签
X = df.iloc[:, :-1] # 所有特征列
y = df.iloc[:, -1] # 最后一列是类别标签View
# 3. 数据清洗 - 处理NaN和无穷大值
def clean_data(df):
# 替换无穷大值为NaN
df.replace([np.inf, -np.inf], np.nan, inplace=True)
# 检查并处理目标列中的NaN
if df.iloc[:, -1].isnull().any():
print(f"警告: 目标列包含 {df.iloc[:, -1].isnull().sum()} 个缺失值,已删除相应行")
df = df.dropna(subset=[df.columns[-1]])
return df
df = clean_data(df)
X = df.iloc[:, :-1]
y = df.iloc[:, -1]
# 4. 自动识别数值和分类特征
numeric_features = X.select_dtypes(include=['int', 'float']).columns.tolist()
categorical_features = X.select_dtypes(include=['object', 'category']).columns.tolist()
print(f"检测到数值特征: {len(numeric_features)}个")
print(f"检测到分类特征: {len(categorical_features)}个")
# 5. 创建预处理转换器
preprocessor = ColumnTransformer(
transformers=[
('num', Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')), # 数值特征用中位数填充
('scaler', StandardScaler()) # 标准化
]), numeric_features),
('cat', Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')), # 分类特征用众数填充
('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False)) # 独热编码
]), categorical_features)
],
remainder='drop' # 丢弃未指定的列
)
# 6. 创建完整管道
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('lassocv', LassoCV(cv=5, random_state=42, max_iter=10000, n_jobs=-1)) # 并行计算
])
# 7. 训练模型
pipeline.fit(X, y)
lasso_model = pipeline.named_steps['lassocv']
# 8. 获取特征名称
# 获取数值特征名称
numeric_feature_names = numeric_features
# 获取分类特征名称(独热编码后)
if categorical_features:
cat_encoder = pipeline.named_steps['preprocessor'].named_transformers_['cat'].named_steps['onehot']
cat_feature_names = cat_encoder.get_feature_names_out(categorical_features).tolist()
else:
cat_feature_names = []
# 合并所有特征名称
all_feature_names = numeric_feature_names + cat_feature_names
# 9. 提取重要特征和系数
feature_coefs = lasso_model.coef_
# 使用相对阈值选择重要特征
max_coef = np.max(np.abs(feature_coefs))
threshold = max(0.001, max_coef * 0.01) # 至少0.001,最多1%的最大系数值
selected_features = np.where(np.abs(feature_coefs) > threshold)[0]
selected_feature_names = [all_feature_names[i] for i in selected_features]
selected_coefs = feature_coefs[selected_features]
# 10. 创建结果DataFrame
results_df = pd.DataFrame({
'特征名称': selected_feature_names,
'Lasso系数': selected_coefs,
'系数绝对值': np.abs(selected_coefs)
}).sort_values(by='系数绝对值', ascending=False)
# 11. 添加模型信息表
model_info = pd.DataFrame({
'指标': ['最佳alpha', '筛选特征数', '原始特征数', '交叉验证折数', '最大迭代次数', '阈值'],
'值': [lasso_model.alpha_, len(selected_features), len(all_feature_names), 5, 10000, threshold]
})
# 12. 导出到ENDING.xlsx
with pd.ExcelWriter('ENDING.xlsx') as writer:
# 特征筛选结果表
results_df.to_excel(writer, sheet_name='重要特征', index=False)
# 模型信息表
model_info.to_excel(writer, sheet_name='模型信息', index=False)
# 原始数据表(带筛选标记)
df_out = df.copy()
# 标记原始特征是否被选中
for col in df_out.columns[:-1]:
if col in selected_feature_names:
df_out[col + '_选中'] = '是'
elif any(s.startswith(col + '_') for s in selected_feature_names):
df_out[col + '_选中'] = '部分选中'
else:
df_out[col + '_选中'] = '否'
df_out.to_excel(writer, sheet_name='原始数据', index=False)
# 获取Excel工作簿和工作表对象
workbook = writer.book
worksheet = writer.sheets['重要特征']
# 设置列宽
worksheet.column_dimensions['A'].width = 35
worksheet.column_dimensions['B'].width = 15
worksheet.column_dimensions['C'].width = 15
# 添加条件格式
red_fill = openpyxl.styles.PatternFill(start_color='FFC7CE', end_color='FFC7CE', fill_type='solid')
green_fill = openpyxl.styles.PatternFill(start_color='C6EFCE', end_color='C6EFCE', fill_type='solid')
for row in range(2, len(results_df) + 2):
cell = worksheet[f'B{row}']
if cell.value > 0:
cell.fill = green_fill
elif cell.value < 0:
cell.fill = red_fill
# 13. 添加汇总信息
print("="*70)
print(f"结果已成功导出到: ENDING.xlsx")
print(f"包含三个工作表: 1.重要特征 2.模型信息 3.原始数据")
print(f"原始特征数: {len(all_feature_names)}")
print(f"筛选出重要特征数: {len(selected_features)} (阈值: {threshold:.6f})")
print(f"最佳正则化参数 alpha: {lasso_model.alpha_:.6f}")
print("="*70)
```
### 主要修复和改进:
1. **数据清洗增强**:
```python
def clean_data(df):
# 替换无穷大值为NaN
df.replace([np.inf, -np.inf], np.nan, inplace=True)
# 检查并处理目标列中的NaN
if df.iloc[:, -1].isnull().any():
print(f"警告: 目标列包含 {df.iloc[:, -1].isnull().sum()} 个缺失值,已删除相应行")
df = df.dropna(subset=[df.columns[-1]])
return df
```
- 自动处理无穷大值(inf)和缺失值(NaN)
- 删除目标列包含缺失值的行
2. **特征选择阈值优化**:
```python
max_coef = np.max(np.abs(feature_coefs))
threshold = max(0.001, max_coef * 0.01) # 至少0.001,最多1%的最大系数值
```
- 动态阈值适应不同规模的数据
- 避免因系数值过小而遗漏重要特征
3. **分类特征处理改进**:
```python
('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
```
- 设置`sparse_output=False`避免内存问题
- 更适合处理大量特征(1342个数值特征+14个分类特征)
4. **性能优化**:
```python
('lassocv', LassoCV(cv=5, random_state=42, max_iter=10000, n_jobs=-1))
```
- `n_jobs=-1`启用多核并行计算加速训练
- 增加最大迭代次数确保收敛
5. **结果标记细化**:
```python
if col in selected_feature_names:
df_out[col + '_选中'] = '是'
elif any(s.startswith(col + '_') for s in selected_feature_names):
df_out[col + '_选中'] = '部分选中'
else:
df_out[col + '_选中'] = '否'
```
- "是":整个特征被选中
- "部分选中":分类特征的某些类别被选中
- "否":特征未被选中
### 使用说明:
1. **运行要求**:
```bash
pip install pandas numpy scikit-learn openpyxl
```
2. **输出文件**:
- 结果将保存为 `ENDING.xlsx`
- 包含三个工作表:`重要特征`、`模型信息`、`原始数据`
3. **处理大型数据**:
- 如果数据量非常大(>10,000行),考虑先进行采样:
```python
# 在读取数据后添加
if len(df) > 10000:
df = df.sample(10000, random_state=42)
```
4. **自定义选项**:
- 调整阈值:修改`threshold`计算方式
- 更改交叉验证折数:修改`cv`参数
- 控制输出:调整`print`语句
### 预期输出:
```
======================================================================
结果已成功导出到: ENDING.xlsx
包含三个工作表: 1.重要特征 2.模型信息 3.原始数据
原始特征数: 1456
筛选出重要特征数: 87 (阈值: 0.023145)
最佳正则化参数 alpha: 0.123456
======================================================================
```
阅读全文
相关推荐



















