机器学习实验二——逻辑回归 实验报告

组员:张继伟 谢正宇 樊佳婷 孙晶铭 刘怡聪

题目

假设你是某大学招生主管,你想根据两次考试的结果决定每个申请者的录取机会。现有以往申请者的历 史数据,可以此作为训练集建立逻辑回归模型,并用其预测某学生能否被大学录取。请按要求完成实 验。建议使用 python 编程实现。 数据集
文件 ex2data1.txt 为该实验的数据集,第一列、第二列分别表示申请者两次考试的成绩,第三列表示录 取结果(1 表示录取,0 表示不录取)。

步骤与要求

1)请导入数据并进行数据可视化,观察数据分布特征。(建议用 python 的matplotlib) 2)将逻辑回归参数初始化为 0,然后计算代价函数(cost function)并求出初始值。 3)选择一种优化方法求解逻辑回归参数。 4)某学生两次考试成绩分别为 42、85,预测其被录取的概率。 5)画出分类边界。(选做)

实验过程与结果分析

# 导入Matploylib库
from matplotlib import pyplot as plt
from numpy import *
import matplotlib.ticker as ticker
import numpy as np
import scipy.optimize as opt

# 定义h(x)预测函数:theat为转置后的矩阵
def hypothesis(theta, x):
    return np.dot(x, theta)

# 定义sigmoid函数
def sigmoid(theta, x):
    z = hypothesis(theta, x)
    return 1.0 / (1 + exp(-z))

# 定义代价函数
def cost(theta, X, y):
    return np.mean(-y * np.log(sigmoid(theta, X)) - (1 - y) * np.log(1 - sigmoid(theta, X)))

# 梯度下降函数
def gradient(theta, X, y):
    return (1 / len(X)) * X.T @ (sigmoid(theta, X) - y)

'''
绘图:绘制训练数据的散点图和h(x)预测函数对应的直线
'''
def draw():
    # 定义x y数据 x1 y1:未通过 x2 y2:通过
    x1 = []
    y1 = []
    x2 = []
    y2 = []

    # 导入训练数据
    train_data = open("ex2data1.txt")
    lines = train_data.readlines()
    for line in lines:
        scores = line.split(",")
        # 去除标记后面的换行符
        isQualified = scores[2].replace("\n", "")
        # 根据标记将两次成绩放到对应的数组
        if isQualified == "0":
            x1.append(float(scores[0]))
            y1.append(float(scores[1]))
        else:
            x2.append(float(scores[0]))
            y2.append(float(scores[1]))

    # 设置标题和横纵坐标的标注
    plt.xlabel("Exam 1 score")
    plt.ylabel("Exam 2 score")

    # 设置通过测试和不通过测试数据的样式。其中x y为两次的成绩,marker:记号形状 color:颜色 s:点的大小 label:标注
    plt.scatter(x1, y1, marker='o', color='red', s=15, label='Not admitted')
    plt.scatter(x2, y2, marker='x', color='green', s=15, label='Admitted')

    # 标注[即上两行中的label]的显示位置:右上角
    plt.legend(loc='upper right')

    # 设置坐标轴上刻度的精度为一位小数。因训练数据中的分数的小数点太多,若不限制坐标轴上刻度显示的精度,影响最终散点图的美观度
    plt.gca().xaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))
    plt.gca().yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))

    # 设置训练得到的模型对应的直线,即h(x)对应的直线
    # 设置x的取值范围:[30, 110]步长为10
    x = np.arange(30, 110, 10)
    y = (-result.x[0] - result.x[1] * x) / result.x[2]
    predict=(-result.x[0]-result.x[1]*42)/result.x[2]
    print("当第一次考试成绩为42时,最小可被接收的第二次成绩为",predict)
    if predict-85<0:
        print("这个学生可以被接收!")
    else:
        print("这个学生不能被接收!")
    plt.plot(x, y)

    # 显示
    plt.show()


'''
数据预先处理:将两次成绩与是否通过测试的标记分别生成矩阵,并将标记的矩阵转置。
'''
def init_data():
    # 两次成绩对应的特征矩阵
    data = []
    # 标记对应的矩阵
    label = []

    # 读取文件
    train_data = open("ex2data1.txt")
    lines = train_data.readlines()
    for line in lines:
        scores = line.split(",")
        # 去除标记后面的换行符
        isQualified = scores[2].replace("\n", "")
        # 添加特征x0,设置为1
        data.append([1, float(scores[0]), float(scores[1])])
        label.append(int(isQualified))

    # 标记矩阵转置,返回特征矩阵和标记矩阵
    return np.array(data), np.array(label).transpose()


'''
主函数
'''
if __name__ == '__main__':
    # 初始化数据
    X, y = init_data()
    # 初始化theta:三行一列的0矩阵
    theta = np.zeros((3, 1))
    # 使用minimize函数求解
    result = opt.minimize(fun=cost, x0=theta, args=(X, y), method='Newton-CG', jac=gradient) #method求极值的方法 Newton-CG算法最小化一个或多个变量的标量函数。
    #minimize函数参数详解:https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize
    #print(result)
    # 绘图
    draw()

代码细节自己看
也可以下载实验报告
工程链接工程链接