diff --git a/function.py b/function.py index fbc31eb..aeaab93 100644 --- a/function.py +++ b/function.py @@ -1,11 +1,11 @@ # function.py import numpy as np -from sklearn.model_selection import train_test_split, GridSearchCV +from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score from sklearn.preprocessing import StandardScaler -from sklearn.metrics import accuracy_score, roc_auc_score -from sklearn.ensemble import RandomForestClassifier +from sklearn.metrics import accuracy_score, roc_auc_score, f1_score +from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier, VotingClassifier from sklearn.linear_model import LogisticRegression -from sklearn.ensemble import VotingClassifier +from sklearn.svm import SVC """ 实验说明: - 自行编写实现数据加载与预测病马死亡的对率回归算法。 @@ -30,18 +30,9 @@ id = "202210423221" name = "廖子豪" -# 这里写自己的代码实现 + + def load_data(filepath): - """ - 从文件中加载数据。 - - Args: - - filepath (str): 数据文件路径。 - - Returns: - - np.array: 特征数据。 - - np.array: 标签数据。 - """ file = open(filepath) fr = file.readlines() data_list = [] @@ -68,75 +59,38 @@ def load_data(filepath): return X_train, y_train def train_logreg(X, y, numIter=1000, learning_rate=0.06, batch_size=128, lambda_reg=0.01): - """ - 对率回归训练函数,加入L2正则化。 - - Args: - - X (numpy array): 特征数据。 - - y (numpy array): 标签数据。 - - numIter (int): 迭代次数。默认为1000。 - - learning_rate (float): 学习率。默认为0.06。 - - batch_size (int): 批量大小。默认为128。 - - lambda_reg (float): L2正则化参数。默认为0.01。 - - Returns: - - numpy array: 训练得到的权重。 - """ - m, n = X.shape # m: 样本数, n: 特征数 - weights = np.zeros(n) # 参数初始化 - + m, n = X.shape + weights = np.zeros(n) for j in range(numIter): - # 随机打乱样本顺序 dataIndex = np.random.permutation(m) for i in range(0, m, batch_size): end = min(i + batch_size, m) - # 批量梯度上升 batch_X = X[dataIndex[i:end]] batch_y = y[dataIndex[i:end]] - - # 计算梯度 z = np.dot(batch_X, weights) - h = 1 / (1 + np.exp(-z)) # 计算h - error = batch_y - h # 计算误差 - gradient = np.dot(batch_X.T, error) / len(batch_y) # 计算梯度 - # 添加L2正则化 + h = 1 / (1 + np.exp(-z)) + error = batch_y - h + gradient = np.dot(batch_X.T, error) / len(batch_y) reg_term = 2 * lambda_reg * weights gradient -= reg_term / len(batch_y) - weights += learning_rate * gradient # 更新权重 - + weights += learning_rate * gradient return weights def predict_logreg(inX, weights): - """ - 对率回归预测函数。 - - Args: - - inX (numpy array): 输入待分类的样本。 - - weights (numpy array): 训练得到的权重。 - - Returns: - - int: 预测的分类标签。 - """ - z = np.dot(inX, weights) # 线性组合 - prob = 1 / (1 + np.exp(-z)) # 计算概率 - return 1 if prob >= 0.5 else 0 # 返回分类标签 + z = np.dot(inX, weights) + prob = 1 / (1 + np.exp(-z)) + return 1 if prob >= 0.5 else 0 if __name__ == "__main__": - # 加载训练集 X_train, y_train = load_data("./data/horse-colic.data") - - # 加载测试集 X_test, y_test = load_data("./data/horse-colic.test") - # 特征缩放 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) - # 划分训练集和验证集 X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42) - # 训练对率回归模型,使用早停法 best_weights = None best_auc = 0 for iter in range(1, 1001): @@ -147,9 +101,8 @@ if __name__ == "__main__": best_auc = auc best_weights = weights if iter > 10 and auc == best_auc: - break # 早停 + break - # 使用最佳权重在测试集上评估模型 y_pred_test = [predict_logreg(x, best_weights) for x in X_test] accuracy_test = accuracy_score(y_test, y_pred_test) print(f"Test Accuracy: {accuracy_test}") @@ -173,4 +126,19 @@ if __name__ == "__main__": voting_clf = VotingClassifier(estimators=[('lr', log_clf), ('rf', rnd_clf)], voting='soft') voting_clf.fit(X_train, y_train) y_pred = voting_clf.predict(X_test) - print("Voting classifier accuracy:", accuracy_score(y_test, y_pred)) \ No newline at end of file + print("Voting classifier accuracy:", accuracy_score(y_test, y_pred)) + + # 梯度提升机模型 + gb_clf = GradientBoostingClassifier() + gb_clf.fit(X_train, y_train) + y_pred = gb_clf.predict(X_test) + print("Gradient Boosting classifier accuracy:", accuracy_score(y_test, y_pred)) + + # 使用K折交叉验证评估模型性能 + scores = cross_val_score(gb_clf, X_train, y_train, cv=5, scoring='accuracy') + print("Cross-validation scores:", scores) + print("Average cross-validation score:", np.mean(scores)) + + # 使用F1分数评估模型性能 + f1 = f1_score(y_test, y_pred) + print("F1 Score:", f1) \ No newline at end of file