上机实验二:逻辑回归算法实现与测试

1、实验目的
深入理解对数几率回归(即逻辑回归的)的算法原理,能够使用 Python 语言实现对数
几率回归的训练与测试,并且使用五折交叉验证算法进行模型训练与评估。
2、实验内容推荐参考书:[1] 范淼, 李超. Python 机器学习及实践, 清华大学出版社.
[2] Peter Harrington. 机器学习实战, 人民邮电出版社。
(1)从 scikit-learn 库中加载 iris 数据集,使用留出法留出 1/3 的样本作为测试集(注
意同分布取样);
(2)使用训练集训练对数几率回归(逻辑回归)分类算法;
(3)使用五折交叉验证对模型性能(准确度、精度、召回率和 F1 值)进行评估和选
择;
(4)使用测试集,测试模型的性能,对测试结果进行分析,完成实验报告中实验二的
部分。
3、操作要点
(1)可以选择自行编写源代码完成对数几率回归算法,或者调用 scikit-learn 库中的函
数;
(2)如果调用 scikit-learn 库中的函数,需要说明函数各个参数的意义、取值、默认值
等,即自行编写代码只需要粘贴完整的源代码即可,调用函数包括粘贴源代码和函数参数说
明两部分;
(3)一周内在超星作业提交源代码,打包命名;学号姓名-任务 2;
(4)按要求撰写实验报告,实验报告在所有上机实验结束后提交。
4、主要仪器设备
微机及 Python 软件。
 
python代码
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import numpy as np
from sklearn.exceptions import ConvergenceWarning
import warnings


# 自定义逻辑回归类
class CustomLogisticRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000):
        self.learning_rate = learning_rate
        self.n_iterations = n_iterations
        self.weights = None
        self.bias = None

    def fit(self, X, y):
        n_samples, n_features = X.shape
        self.weights = np.zeros(n_features)
        self.bias = 0

        for _ in range(self.n_iterations):
            linear_model = np.dot(X, self.weights) + self.bias
            y_predicted = self.sigmoid(linear_model)

            dw = (1 / n_samples) * np.dot(X.T, (y_predicted - y))
            db = (1 / n_samples) * np.sum(y_predicted - y)

            self.weights -= self.learning_rate * dw
            self.bias -= self.learning_rate * db

    def predict(self, X):
        linear_model = np.dot(X, self.weights) + self.bias
        y_predicted = self.sigmoid(linear_model)
        y_predicted_class = [1 if i > 0.5 else 0 for i in y_predicted]
        return y_predicted_class

    def sigmoid(self, z):
        return 1 / (1 + np.exp(-z))

    def score(self, X, y):
        y_pred = self.predict(X)
        return accuracy_score(y, y_pred)

    def get_params(self, deep=True):
        return {'learning_rate': self.learning_rate, 'n_iterations': self.n_iterations}

    def set_params(self, **parameters):
        for parameter, value in parameters.items():
            setattr(self, parameter, value)
        return self


# 加载 iris 数据集
iris = load_iris()
X = iris.data
y = iris.target

# 使用留出法留出 1/3 的样本作为测试集(同分布取样)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/3, random_state=42)

# 创建自定义逻辑回归模型并训练
custom_lr = CustomLogisticRegression()
custom_lr.fit(X_train, y_train)

# 创建 scikit-learn 逻辑回归模型并训练,处理 ConvergenceWarning 警告
with warnings.catch_warnings():
    warnings.simplefilter('ignore', category=FutureWarning)  # 忽略 FutureWarning,可能是因为 scikit-learn 版本问题导致的警告
    warnings.filterwarnings('error', category=ConvergenceWarning)  # 将 ConvergenceWarning 转换为错误,以便进行处理
    try:
        sklearn_lr = LogisticRegression(max_iter=10000)  # 增加最大迭代次数
        sklearn_lr.fit(X_train, y_train)
    except ConvergenceWarning as e:
        print(f"Scikit-learn 逻辑回归模型未能收敛: {e}")

# 定义评估函数
def evaluate_model(model, X, y):
    scores = cross_val_score(model, X, y, cv=5)
    accuracy = np.mean(scores)
    print(f"五折交叉验证准确度:{accuracy}")

    y_pred = model.predict(X)
    precision = precision_score(y, y_pred, average='macro', zero_division=0)  # 处理 UndefinedMetricWarning 警告
    print(f"精度:{precision}")

    recall = recall_score(y, y_pred, average='macro')
    print(f"召回率:{recall}")

    f1 = f1_score(y, y_pred, average='macro')
    print(f"F1 值:{f1}\n")


# 评估自定义逻辑回归模型
print("自定义逻辑回归模型评估:")
evaluate_model(custom_lr, X_train, y_train)

# 评估 scikit-learn 逻辑回归模型
print("scikit-learn 逻辑回归模型评估:")
if'sklearn_lr' in locals():  # 确保模型已成功训练
    evaluate_model(sklearn_lr, X_train, y_train)

# 使用测试集测试自定义逻辑回归模型
y_pred_test_custom = custom_lr.predict(X_test)
accuracy_custom = accuracy_score(y_test, y_pred_test_custom)
print(f"自定义逻辑回归模型在测试集上的准确度:{accuracy_custom}")

precision_custom = precision_score(y_test, y_pred_test_custom, average='macro', zero_division=0)
print(f"精度:{precision_custom}")

recall_custom = recall_score(y_test, y_pred_test_custom, average='macro')
print(f"召回率:{recall_custom}")

f1_custom = f1_score(y_test, y_pred_test_custom, average='macro')
print(f"F1 值:{f1_custom}\n")

# 使用测试集测试 scikit-learn 逻辑回归模型
if'sklearn_lr' in locals():  # 确保模型已成功训练
    y_pred_test_sklearn = sklearn_lr.predict(X_test)
    accuracy_sklearn = accuracy_score(y_test, y_pred_test_sklearn)
    print(f"scikit-learn 逻辑回归模型在测试集上的准确度:{accuracy_sklearn}")

    precision_sklearn = precision_score(y_test, y_pred_test_sklearn, average='macro', zero_division=0)
    print(f"精度:{precision_sklearn}")

    recall_sklearn = recall_score(y_test, y_pred_test_sklearn, average='macro')
    print(f"召回率:{recall_sklearn}")

    f1_sklearn = f1_score(y_test, y_pred_test_sklearn, average='macro')
    print(f"F1 值:{f1_sklearn}")

    # load_iris(来自 sklearn.datasets)
    # 无参数,用于加载鸢尾花数据集(Iris dataset),返回一个包含数据和目标值的对象。该数据集是一个经典的用于分类任务的数据集,包含了 4 个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和 3 个类别(山鸢尾、变色鸢尾、维吉尼亚鸢尾)。
    # train_test_split(来自 sklearn.model_selection)
    # X:特征数据,必填参数,这里是鸢尾花数据集的特征部分(iris.data)。
    # y:目标数据,必填参数,对应鸢尾花数据集的类别标签(iris.target)。
    # test_size:测试集所占比例,默认为 0.25,表示将数据集划分为 75% 的训练集和 25% 的测试集。在代码中设置为1/3,即约 33.3% 的数据作为测试集。
    # random_state:随机数生成器的种子,用于确保每次划分数据集的结果相同,便于实验的重复性。设置为 42,这是一个常用的随机种子值。
    # cross_val_score(来自 sklearn.model_selection)
    # model:要评估的模型对象,如自定义的CustomLogisticRegression模型或scikit-learn的LogisticRegression模型。
    # X:用于交叉验证的特征数据,与训练集特征数据相同(X_train)。
    # y:用于交叉验证的目标数据,与训练集目标数据相同(y_train)。
    # cv:交叉验证的折数,设置为 5,表示进行五折交叉验证。即将数据集划分为 5 份,每次用其中 4 份作为训练集,1 份作为测试集,重复 5 次,最后计算平均评估指标。
    # LogisticRegression(来自 sklearn.linear_model)
    # max_iter:最大迭代次数,用于控制优化算法的迭代过程。默认值为 100,在代码中为了处理可能出现的不收敛问题,将其设置为 10000,以给予模型更多的迭代机会来找到最优解。
    # accuracy_score(来自 sklearn.metrics)
    # y_true:真实的目标值,如测试集的真实类别标签(y_test)。
    # y_pred:预测的目标值,由模型预测得到(如custom_lr.predict(X_test)或sklearn_lr.predict(X_test)),用于计算模型预测的准确度,即预测正确的样本数占总样本数的比例。
    # precision_score(来自 sklearn.metrics)
    # y_true:真实的目标值。
    # y_pred:预测的目标值。
    # average:计算精度的平均方式,设置为'macro'表示对每个类别计算精度后取平均值,不考虑类别不平衡问题。若设置为'micro',则将所有类别合并后计算总体精度;若设置为'weighted',则根据每个类别的样本数量加权平均。
    # zero_division:处理当分母为 0 时的情况,设置为 0,表示当某个类别没有预测样本时,精度为 0。默认情况下,会发出警告(UndefinedMetricWarning)。
    # recall_score(来自 sklearn.metrics)
    # y_true:真实的目标值。
    # y_pred:预测的目标值。
    # average:计算召回率的平均方式,同样设置为'macro',含义与precision_score中的'macro'类似,对每个类别计算召回率后取平均值。
    # f1_score(来自 sklearn.metrics)
    # y_true:真实的目标值。
    # y_pred:预测的目标值。
    # average:计算 F1 值的平均方式,设置为'macro',综合考虑了精度和召回率,用于评估模型在多类别情况下的整体性能。F1 值是精度和召回率的调和平均值,能够更全面地反映模型的性能。

 

posted @ 2024-11-13 10:41  *太¥^白%  阅读(87)  评论(0)    收藏  举报