diff --git a/function.py b/function.py index a89a693..cb5b262 100644 --- a/function.py +++ b/function.py @@ -1,82 +1,46 @@ -import numpy as np + import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler -from sklearn.model_selection import train_test_split, GridSearchCV -from sklearn.linear_model import LogisticRegression +from sklearn.model_selection import train_test_split id = "202210423130" name = "董秋" -def load_data(filepath): - data = [] - labels = [] - - with open(filepath, 'r') as f: - for line in f: - values = line.strip().replace('?', '0').split() - try: - values = [float(v) for v in values] - - # 合并特征23的取值 - if values[22] == 2 or values[22] == 3: # 特征23(索引22) - labels.append(0) # 死亡 - elif values[22] == 1: - labels.append(1) # 生存 - else: - continue # 无效标签,丢弃 - - # 用0填充缺失值 - values = [0 if np.isnan(v) else v for v in values] - - # 去掉特征3(索引2)和特征24~28(索引23-27) - data.append(values[:2] + values[3:23]) # 保留特征1, 2 和特征4-23 - except ValueError: - continue - - return np.array(data), np.array(labels) - - -def preprocess_data(X): - # 特征标准化 - scaler = StandardScaler() - return scaler.fit_transform(X) - - -def train_logreg(X_train, y_train): +def train_logreg(X, y, learning_rate=0.01, iterations=1000, lambda_reg=0.01): """ - 逻辑回归训练函数,使用网格搜索优化超参数。 + 对率回归训练函数。 Args: - - X_train (numpy array): 特征数据。 - - y_train (numpy array): 标签数据。 + - X (numpy array): 特征数据。 + - y (numpy array): 标签数据。 Returns: - - LogisticRegression: 训练得到的最佳模型。 + - numpy array: 训练得到的权重。 """ - # 定义要调优的超参数范围 - param_grid = { - 'C': [0.001, 0.01, 0.1, 1, 10, 100], # 正则化参数 - 'solver': ['liblinear', 'lbfgs'], # 求解器 - 'max_iter': [100, 500, 1000] # 最大迭代次数 - } + m, n = X.shape + weights = np.zeros(n) - # 创建逻辑回归模型 - log_reg = LogisticRegression() + for i in range(iterations): + z = np.dot(X, weights) + predictions = 1 / (1 + np.exp(-z)) + gradient = np.dot(X.T, (predictions - y)) / m + + # L2正则化 + gradient += (lambda_reg / m) * weights - # 创建网格搜索对象 - grid_search = GridSearchCV(estimator=log_reg, param_grid=param_grid, cv=5, scoring='accuracy') + weights -= learning_rate * gradient - # 进行网格搜索 - grid_search.fit(X_train, y_train) + # 动态调整学习率,逐渐减小 + learning_rate *= 0.99 # 每次迭代将学习率乘以0.99 - return grid_search.best_estimator_ + return weights def predict_logreg(inX, weights): """ - 逻辑回归预测函数。 + 对率回归预测函数。 Args: - inX (numpy array): 输入待分类的样本。 @@ -90,6 +54,41 @@ def predict_logreg(inX, weights): return 1 if prediction_prob >= 0.5 else 0 +def load_data(filepath): + data = [] + labels = [] + + with open(filepath, 'r') as f: + for line in f: + values = line.strip().replace('?', '0').split() + try: + values = [float(v) for v in values] + + # 合并特征23的取值 + if values[22] == 2 or values[22] == 3: # 特征23(索引22) + labels.append(0) # 死亡 + elif values[22] == 1: + labels.append(1) # 生存 + else: + continue # 无效标签,丢弃 + + # 用0填充缺失值 + values = [0 if np.isnan(v) else v for v in values] + + # 去掉特征3(索引2)和特征24~28(索引23-27) + data.append(values[:2] + values[3:23]) # 保留特征1, 2 和特征4-23 + except ValueError: + continue + + return np.array(data), np.array(labels) + + +def preprocess_data(X): + # 特征标准化 + scaler = StandardScaler() + return scaler.fit_transform(X) + + if __name__ == "__main__": # 加载数据集 X, y = load_data("./data/horse-colic.data") @@ -98,9 +97,9 @@ if __name__ == "__main__": # 使用 train_test_split 打乱并随机抽取数据 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - # 训练逻辑回归模型 - best_model = train_logreg(X_train, y_train) + # 训练对率回归模型 + weights = train_logreg(X_train, y_train, learning_rate=0.1, iterations=1000, lambda_reg=0.01) # 测试单个数据 - y_pred = best_model.predict(X_test[11].reshape(1, -1)) # 进行预测时需要调整输入形状 - print(f"预测结果: {y_pred[0]}, 实际结果: {y_test[11]}") + y_pred = predict_logreg(X_test[11], weights) + print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}") \ No newline at end of file