一·随机森林的算法填充

import pandas as pd
import matplotlib.pyplot as plt
import fill_data

data = pd.read_excel("矿物数据.xls")
data = data[data['矿物类型'] != 'E']  # 删除特殊的类别E。整个数据集中只存在1个E数据。
null_num = data.isnull()
null_total = null_num.sum()  # 检测每列中的缺失值

X_whole = data.drop('矿物类型', axis=1).drop('序号', axis=1)  # 获取全部特征数据
y_whole = data.矿物类型  # 获取全部标签数据

label_dict = {"A": 0, "B": 1, "C": 2, "D": 3}  # 将数据中的中文标签转换为字符
encoded_labels = [label_dict[label] for label in y_whole]
y_whole = pd.Series(encoded_labels, name='矿物类型')  # 将列表转换为Pandas Series

# 数据中存在大量字符串数值、\、空格等异常数据。字符串数值直接转换为float,\和空格转换为nan
for column_name in X_whole.columns:
    X_whole[column_name] = pd.to_numeric(X_whole[column_name], errors='coerce')
#pd.to_numeric()函数尝试将参数中的数据转换为数值类型。如果转换失败,它会引发一个异常,
#设置errors='coerce',会将无法转换的值设置为NaN。

"""数据标准化:Z标准化"""
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_whole_Z = scaler.fit_transform(X_whole)
X_whole = pd.DataFrame(X_whole_Z, columns=X_whole.columns)  # Z标准化处理后为numpy数据,这里再转换回pandas数据

'''数据集的切分'''
from sklearn.model_selection import train_test_split
x_train_w, x_test_w, y_train_w, y_test_w = \
    train_test_split(X_whole, y_whole, test_size=0.3, random_state=50000)

'''数据中存在空缺,进行6种方法进行填充'''
## 1、只保留完整数据集
# x_train_fill,y_train_fill = fill_data.cca_train_fill(x_train_w,y_train_w)#调用自己写的implement_data.py
# 测试集的填充
# x_test_fill,y_test_fill = fill_data.cca_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)#调用

#2、使用平均值的方法对数据进行填充
# x_train_fill,y_train_fill = fill_data.mean_train_fill(x_train_w,y_train_w)
# 测试集的填充
# x_test_fill,y_test_fill = fill_data.mean_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

##3、使用中位数的方法对数据进行填充
# x_train_fill,y_train_fill = fill_data.median_train_fill(x_train_w,y_train_w)#调用自己写的implement_data
##测试集的填充
# x_test_fill,y_test_fill = fill_data.median_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

##4、使用众数的方法对数据进行填充
# x_train_fill,y_train_fill = fill_data.mode_train_fill(x_train_w,y_train_w)#调用自己写的implement_data.p
###测试集的填充
# x_test_fill,y_test_fill = fill_data.mode_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)#调

# 5、线性回归算法实现训练数据集、测试数据集的填充
x_train_fill,y_train_fill = fill_data.lr_train_fill(x_train_w,y_train_w)#调用自己写的#implement_data.py文
# 测试集的填充
#x_test_fill,y_test_fill = fill_data.lr_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)#调用自

## 6、随机森林算法实现训练数据集、测试数据集的填充
x_train_fill,y_train_fill = fill_data.rf_train_fill(x_train_w,y_train_w)
# 测试集的填充
x_test_fill,y_test_fill = fill_data.rf_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)#调用自己



'''smote算法实现数据集的拟合,解决样本不均衡'''
from imblearn.over_sampling import SMOTE
oversampler = SMOTE(k_neighbors=1, random_state=42)#数据对象
os_x_train, os_y_train = oversampler.fit_resample(x_train_fill, y_train_fill)#人工拟合的只是训练集。


'''数据保存为excel文件'''
data_train = pd.concat([os_y_train,os_x_train],axis=1).sample(frac=1, random_state=4)#sample()方法用于从 `DataFrame` 中随机抽取行,`frac` 表示抽取行的比例。
data_test = pd.concat([y_test_fill,x_test_fill],axis=1)#测试集不用传入模型训练,无需打乱顺序。

data_train.to_excel(r'.//temp_data//训练数据集[平均值填充的数据].xlsx', index=False)
data_test.to_excel(r'.//temp_data//测试数据集[平均值填充的数据].xlsx', index=False)
from sklearn.ensemble import RandomForestRegressor
'''---------------------随机森林算法实现训练数据集、测试数据集的填充---------------------'''
def rf_train_fill(train_data, train_label):
    '''使用随机森林算法填充训练数据集中的缺失值'''
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)#data数据行号存在混乱(因随机抽取70%的数据作为训练集导致),进行重置
    train_data_X = train_data_all.drop('矿物类型', axis=1)

    null_num = train_data_X.isnull().sum()  # 查看每个特征中存在空数据的个数
    null_num_sorted = null_num.sort_values(ascending=True)#将空数据的类别从小到大进行排序

    filling_feature = []
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] !=0:
            X = train_data_X[filling_feature].drop(i, axis=1)
            y = train_data_X[i]
            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()#获取空数据对应行号
            X_train = X.drop(row_numbers_mg_null)  # 非空的数据作为训练数据集
            y_train = y.drop(row_numbers_mg_null)  # 非空的标签作为训练标签
            X_test = X.iloc[row_numbers_mg_null]  # 空的数据作为测试数据集

            regr = RandomForestRegressor(n_estimators=100, random_state=42)  # 创建随机森林回归模型
            regr.fit(X_train, y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            train_data_X.loc[row_numbers_mg_null,i] = y_pred#loc和iloc的区别:iloc[行号.列号]  loc[行名,列名],例如iloc[3,4]
            print('完成训练数据集中的\'{}\'列数据的填充'.format(i))
    return train_data_X, train_data_all.矿物类型

def rf_test_fill(train_data, train_label, test_data, test_label):
    '''使用随机森林算法对测试数据集中缺失的数据进行填充,主要是基于这样一个思想:
    根据已经填充后的训练数据集建立模型,来补充空缺的测试数据集。'''
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)

    test_data_all = pd.concat([test_data, test_label], axis=1)
    test_data_all = test_data_all.reset_index(drop=True)

    train_data_X = train_data_all.drop('矿物类型', axis=1)
    test_data_X = test_data_all.drop('矿物类型', axis=1)
    null_num = test_data_X.isnull().sum()
    null_num_sorted = null_num.sort_values(ascending=True)

    filling_feature = []
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] !=0:
            X_train = train_data_X[filling_feature].drop(i, axis=1)
            y_train = train_data_X[i]
            X_test = test_data_X[filling_feature].drop(i, axis=1)
            row_numbers_mg_null = test_data_X[test_data_X[i].isnull()].index.tolist()#获取空数据对应行号
            X_test = X_test.iloc[row_numbers_mg_null]  # 空的数据作为测试数据集

            regr = RandomForestRegressor(n_estimators=100, random_state=42)  # 创建随机森林回归模型
            regr.fit(X_train, y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            test_data_X.loc[row_numbers_mg_null,i] = y_pred
            print('完成测试数据集中的\'{}\'列数据的填充'.format(i))
    return test_data_X, test_data_all.矿物类型

rf_train_fill 函数(训练集填充)

python

运行

from sklearn.ensemble import RandomForestRegressor
  • 导入随机森林回归器,用于构建预测缺失值的模型(因为缺失值是连续数值,所以用回归而非分类)

python

运行

'''---------------------随机森林算法实现训练数据集、测试数据集的填充---------------------'''
def rf_train_fill(train_data, train_label):
  • 定义rf_train_fill函数,参数是训练特征(train_data,对应整体代码中的x_train_w)和训练标签(train_label,对应y_train_w
  • 功能:用随机森林填充训练集中的缺失值,返回填充后的训练特征和标签

python

运行

    train_data_all = pd.concat([train_data, train_label], axis=1)
  • 合并训练特征和标签(按列合并,axis=1),得到包含特征 + 标签的完整训练数据
  • 原因:后续填充时可能需要保持特征与标签的对应关系(虽然填充逻辑中未直接用标签,但保留完整结构更安全)

python

运行

    train_data_all = train_data_all.reset_index(drop=True)
  • 重置数据的索引(drop=True表示删除原有索引,不保留为新列)
  • 原因:之前用train_test_split划分数据集时,索引可能被打乱(不是连续的 0,1,2...),重置后方便后续按行索引操作

python

运行

    train_data_X = train_data_all.drop('矿物类型', axis=1)
  • 从合并数据中删除标签列(矿物类型),得到纯特征数据(train_data_X
  • 因为填充操作只针对特征,不涉及标签

python

运行

    null_num = train_data_X.isnull().sum()
  • 统计每个特征列的缺失值数量(isnull()判断是否为 NaN,sum()按列求和)
  • 例如:若某列有 10 个 NaN,null_num中该列对应的值就是 10

python

运行

    null_num_sorted = null_num.sort_values(ascending=True)
  • 对缺失值数量按升序排序(ascending=True
  • 核心逻辑:先处理缺失值少的特征(用其他更完整的特征预测它),再处理缺失值多的特征(避免用已填充过的、误差可能较大的特征做过多预测)

python

运行

    filling_feature = []
  • 创建空列表,用于记录 “已经处理过的特征”
  • 作用:后续用这些已处理的特征作为输入,预测当前需要填充的特征

python

运行

    for i in null_num_sorted.index:
  • 遍历排序后的特征名称(按缺失值从少到多的顺序)

python

运行

        filling_feature.append(i)
  • 将当前遍历的特征加入 “已处理列表”
  • 即使该特征没有缺失值,也会加入(作为后续其他特征的预测输入)

python

运行

        if null_num_sorted[i] !=0:
  • 只处理有缺失值的特征(无缺失值的特征跳过填充逻辑)

python

运行

            X = train_data_X[filling_feature].drop(i, axis=1)
  • 构建 “预测输入特征集”:从已处理的特征中,去掉当前要填充的特征i
  • 例如:当前填充特征是Fe,已处理特征有SiO2Al2O3Fe,则X就是SiO2Al2O3的数据(用它们预测Fe的缺失值)

python

运行

            y = train_data_X[i]
  • 定义 “预测目标”:当前要填充的特征i的所有值(包括非缺失和缺失的)

python

运行

            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()
  • 找到特征i中所有缺失值所在的行索引,并转为列表
  • 例如:Fe列在第 5、10、15 行有缺失,则这个列表就是[5,10,15]

python

运行

            X_train = X.drop(row_numbers_mg_null)
  • 构建模型的训练输入:从X中删除缺失值所在的行(只保留特征i非缺失的行)
  • 这些行的特征i有真实值,可用于训练模型

python

运行

            y_train = y.drop(row_numbers_mg_null)
  • 构建模型的训练目标:从y中删除缺失值所在的行(只保留特征i的非缺失值)

python

运行

            X_test = X.iloc[row_numbers_mg_null]
  • 构建模型的测试输入:从X中提取缺失值所在的行(这些行的特征i需要被预测填充)

python

运行

            regr = RandomForestRegressor(n_estimators=100, random_state=42)
  • 创建随机森林回归模型:n_estimators=100表示用 100 棵树,random_state=42固定随机种子(保证结果可复现)

python

运行

            regr.fit(X_train, y_train)
  • 用非缺失数据训练模型:学习输入特征X_train与目标y_train(特征i的真实值)的关系

python

运行

            y_pred = regr.predict(X_test)
  • 预测缺失值:用训练好的模型,对缺失行的输入特征X_test进行预测,得到特征i缺失值的预测结果

python

运行

            train_data_X.loc[row_numbers_mg_null,i] = y_pred
  • 填充缺失值:将预测结果y_pred赋值给特征i的缺失行(通过行索引定位)
  • loc按 “行索引 + 列名” 定位,确保准确填充到缺失位置

python

运行

            print('完成训练数据集中的\'{}\'列数据的填充'.format(i))
  • 打印日志:提示当前特征i的填充已完

python

运行

    return train_data_X, train_data_all.矿物类型
  • 函数返回:填充后的训练特征(train_data_X)和对应的标签(train_data_all.矿物类型
  • 对应整体代码中接收的x_train_fill, y_train_fill

rf_test_fill 函数(测试集填充)

python

运行

def rf_test_fill(train_data, train_label, test_data, test_label):
  • 定义rf_test_fill函数,参数包括:填充后的训练特征(train_data)、训练标签(train_label)、原始测试特征(test_data,对应x_test_w)、测试标签(test_label,对应y_test_w
  • 功能:用训练集的数据训练模型,填充测试集中的缺失值,返回填充后的测试特征和标签

python

运行

    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
  • 合并填充后的训练特征和标签,重置索引(同训练集填充逻辑,统一格式)

python

运行

    test_data_all = pd.concat([test_data, test_label], axis=1)
    test_data_all = test_data_all.reset_index(drop=True)
  • 合并原始测试特征和标签,重置索引(处理测试集的索引混乱问题)

python

运行

    train_data_X = train_data_all.drop('矿物类型', axis=1)
    test_data_X = test_data_all.drop('矿物类型', axis=1)
  • 从合并数据中分离出训练集特征(train_data_X)和测试集特征(test_data_X)(均删除标签列)

python

运行

    null_num = test_data_X.isnull().sum()
    null_num_sorted = null_num.sort_values(ascending=True)
  • 统计测试集每个特征的缺失值数量,并按升序排序(同训练集逻辑,先处理缺失少的)

python

运行

    filling_feature = []
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] !=0:
  • 逻辑同训练集:创建 “已处理特征列表”,遍历测试集特征(按缺失值从少到多),只处理有缺失值的特征

python

运行

            X_train = train_data_X[filling_feature].drop(i, axis=1)
  • 构建模型的训练输入:使用训练集的已处理特征(而非测试集自身),去掉当前要填充的特征i
  • 核心:测试集填充的模型完全基于训练集,避免数据泄露(测试集信息不能参与模型训练)

python

运行

            y_train = train_data_X[i]
  • 构建模型的训练目标:训练集中特征i的所有值(此时训练集已填充完整,无缺失)

python

运行

            X_test = test_data_X[filling_feature].drop(i, axis=1)
            row_numbers_mg_null = test_data_X[test_data_X[i].isnull()].index.tolist()
            X_test = X_test.iloc[row_numbers_mg_null]
  • 构建模型的测试输入:从测试集的已处理特征中,提取当前特征i缺失值所在行的数据(用于预测填充)

python

运行

            regr = RandomForestRegressor(n_estimators=100, random_state=42)
            regr.fit(X_train, y_train)
            y_pred = regr.predict(X_test)
            test_data_X.loc[row_numbers_mg_null,i] = y_pred
            print('完成测试数据集中的\'{}\'列数据的填充'.format(i))

  • 逻辑同训练集:用训练集数据训练模型,预测测试集缺失值并填充,打印日志

python

运行

    return test_data_X, test_data_all.矿物类型

二·模型算法

一·算法--逻辑回归

  • 函数返回:填充后的测试特征(test_data_X)和对应的标签(test_data_all.矿物类型
  • 对应整体代码中接收的x_test_fill, y_test_fill
import pandas as pd
from sklearn import metrics

# 数据提取
train_data = pd.read_excel(r'./temp_data/训练数据集[平均值填充的数据].xlsx')
train_data_x = train_data.iloc[:, 1:]  # 训练数据集的特征
train_data_y = train_data.iloc[:, 0]  # 训练数据集的测试标签label

test_data = pd.read_excel(r'./temp_data/测试数据集[平均值填充的数据].xlsx')
test_data_x = test_data.iloc[:, 1:]  # 测试数据集的特征
test_data_y = test_data.iloc[:, 0]  # 测试数据集的测试标签label

result_data = {}  # 用来保存后面6种算法的结果

'''#####################逻辑回归LR算法实现代码###########################'''
from sklearn.linear_model import LogisticRegression

from sklearn.model_selection import GridSearchCV  # 网格搜索


param_grid = {
    'penalty': ['l1', 'l2', 'elasticnet', 'none'],  # 正则化类型
    'C': [0.001, 0.01, 0.1, 1, 10, 100],  # 正则化强度的倒数
    'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],  # 优化算法
    'max_iter': [100, 200, 500],  # 最大迭代次数
    'multi_class': ['auto', 'ovr', 'multinomial'],
}  # 多分类策略(注意: 'none' 惩罚时不支持 'multinomial')
# 注意: 'penalty' 为 'none' 时, 'C' 将被忽略。而且, 不是所有的求解器都支持所有的正则化选项。
# 另外, 当使用 'liblinear' 求解器时, 'multi_class' 只能为 'ovr'。
# 因此, 在实际使用中, 可能需要针对特定的求解器调整参数网格。

# 注意: 上述参数网格在实际应用中可能需要调整, 因为某些参数组合可能不支持·或不稳定。
# 例如, 当使用L1正则化时, 'solver' 参数就不能使用 'newton-cg', 'sag' 和 'lbfgs'。
# 同样地, 当 'penalty' 是 'none' 时, 'C' 参数将不起作用。

# 创建Logistic回归模型实例
logreg = LogisticRegression()
grid_search = GridSearchCV(logreg, param_grid, cv=5)  # 创建GridSearchCV对象
grid_search.fit(train_data_x, train_data_y)  # 在训练集上执行网格搜索
print("Best parameters set found on development set:")  # 输出最佳参数
print(grid_search.best_params_)
...

"""建立最优模型"""
LR_result = {}  # 用来保存训练之后的结果。
lr = LogisticRegression(C=0.001, max_iter=100, penalty='none', solver='newton-cg')  # 逻辑回归的参
lr.fit(train_data_x, train_data_y)

'''测试结果【含训练数据集的测试 + 测试数据集的测试】'''
train_predicted = lr.predict(train_data_x)  # 训练数据集的预测结果
print('LR的train:\n', metrics.classification_report(train_data_y, train_predicted))
test_predicted = lr.predict(test_data_x)  # 测试数据集的预测结果
print('LR的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集的
a = metrics.classification_report(test_data_y, test_predicted, digits=6)  # digits表示保留有效位数
b = a.split()

LR_result['recall_0'] = float(b[6])     # 添加类别为0的召回率
LR_result['recall_1'] = float(b[11])    # 添加类别为1的召回率
LR_result['recall_2'] = float(b[16])    # 添加类别为2的召回率
LR_result['recall_3'] = float(b[21])    # 添加类别为3的召回率
LR_result['acc'] = float(b[25])         # 添加accuracy的结果
result_data['LR'] = LR_result  # result_data是总体的结果,
print('lr结束')

分别确立确立特征x和y标签

import pandas as pd
from sklearn import metrics

# 数据提取
train_data = pd.read_excel(r'./temp_data/训练数据集[平均值填充的数据].xlsx')
train_data_x = train_data.iloc[:, 1:]  # 训练数据集的特征
train_data_y = train_data.iloc[:, 0]  # 训练数据集的测试标签label

test_data = pd.read_excel(r'./temp_data/测试数据集[平均值填充的数据].xlsx')
test_data_x = test_data.iloc[:, 1:]  # 测试数据集的特征
test_data_y = test_data.iloc[:, 0]  # 测试数据集的测试标签label

result_data = {}  # 用来保存后面6种算法的结果

网格搜索——核心还是交叉验证

from sklearn.model_selection import GridSearchCV  # 网格搜索


param_grid = {
    'penalty': ['l1', 'l2', 'elasticnet', 'none'],  # 正则化类型
    'C': [0.001, 0.01, 0.1, 1, 10, 100],  # 正则化强度的倒数
    'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],  # 优化算法
    'max_iter': [100, 200, 500],  # 最大迭代次数
    'multi_class': ['auto', 'ovr', 'multinomial'],
}  
# 多分类策略(注意: 'none' 惩罚时不支持 'multinomial')
# 注意: 'penalty' 为 'none' 时, 'C' 将被忽略。而且, 不是所有的求解器都支持所有的正则化选项。
# 另外, 当使用 'liblinear' 求解器时, 'multi_class' 只能为 'ovr'。
# 因此, 在实际使用中, 可能需要针对特定的求解器调整参数网格。

# 注意: 上述参数网格在实际应用中可能需要调整, 因为某些参数组合可能不支持·或不稳定。
# 例如, 当使用L1正则化时, 'solver' 参数就不能使用 'newton-cg', 'sag' 和 'lbfgs'。
# 同样地, 当 'penalty' 是 'none' 时, 'C' 参数将不起作用。
logreg = LogisticRegression()
grid_search = GridSearchCV(logreg, param_grid, cv=5)  # 创建GridSearchCV对象
grid_search.fit(train_data_x, train_data_y)  # 在训练集上执行网格搜索
print("Best parameters set found on development set:")  # 输出最佳参数
print(grid_search.best_params_)
logreg = LogisticRegression()

得到一个逻辑回归对象

grid_search = GridSearchCV(logreg, param_grid, cv=5)  # 创建GridSearchCV对象

然后参数进行网格交换实验,

GridSearchCV网格搜索算法内部就是交叉验证

C参数是惩罚因子

"""建立最优模型"""
LR_result = {}  # 用来保存训练之后的结果。
lr = LogisticRegression(C=0.001, max_iter=100, penalty='none', solver='newton-cg')  # 逻辑回归的参
lr.fit(train_data_x, train_data_y)
lr = LogisticRegression(C=0.001, max_iter=100, penalty='none', solver='newton-cg')  # 逻辑回归的参

这里就是把之前网络搜索的内容给填进来,

'''测试结果【含训练数据集的测试 + 测试数据集的测试】'''
train_predicted = lr.predict(train_data_x)  # 训练数据集的预测结果
print('LR的train:\n', metrics.classification_report(train_data_y, train_predicted))
test_predicted = lr.predict(test_data_x)  # 测试数据集的预测结果
print('LR的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集的
a = metrics.classification_report(test_data_y, test_predicted, digits=6)  # digits表示保留有效位数
b = a.split()

分别把预测集的y和测试集的y打印出来,然后比较

LR_result['recall_0'] = float(b[6])     # 添加类别为0的召回率
LR_result['recall_1'] = float(b[11])    # 添加类别为1的召回率
LR_result['recall_2'] = float(b[16])    # 添加类别为2的召回率
LR_result['recall_3'] = float(b[21])    # 添加类别为3的召回率
LR_result['acc'] = float(b[25])         # 添加accuracy的结果
result_data['LR'] = LR_result  # result_data是总体的结果,
print('lr结束')

                            

输入字典表格,返回到这个位置来

LR_result = {}  # 用来保存训练之后的结果。

然后保存训练好预测数据

二·算法--随机森林

'''#####################RF算法实现代码###########################'''
from sklearn.ensemble import RandomForestClassifier
# from sklearn.model_selection import GridSearchCV
#定义网络参数
# param_grid = {
#     'n_estimators': [50, 100, 200],  # 树的数量
#     'max_depth': [None, 10, 20, 30],  # 树的深度
#     'min_samples_split': [2, 5, 10],  # 节点分裂所需的最小样本数
#     'min_samples_leaf': [1, 2, 5],  # 叶子节点所需的最小样本数
#     'max_features': ['auto', 'sqrt', 'log2'],  # 最大特征数
#     'bootstrap': [True, False]  # 是否使用自举样本
# }

# ## 创建RandomForest分类器实例
# # rf = RandomForestClassifier()
#
# ## 创建GridSearchCV对象
# # grid_search = GridSearchCV(rf, param_grid, cv=5)
#
# ## 在训练集上执行网格搜索
# # grid_search.fit(train_data_x, train_data_y)
#
# ## 输出最佳参数
# # print("Best parameters set found on development set:")
# # print()
# # print(grid_search.best_params_)

RF_result = {}
rf = RandomForestClassifier(bootstrap=False,
                            max_depth=20,
                            max_features='log2',
                            min_samples_leaf=1,
                            min_samples_split=2,
                            n_estimators=50,
                            random_state=487)

rf.fit(train_data_x, train_data_y)
train_predicted = rf.predict(train_data_x)  # 训练数据集的预测结果
test_predicted = rf.predict(test_data_x)  # 测试数据集的预测结果

print('RF的train:\n', metrics.classification_report(train_data_y, train_predicted))  # 打印训练数据集的
print('RF的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集
rf_test_report = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = rf_test_report.split()

RF_result['recall_0'] = float(b[6])     # 添加类别为0的召回率
RF_result['recall_1'] = float(b[11])    # 添加类别为1的召回率
RF_result['recall_2'] = float(b[16])    # 添加类别为2的召回率
RF_result['recall_3'] = float(b[21])    # 添加类别为3的召回率
RF_result['acc'] = float(b[25])         # 添加accuracy的结果
result_data['RF'] = RF_result

这段代码实现了使用随机森林(Random Forest)算法进行分类任务,并对模型性能进行了评估。让我逐步解释代码的主要功能和流程:

  1. 导入必要的库

    python

    运行

    from sklearn.ensemble import RandomForestClassifier
    
     

    这里导入了 scikit-learn 库中的随机森林分类器。

  2. 参数网格(注释部分)
    代码中注释掉了一个参数网格param_grid和网格搜索(GridSearchCV)的相关代码。这部分的作用是:

    • 定义了一系列可能的超参数组合
    • 网格搜索会自动尝试这些组合,找到性能最佳的参数配置
    • 这是一种常用的模型调优方法
  3. 初始化随机森林模型

    python

    运行

    rf = RandomForestClassifier(bootstrap=False,
                               max_depth=20,
                               max_features='log2',
                               min_samples_leaf=1,
                               min_samples_split=2,
                               n_estimators=50,
                               random_state=487)
    
     

    这里使用了一组特定的超参数初始化了随机森林模型,这些参数可能是通过之前的网格搜索得到的最佳参数。

  4. 训练模型

    python

    运行

    rf.fit(train_data_x, train_data_y)
    
     

    使用训练数据(特征train_data_x和标签train_data_y)拟合模型。

  5. 模型预测

    python

    运行

    train_predicted = rf.predict(train_data_x)  # 训练数据集的预测结果
    test_predicted = rf.predict(test_data_x)    # 测试数据集的预测结果
    
     

    分别对训练集和测试集进行预测,得到预测结果。

  6. 模型评估

    python

    运行

    print('RF的train:\n', metrics.classification_report(train_data_y, train_predicted))
    print('RF的test:\n', metrics.classification_report(test_data_y, test_predicted))
    

     

    使用classification_report函数生成详细的分类评估报告,包括精确率(precision)、召回率(recall)、F1 分数等指标,并打印出来。

  7. 提取评估结果

    python

    运行

    rf_test_report = metrics.classification_report(test_data_y, test_predicted, digits=6)
    b = rf_test_report.split()
    
    RF_result['recall_0'] = float(b[6])     # 类别为0的召回率
    RF_result['recall_1'] = float(b[11])    # 类别为1的召回率
    RF_result['recall_2'] = float(b[16])    # 类别为2的召回率
    RF_result['recall_3'] = float(b[21])    # 类别为3的召回率
    RF_result['acc'] = float(b[25])         # 准确率
    result_data['RF'] = RF_result
    

     

    这段代码从评估报告中提取了特定类别的召回率和总体准确率,存储到RF_result字典中,最后将结果存入result_data

三·算法--SVM

# '''#####################SVM算法实现代码###########################'''
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn import metrics

# 定义参数网格
param_grid = {
    'C': [0.01, 0.1, 1, 2],  # 惩罚系数
    'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],  # 核函数类型
    'degree': [2, 3, 4, 5],  # 多项式核函数的阶数,仅在'poly'核函数下有效
    'gamma': ['scale', 'auto'] + [1],  # RBF, poly 和 sigmoid的核函数参数
    'coef0': [0.1],  # 核函数中的独立项,仅在'poly'和'sigmoid'核函数下有效
}
svc = SVC()  # 创建SVC分类器实例

## 创建GridSearchCV对象
grid_search = GridSearchCV(svc, param_grid, cv=5)

## 在训练集上执行网格搜索
grid_search.fit(train_data_x, train_data_y)

SVM_result = {}
svm = SVC(C=1, coef0=0.1, degree=4, gamma=1, kernel='poly', probability=True, random_state=10)

svm.fit(train_data_x, train_data_y)
test_predicted = svm.predict(test_data_x)  # 测试数据集的预测结果

print('SVM的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集的
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
print(a)

SVM_result['recall_0'] = float(b[6])     # 添加类别为0的召回率
SVM_result['recall_1'] = float(b[11])    # 添加类别为1的召回率
SVM_result['recall_2'] = float(b[16])    # 添加类别为2的召回率
SVM_result['recall_3'] = float(b[21])    # 添加类别为3的召回率
SVM_result['acc'] = float(b[25])         # 添加accuracy的结果
result_data['SVM'] = SVM_result

C是惩罚间距的

这段代码实现了使用支持向量机 (SVM) 进行分类任务,并通过网格搜索寻找最佳参数,最后评估模型性能的完整流程。下面是详细讲解:

1. 导入必要的库

python

运行

from sklearn.svm import SVC  # SVM分类器
from sklearn.model_selection import GridSearchCV  # 网格搜索工具
from sklearn import metrics  # 模型评估指标

2. 定义参数网格

python

运行

param_grid = {
    'C': [0.01, 0.1, 1, 2],  # 惩罚系数,控制正则化强度,值越大惩罚越重
    'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],  # 核函数类型
    'degree': [2, 3, 4, 5],  # 多项式核函数的阶数,仅对'poly'有效
    'gamma': ['scale', 'auto'] + [1],  # 核函数系数,影响模型复杂度
    'coef0': [0.1],  # 核函数中的独立项,对'poly'和'sigmoid'有效
}

这里定义了要搜索的参数组合,GridSearchCV 会尝试所有可能的组合来找到最佳参数。

3. 网格搜索寻找最佳参数

python

运行

svc = SVC()  # 创建SVC分类器实例
grid_search = GridSearchCV(svc, param_grid, cv=5)  # 5折交叉验证
grid_search.fit(train_data_x, train_data_y)  # 在训练集上执行网格搜索

这部分代码会自动尝试所有参数组合,通过 5 折交叉验证评估性能,找到最佳参数配置。

4. 使用最佳参数训练模型

python

运行

# 这里使用了搜索得到的最佳参数(示例值)
svm = SVC(C=1, coef0=0.1, degree=4, gamma=1, kernel='poly', probability=True, random_state=10)
svm.fit(train_data_x, train_data_y)  # 用训练数据拟合模型

probability=True表示允许模型输出概率预测,random_state=10保证结果可复现。

5. 模型评估

python

运行

test_predicted = svm.predict(test_data_x)  # 对测试集进行预测
# 打印详细的分类报告,包括precision、recall、f1-score等指标
print('SVM的test:\n', metrics.classification_report(test_data_y, test_predicted))

6. 提取关键指标

python

运行

a = metrics.classification_report(test_data_y, test_predicted, digits=6)  # 保留6位小数
b = a.split()  # 将报告按空格分割成列表

# 从分割后的列表中提取所需指标
SVM_result['recall_0'] = float(b[6])     # 类别0的召回率
SVM_result['recall_1'] = float(b[11])    # 类别1的召回率
SVM_result['recall_2'] = float(b[16])    # 类别2的召回率
SVM_result['recall_3'] = float(b[21])    # 类别3的召回率
SVM_result['acc'] = float(b[25])         # 整体准确率

result_data['SVM'] = SVM_result  # 将结果存入总结果字典

整体流程总结

  1. 定义要搜索的参数空间
  2. 通过网格搜索和交叉验证找到最佳参数
  3. 使用最佳参数训练 SVM 模型
  4. 在测试集上评估模型性能
  5. 提取关键评估指标并存储

四·AdaBoost算法实现代码

'''#####################AdaBoost算法实现代码###########################'''
# 随机森林和XGBoost使用的基学习器是决策树,而AdaBoost可以使用其他各种弱学习器。
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics

# 此处省略网格搜索参数相关代码(如param_grid定义、GridSearchCV创建等)

AdaBoost_reslut = {}
abf = AdaBoostClassifier(algorithm='SAMME',
                         base_estimator=DecisionTreeClassifier(max_depth=2),
                         n_estimators=200,
                         learning_rate=1.0,
                         random_state=0)  # 创建AdaBoost分类器

abf.fit(train_data_x, train_data_y)
train_predicted = abf.predict(train_data_x)  # 训练数据集的预测结果
print('AdaBoost的train:\n', metrics.classification_report(train_data_y, train_predicted))  # 打印训练数据集的

test_predicted = abf.predict(test_data_x)  # 测试数据集的预测结果
print('AdaBoost的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集的

a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()

AdaBoost_reslut['recall_0'] = float(b[6])     # 添加类别为0的召回率
AdaBoost_reslut['recall_1'] = float(b[11])    # 添加类别为1的召回率
AdaBoost_reslut['recall_2'] = float(b[16])    # 添加类别为2的召回率
AdaBoost_reslut['recall_3'] = float(b[21])    # 添加类别为3的召回率
AdaBoost_reslut['acc'] = float(b[25])         # 添加accuracy的结果
result_data['AdaBoost'] = AdaBoost_reslut

这段代码实现了 AdaBoost 分类算法的训练、预测和结果评估过程。让我为你详细讲解:

首先,代码导入了必要的库:

  • AdaBoostClassifier:这是 scikit-learn 库中实现 AdaBoost 算法的分类器
  • DecisionTreeClassifier:决策树分类器,这里作为 AdaBoost 的基学习器
  • metrics:scikit-learn 的评估指标模块,用于模型性能评估

核心部分解析:

  1. 创建 AdaBoost 分类器:

python

运行

abf = AdaBoostClassifier(algorithm='SAMME',
                         base_estimator=DecisionTreeClassifier(max_depth=2),
                         n_estimators=200,
                         learning_rate=1.0,
                         random_state=0)

  • algorithm='SAMME':指定使用 SAMME 算法(多类 AdaBoost 的一种实现)
  • base_estimator:指定基学习器为深度为 2 的决策树
  • n_estimators=200:指定集成 200 个基学习器
  • learning_rate=1.0:学习率参数,控制每个基学习器的权重
  • random_state=0:随机种子,保证结果可复现

  1. 模型训练与预测:

python

运行

abf.fit(train_data_x, train_data_y)  # 用训练数据拟合模型
train_predicted = abf.predict(train_data_x)  # 对训练数据进行预测
test_predicted = abf.predict(test_data_x)    # 对测试数据进行预测

  1. 模型评估:

python

运行

# 打印训练集的分类报告,包含精确率、召回率、F1分数等
print('AdaBoost的train:\n', metrics.classification_report(train_data_y, train_predicted))
# 打印测试集的分类报告
print('AdaBoost的test:\n', metrics.classification_report(test_data_y, test_predicted))

  1. 结果数据整理:

python

运行

# 提取测试集评估结果的详细数据
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()

# 将各类别的召回率和整体准确率存入字典
AdaBoost_reslut['recall_0'] = float(b[6])     # 类别0的召回率
AdaBoost_reslut['recall_1'] = float(b[11])    # 类别1的召回率
AdaBoost_reslut['recall_2'] = float(b[16])    # 类别2的召回率
AdaBoost_reslut['recall_3'] = float(b[21])    # 类别3的召回率
AdaBoost_reslut['acc'] = float(b[25])         # 整体准确率

# 将结果存入总的结果字典中
result_data['AdaBoost'] = AdaBoost_reslut

这段代码的特点是使用决策树作为 AdaBoost 的弱学习器,通过集成多个弱学习器构建一个强学习器,最后对模型在训练集和测试集上的表现进行了评估和结果整理。代码中假设是 4 分类问题(因为提取了 0-3 类的召回率)。

五·GNB朴素贝叶斯算法

'''#####################GNB算法实现代码###########################'''
from sklearn.naive_bayes import GaussianNB
from sklearn import metrics

GNB_result = {}
gnb = GaussianNB()  # 创建高斯朴素贝叶斯分类器
gnb.fit(train_data_x, train_data_y)
train_predicted = gnb.predict(train_data_x)  # 训练数据集的预测结果
print('GNB的train:\n', metrics.classification_report(train_data_y, train_predicted))  # 打印训练数据集的测试结果

test_predicted = gnb.predict(test_data_x)  # 测试数据集的预测结果
print('GNB的test:\n', metrics.classification_report(test_data_y, test_predicted))  # 打印测试数据集的测试结果
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()

GNB_result['recall_0'] = float(b[6])     # 添加类别为0的召回率
GNB_result['recall_1'] = float(b[11])    # 添加类别为1的召回率
GNB_result['recall_2'] = float(b[16])    # 添加类别为2的召回率
GNB_result['recall_3'] = float(b[21])    # 添加类别为3的召回率
GNB_result['acc'] = float(b[25])         # 添加accuracy的结果
result_data['GNB'] = GNB_result

这段代码实现了高斯朴素贝叶斯(Gaussian Naive Bayes, GNB)分类算法的训练、预测和评估过程,下面逐步解释其功能:

  1. 导入所需库

    • GaussianNB:从 scikit-learn 库中导入高斯朴素贝叶斯分类器
    • metrics:从 scikit-learn 库中导入评估指标模块,用于模型性能评估
  2. 初始化变量

    • 创建空字典GNB_result用于存储 GNB 模型的评估结果
    • 实例化高斯朴素贝叶斯分类器gnb = GaussianNB()
  3. 模型训练

    • 使用gnb.fit(train_data_x, train_data_y)对模型进行训练
    • train_data_x是训练数据集的特征
    • train_data_y是训练数据集的标签(类别)
  4. 训练集预测与评估

    • train_predicted = gnb.predict(train_data_x):使用训练好的模型对训练数据进行预测
    • metrics.classification_report():生成详细的分类评估报告,包括精确率、召回率、F1 分数等
    • 打印训练集的评估报告,用于查看模型在训练数据上的表现
  5. 测试集预测与评估

    • test_predicted = gnb.predict(test_data_x):使用模型对测试数据进行预测
    • 打印测试集的评估报告,用于评估模型的泛化能力
    • digits=6参数指定评估报告中数值的小数位数为 6 位
  6. 提取关键评估指标

    • 将评估报告按空格分割成列表b
    • 从列表中提取特定位置的数值作为评估指标:
      • 类别 0-3 的召回率(recall)
      • 整体准确率(accuracy)
    • 将这些指标存储到GNB_result字典中
  7. 保存结果

    • GNB_result字典存入result_data字典的 "GNB" 键下,便于后续与其他模型结果进行比较

六·Xgboost

import xgboost as xgb
from sklearn import metrics
# 假设 train_data_x、train_data_y、test_data_x、test_data_y 已提前定义好数据
# 若未定义,需补充数据加载、预处理等代码,比如用 pandas 读取并拆分特征和标签

# XGBoost 算法实现代码
XGBoost_result = {}
xgb_model = xgb.XGBClassifier(
    learning_rate=0.05,  # 学习率
    n_estimators=200,  # 决策树数量
    num_class=5,
    max_depth=7,  # 树的最大深度
    min_child_weight=1,  # 叶子节点中最小的样本权重和
    gamma=0,  # 节点分裂所需的最小损失函数下降值
    colsample_bytree=0.8,  # 每棵树随机采样的列数的占比
    objective='multi:softmax',  # 损失函数类型(多分类场景)
    seed=0  # 随机数种子
)  # 创建 XGBoost 分类器

# 训练模型
xgb_model.fit(train_data_x, train_data_y)

# 训练集预测与评估
train_predicted = xgb_model.predict(train_data_x)
print('XGBoost的train:\n', metrics.classification_report(train_data_y, train_predicted))

# 测试集预测与评估
test_predicted = xgb_model.predict(test_data_x)
print('XGBoost的test:\n', metrics.classification_report(test_data_y, test_predicted))

# 提取详细评估指标到 XGBoost_result
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
XGBoost_result['recall_0'] = float(b[6])  # 类别为0的召回率
XGBoost_result['recall_1'] = float(b[11])  # 类别为1的召回率
XGBoost_result['recall_2'] = float(b[16])  # 类别为2的召回率
XGBoost_result['recall_3'] = float(b[21])  # 类别为3的召回率
XGBoost_result['acc'] = float(b[25])  # 准确率

# 若有 result_data 字典用于汇总不同模型结果,可按如下方式整合
result_data = {}
result_data['XGBoost'] = XGBoost_result

这段代码实现了随机森林(Random Forest)分类算法,并对模型性能进行了评估和结果记录。下面是详细讲解:

1. 导入必要的库

python

运行

from sklearn.ensemble import RandomForestClassifier

  • 从 scikit-learn 库的集成学习模块中导入了RandomForestClassifier类,用于构建随机森林分类模型

2. 网格搜索参数(注释部分)

这部分代码定义了用于网格搜索的参数范围,但目前处于注释状态:

python

运行

# param_grid = {
#     'n_estimators': [50, 100, 200],  # 树的数量
#     'max_depth': [None, 10, 20, 30],  # 树的深度
#     'min_samples_split': [2, 5, 10],  # 节点分裂所需的最小样本数
#     'min_samples_leaf': [1, 2, 5],  # 叶子节点所需的最小样本数
#     'max_features': ['auto', 'sqrt', 'log2'],  # 最大特征数
#     'bootstrap': [True, False]  # 是否使用自举样本
# }

  • 网格搜索(Grid Search)用于自动寻找最佳参数组合
  • 如果需要调参,可以取消这些注释并运行相关代码

3. 模型初始化与训练

python

运行

RF_result = {}  # 用于存储模型评估结果的字典

# 初始化随机森林分类器,使用指定的参数
rf = RandomForestClassifier(
    bootstrap=False,          # 不使用自举样本
    max_depth=20,             # 树的最大深度为20
    max_features='log2',      # 每个节点考虑的最大特征数为log2(n_features)
    min_samples_leaf=1,       # 叶子节点的最小样本数为1
    min_samples_split=2,      # 节点分裂所需的最小样本数为2
    n_estimators=50,          # 森林中树的数量为50
    random_state=487          # 随机数种子,保证结果可复现
)

# 在训练数据上拟合模型
rf.fit(train_data_x, train_data_y)

4. 模型预测

python

运行

train_predicted = rf.predict(train_data_x)  # 对训练数据进行预测
test_predicted = rf.predict(test_data_x)    # 对测试数据进行预测

  • 分别在训练集和测试集上进行预测,用于评估模型的拟合效果和泛化能力

5. 模型评估

python

运行

# 打印训练集的分类报告
print('RF的train:\n', metrics.classification_report(train_data_y, train_predicted))
# 打印测试集的分类报告
print('RF的test:\n', metrics.classification_report(test_data_y, test_predicted))

  • metrics.classification_report会生成详细的分类评估指标,包括精确率(precision)、召回率(recall)、F1 分数等
  • 同时打印训练集和测试集的结果,可以对比模型是否过拟合

6. 结果提取与存储

python

运行

# 获取测试集的详细分类报告(保留6位小数)
rf_test_report = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = rf_test_report.split()  # 将报告字符串分割成列表,便于提取数值

# 提取各类别的召回率和整体准确率
RF_result['recall_0'] = float(b[6])     # 类别为0的召回率
RF_result['recall_1'] = float(b[11])    # 类别为1的召回率
RF_result['recall_2'] = float(b[16])    # 类别为2的召回率
RF_result['recall_3'] = float(b[21])    # 类别为3的召回率
RF_result['acc'] = float(b[25])         # 整体准确率

# 将随机森林的结果存入总的结果字典中
result_data['RF'] = RF_result

最后保存数据

import json  # 数据格式,网络传输。保存提取json类型的数据。
# 使用 'w' 模式打开文件,确保如果文件已存在则会被覆盖,
result = {}
result['mean fill'] = result_data
with open(r'temp_data/平均值填充result.json', 'w', encoding='utf-8') as file:
    # 使用 json.dump() 方法将字典转换为 JSON 格式并写入文件,JSON 一般来是字典
    json.dump(result, file, ensure_ascii=False, indent=4)

json方便网络传输,任何编程语言都可以读取,json是字符类型的文件,所以用open就可以

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐