@浙大疏锦行

import sklearn.datasets

# 获取 sklearn.datasets 模块下所有的属性名
all_names = dir(sklearn.datasets)

print("【1】自带的小数据集 (load_*) - 适合练手/测试:")
print([name for name in all_names if name.startswith("load_")]) # startswith 方法用于判断字符串是否以指定子字符串开头

print("\n【2】在线下载的大数据集 (fetch_*) - 适合真实项目:")
print([name for name in all_names if name.startswith("fetch_")])

print("\n【3】构造的假数据 (make_*) - 适合做实验/画图:")
print([name for name in all_names if name.startswith("make_")])
from sklearn.datasets import fetch_california_housing
import pandas as pd
import matplotlib.pyplot as plt

# 加载数据
california = fetch_california_housing()
X = california.data
y = california.target
feature_names = california.feature_names

# 创建 DataFrame
df = pd.DataFrame(X, columns=feature_names)
df['MedHouseVal'] = y

print("=== 加州房价数据集基本信息 ===")
print(f"样本数量: {df.shape[0]}")
print(f"特征数量: {df.shape[1] - 1}")
print("\n特征名称:")
for i, feature in enumerate(feature_names, 1):
    print(f"{i}. {feature}")

print("\n=== 数据统计摘要 ===")
print(df.describe())

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
# 80% 训练,20% 测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

regressors = {
    "Linear Regression (线性回归)": LinearRegression(),
    "Decision Tree (决策树)": DecisionTreeRegressor(random_state=42),
    "Random Forest (随机森林)": RandomForestRegressor(n_estimators=100, random_state=42),
    "Gradient Boosting (梯度提升)": GradientBoostingRegressor(n_estimators=100, random_state=42)
}

results = []      # 用于存指标
preds_dict = {}   # 用于存预测结果(画图用)

print("\n" + "="*30 + " 开始训练与评估 " + "="*30)

for name, model in regressors.items():
    # A. 训练
    model.fit(X_train, y_train)
    
    # B. 预测
    y_pred = model.predict(X_test)
    preds_dict[name] = y_pred # 存下来画图
    
    # C. 计算核心指标
    r2 = r2_score(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(y_test, y_pred)
    
    # D. 记录结果
    results.append({
        "模型名称": name,
        "R2": r2,      # 决定系数
        "RMSE": rmse,  # 均方根误差
        "MAE": mae     # 平均绝对误差
    })
    print(f"模型 {name} 训练完成。R2 = {r2:.4f}")

# ==========================================
# 5. 展示指标对比表
# ==========================================
results_df = pd.DataFrame(results).sort_values(by="R2", ascending=False)
print("\n" + "="*30 + " 最终性能排行榜 " + "="*30)
print(results_df)

# --- 模块一:准备工作 ---

# 1. 区分指标类型
# 对于回归问题,R2是效益型指标(越大越好),RMSE和MAE是成本型指标(越小越好)
benefit_cols = ['R2']  # R²分数越大越好
cost_cols = ['RMSE', 'MAE']  # 误差越小越好

# 2. 复制一份数据用于计算
# 首先,我们需要把"模型名称"设为索引,这样其他列就都是数值了
if '模型名称' in results_df.columns:
    data_eval = results_df.set_index('模型名称')
else:
    data_eval = results_df.copy()

print("=== 数据预处理 ===")
print("处理前的数据:")
print(results_df)
print(f"\n处理后的数据(模型名称作为索引):")
print(data_eval)
print(f"\n索引:{data_eval.index.tolist()}")
print(f"列名:{data_eval.columns.tolist()}")

# 3. 数据类型转换(确保数值列是浮点数)
# 现在只有数值列,可以安全转换了
data_eval = data_eval.astype(float)

print("\n=== 指标类型定义 ===")
print("步骤 1 完成:指标方向已定义。")
print(f"效益型指标 (+) 越大越好: {benefit_cols}")
print(f"成本型指标 (-) 越小越好: {cost_cols}")
print(f"\n用于MCDA分析的数据矩阵:")
print(data_eval)
print(f"\n数据形状:{data_eval.shape}")
print(f"数据类型:")
print(data_eval.dtypes)

# --- 模块二:数据标准化 ---

# 我们使用最小-最大归一化(Min-Max Normalization)
# 对于效益型指标(越大越好):标准化到 [0, 1],值越大越好
# 对于成本型指标(越小越好):需要先取倒数或负向处理,再标准化

from sklearn.preprocessing import MinMaxScaler
import numpy as np

print("=== 开始数据标准化 ===")
print("原始数据:")
print(data_eval)

# 创建标准化的DataFrame
data_normalized = pd.DataFrame(index=data_eval.index)

# 方法1:分别处理效益型和成本型指标(推荐)
scaler = MinMaxScaler()

# 1. 处理效益型指标(越大越好)
for col in benefit_cols:
    if col in data_eval.columns:
        # 直接标准化,因为越大越好
        values = data_eval[col].values.reshape(-1, 1)
        normalized_values = scaler.fit_transform(values)
        data_normalized[col] = normalized_values.flatten()
        print(f"效益型指标 '{col}' 已标准化:原始范围 [{data_eval[col].min():.4f}, {data_eval[col].max():.4f}] -> 标准化范围 [0, 1]")

# 2. 处理成本型指标(越小越好)
for col in cost_cols:
    if col in data_eval.columns:
        # 对于成本型指标,有两种常用方法:
        # 方法A:先取倒数再标准化(适用于正值)
        if (data_eval[col] > 0).all():  # 确保所有值都大于0
            # 取倒数,使越小越好变为越大越好
            inverse_values = 1 / data_eval[col].values.reshape(-1, 1)
            normalized_values = scaler.fit_transform(inverse_values)
            data_normalized[col] = normalized_values.flatten()
            print(f"成本型指标 '{col}' 已标准化(取倒数法):原始范围 [{data_eval[col].min():.4f}, {data_eval[col].max():.4f}] -> 标准化范围 [0, 1]")
        else:
            # 方法B:使用负向标准化
            # 公式:1 - (x - min)/(max - min) = (max - x)/(max - min)
            max_val = data_eval[col].max()
            min_val = data_eval[col].min()
            normalized_values = (max_val - data_eval[col]) / (max_val - min_val)
            data_normalized[col] = normalized_values
            print(f"成本型指标 '{col}' 已标准化(负向法):原始范围 [{min_val:.4f}, {max_val:.4f}] -> 标准化范围 [0, 1]")

print("\n标准化后的数据:")
print(data_normalized)



# 检查标准化结果
print("\n标准化后的数值范围:")
for col in data_normalized.columns:
    print(f"{col}: [{data_normalized[col].min():.4f}, {data_normalized[col].max():.4f}]")

# 显示每个模型的综合表现(简单平均)
print("\n=== 初步综合得分(简单平均)===")
data_normalized['简单平均分'] = data_normalized.mean(axis=1)
sorted_scores = data_normalized['简单平均分'].sort_values(ascending=False)

print("各模型标准化后各指标得分:")
print(data_normalized)

print("\n模型排名(按简单平均分):")
for rank, (model, score) in enumerate(sorted_scores.items(), 1):
    print(f"{rank}. {model}: {score:.4f}")

# 保存标准化结果供后续使用
standardized_results = data_normalized.copy()

# --- 模块三:熵权法计算权重 ---

import numpy as np

print("=== 熵权法计算权重 ===")
print("标准化后的数据:")
print(data_normalized)

# 确保没有零值,避免对数计算错误
# 将0替换为一个很小的正数
data_for_entropy = data_normalized.copy()
epsilon = 1e-10  # 一个很小的正数
data_for_entropy = data_for_entropy.replace(0, epsilon)

print("\n数据处理(避免零值):")
print(data_for_entropy)

# 1. 计算每个指标下各方案的比重(概率)
m, n = data_for_entropy.shape  # m个方案(模型),n个指标
print(f"\n数据维度:{m} 个模型,{n} 个指标")

# 计算概率矩阵 P
P = data_for_entropy.values / np.sum(data_for_entropy.values, axis=0)

print("\n概率矩阵 P(每列和为1):")
print(P)

# 2. 计算每个指标的熵值
# 公式:e_j = -k * ∑(p_ij * ln(p_ij)),其中 k = 1/ln(m)
k = 1 / np.log(m)  # 调节系数

# 计算熵值
entropy_values = np.zeros(n)
for j in range(n):
    # 对每个指标计算熵值
    p_col = P[:, j]
    # 避免ln(0)的情况,使用np.log函数会自动处理
    entropy_values[j] = -k * np.sum(p_col * np.log(p_col))

print(f"\n各指标熵值:")
for i, col in enumerate(data_for_entropy.columns):
    print(f"{col}: {entropy_values[i]:.6f}")

# 3. 计算差异系数(信息效用值)
# 公式:d_j = 1 - e_j
d_values = 1 - entropy_values
print(f"\n各指标差异系数(信息效用值):")
for i, col in enumerate(data_for_entropy.columns):
    print(f"{col}: {d_values[i]:.6f}")

# 4. 计算权重
# 公式:w_j = d_j / ∑d_j
weights = d_values / np.sum(d_values)
print(f"\n各指标权重(熵权法):")
for i, col in enumerate(data_for_entropy.columns):
    print(f"{col}: {weights[i]:.6f} ({(weights[i]*100):.2f}%)")

# 创建权重字典和DataFrame
weight_dict = dict(zip(data_for_entropy.columns, weights))
weights_df = pd.DataFrame({
    '指标': list(weight_dict.keys()),
    '权重': list(weight_dict.values()),
    '权重百分比': [f"{w*100:.2f}%" for w in weight_dict.values()]
})

print("\n权重汇总表:")
print(weights_df)

# --- 模块四:TOPSIS 计算与排序 ---

print("=== TOPSIS 综合评价 ===")

# 1. 构建加权规范化矩阵 V
# 使用标准化后的数据 data_normalized 乘以 熵权法权重
print("\n1. 构建加权规范化矩阵 V = 标准化数据 × 权重")

# 创建权重向量,确保顺序与数据列一致
weight_vector = np.array([weight_dict[col] for col in data_normalized.columns])
print(f"权重向量: {weight_vector}")

# 计算加权规范化矩阵
V = data_normalized.values * weight_vector
V_df = pd.DataFrame(V, index=data_normalized.index, columns=data_normalized.columns)

print("\n加权规范化矩阵 V:")
print(V_df)

# 2. 确定正理想解 (V+) 和负理想解 (V-)
# 由于我们已经将所有指标标准化为效益型(越大越好)
# 所以正理想解取每列的最大值,负理想解取每列的最小值
V_plus = V_df.max()
V_minus = V_df.min()

print(f"\n2. 确定理想解和负理想解:")
for col in V_df.columns:
    print(f"{col}: 正理想解(V+)={V_plus[col]:.6f}, 负理想解(V-)={V_minus[col]:.6f}")

# 3. 计算欧氏距离
print("\n3. 计算欧氏距离:")

# D+ : 每个模型与正理想解的距离
D_plus = np.sqrt(((V_df - V_plus) ** 2).sum(axis=1))

# D- : 每个模型与负理想解的距离
D_minus = np.sqrt(((V_df - V_minus) ** 2).sum(axis=1))

print("\n各模型到正理想解的距离 D+:")
for model, distance in D_plus.items():
    print(f"  {model}: {distance:.6f}")

print("\n各模型到负理想解的距离 D-:")
for model, distance in D_minus.items():
    print(f"  {model}: {distance:.6f}")

# 4. 计算相对接近度 C_i (TOPSIS得分)
# Score = D- / (D+ + D-)
# 值域 [0, 1],越接近1越好
scores = D_minus / (D_plus + D_minus)

print("\n4. 计算相对接近度(TOPSIS得分):")
for model, score in scores.items():
    print(f"  {model}: {score:.6f}")

# 5. 整理最终结果
print("\n5. 整理最终排名结果:")

# 创建包含原始数据、标准化数据、TOPSIS得分的综合结果表
final_results = pd.DataFrame({
    '模型名称': data_eval.index,
    'R2_原始': data_eval['R2'],
    'RMSE_原始': data_eval['RMSE'],
    'MAE_原始': data_eval['MAE'],
    'R2_标准化': data_normalized['R2'],
    'RMSE_标准化': data_normalized['RMSE'],
    'MAE_标准化': data_normalized['MAE'],
    '到正理想解距离(D+)': D_plus.values,
    '到负理想解距离(D-)': D_minus.values,
    'TOPSIS得分': scores.values
})

# 计算排名(得分越高越好)
final_results['排名'] = final_results['TOPSIS得分'].rank(ascending=False, method='min').astype(int)

# 按排名排序
final_results = final_results.sort_values(by='排名')

print("\n=== TOPSIS综合评价结果 ===")
print(final_results.to_string(index=False))

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐