diff --git a/function.py b/function.py index 31ff4c8..3cbbe90 100644 --- a/function.py +++ b/function.py @@ -26,97 +26,64 @@ name = "吴俊煯" # 这里写自己的代码实现 -def train_logreg(X, y, learning_rate=0.01, iterations=1000): - """ - 对率回归训练函数。 - - Args: - - X (numpy array): 特征数据。 - - y (numpy array): 标签数据。 - - other_params (str): 其它参数,可选设置。若需设置其它参数,必须设置其默认值,否则将**无法通过**自动评测,**成绩为零**。 - - Returns: - - numpy array: 训练得到的权重。 - """ +def train_logreg(X, y, learning_rate=0.01, iterations=1000, regularization=0.0): m, n = X.shape weights = np.zeros(n) bias = 0 - + m = len(X) # 重新赋值m,以确保它表示样本数量(在添加正则化时可能需要) + for _ in range(iterations): - for idx, x_i in enumerate(X): - linear_output = np.dot(x_i, weights) + bias - y_predicted = 1 / (1 + np.exp(-linear_output)) - - # 计算误差 - error = y[idx] - y_predicted - - # 更新权重和偏置 - weights += learning_rate * error * x_i - bias += learning_rate * error - - return weights + linear_output = np.dot(X, weights) + bias # 向量化操作 + y_predicted = 1 / (1 + np.exp(-linear_output)) + error = y - y_predicted + + # 更新权重和偏置,添加正则化项 + weights += learning_rate * (error * X.T - regularization * weights) / m + bias += learning_rate * np.sum(error) / m + + return weights, bias def predict_logreg(inX, weights): - """ - 对率回归预测函数。 - - Args: - - inX (numpy array): 输入待分类的样本。 - - weights (numpy array): 训练得到的权重。 - - Returns: - - int: 预测的分类标签。 - """ - linear_output = np.dot(inX, weights) - y_predicted = 1 / (1 + np.exp(-linear_output)) - - # 将输出转换为分类标签 - return 1 if y_predicted >= 0.5 else 0 + linear_output = np.dot(inX, weights) + bias + y_predicted = 1 if linear_output >= 0 else 0 # 简化判断条件,因为逻辑回归输出已经通过sigmoid函数处理 + return y_predicted # 这里也写自己的代码实现 def load_data(filepath): - """ - 从文件中加载数据,若不自行正确实现,则无法通过评测,**不记录成绩**。 - - Args: - - directory (str): 数据文件路径。 - - Returns: - - np.array: 特征数据。 - - np.array: 标签数据。 - """ - # 读取数据,假设数据是用空格分隔的,并且最后一列是标签 data = [] with open(filepath, 'r') as file: for line in file: - # 分割行,并去除任何可能的空白字符 parts = [part.strip() for part in line.split()] - # 将缺失值'?'替换为0(或者你可以选择其他适当的处理方式) features = [float(part) if part != '?' else 0 for part in parts[:-1]] - # 将标签从2转换为1(如果原始标签是1和2的话) - label = int(parts[-1]) - 1 # 假设原始标签是1和2,转换为0和1 + label = int(parts[-1]) - 1 # 假设标签是{1, 2},转换为{0, 1} data.append(features + [label]) - - # 将数据转换为numpy数组 data_array = np.array(data) - - # 分离特征和标签 - X = data_array[:, :-1] # 所有行,除了最后一列 - y = data_array[:, -1] # 所有行的最后一列 - + X = data_array[:, :-1] + y = data_array[:, -1] return X, y +def evaluate_model(X, y, weights, bias): + predictions = [predict_logreg(x, weights, bias) for x in X] + accuracy = np.mean(predictions == y) + return accuracy + if __name__ == "__main__": - # 以下代码可用于测试,可自行随意修改 - # 加载训练集 - X_train, y_train = load_data("./data/horse-colic.data") - - # 加载测试集 - X_test, y_test = load_data("./data/horse-colic.test") - - # 训练对率回归模型 - weights = train_logreg(X_train, y_train, learning_rate=0.01, iterations=1000) - - # 测试单个数据 - y_pred = predict_logreg(X_test[11], weights) + X_train, y_train = load_data("./data/horse-colic.data") + X_test, y_test = load_data("./data/horse-colic.test") + + # 数据标准化(可选,但通常有助于模型性能) + X_train_mean = np.mean(X_train, axis=0) + X_train_std = np.std(X_train, axis=0) + X_train = (X_train - X_train_mean) / X_train_std + X_test = (X_test - X_train_mean) / X_train_std # 使用训练集的标准差来标准化测试集 + + # 训练逻辑回归模型 + weights, bias = train_logreg(X_train, y_train, learning_rate=0.01, iterations=1000, regularization=0.1) + + # 评估模型性能 + accuracy = evaluate_model(X_test, y_test, weights, bias) + print(f"测试集准确率: {accuracy:.2f}") + + # 测试单个数据(可选) + y_pred = predict_logreg(X_test[11], weights, bias) print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}")