diff --git a/function.py b/function.py index 99cc363..583f71b 100644 --- a/function.py +++ b/function.py @@ -26,59 +26,101 @@ name = "周佳成" # 这里写自己的代码实现 -import pandas as pd -import numpy as np -from sklearn.model_selection import train_test_split -from sklearn.linear_model import LogisticRegression -from sklearn.metrics import accuracy_score, classification_report - -def load_data(file_path): - # 读取数据 - data = pd.read_csv(file_path, header=None, delim_whitespace=True, na_values='?') - # 处理缺失值(用0填充) - data.fillna(0, inplace=True) - - # 选择特征和目标变量 - # 去掉特征3和特征24~28 - features = data.iloc[:, :-5].values # 假设最后一列是目标变量,前面的都是特征 - target = data.iloc[:, -1].values - - # 将目标变量中的2和3合并为0 - target[target == 2] = 0 - target[target == 3] = 0 - - # 将目标变量转换为二进制分类(0或1) - target = (target == 1).astype(int) - - return features, target - -def train_logreg(X_train, y_train): - # 训练逻辑回归模型 - model = LogisticRegression(max_iter=1000) - model.fit(X_train, y_train) - return model - -def predict_logreg(model, X_test): - # 进行预测 - return model.predict(X_test) - -# 主程序 -data_path = './data/horse-colic.data' -features, target = load_data(data_path) - -# 划分训练集和测试集 -X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, random_state=42) - -# 训练模型 -model = train_logreg(X_train, y_train) - -# 预测并评估模型 -y_pred = predict_logreg(model, X_test) -accuracy = accuracy_score(y_test, y_pred) -report = classification_report(y_test, y_pred) - -print(f"Accuracy: {accuracy:.2f}") -print("Classification Report:") -print(report) +# Sigmoid函数 +def sigmoid(z): + return 1 / (1 + np.exp(-z)) +# 对率回归训练函数 +def train_logreg(X, y, learning_rate=0.01, iterations=1000): + """ + 对率回归训练函数。 + + Args: + - X (numpy array): 特征数据。 + - y (numpy array): 标签数据。 + - learning_rate (float): 学习率, 默认值为0.01。 + - iterations (int): 迭代次数, 默认值为1000。 + + Returns: + - numpy array: 训练得到的权重和偏置(合并为一个数组)。 + """ + n_samples, n_features = X.shape + weights = np.zeros(n_features + 1) # 增加一位用于偏置 + + # 增加一列1表示偏置 + X = np.c_[X, np.ones((n_samples, 1))] + + # 梯度下降法 + for i in range(iterations): + linear_model = np.dot(X, weights) + y_pred = sigmoid(linear_model) + + # 计算梯度 + dw = (1 / n_samples) * np.dot(X.T, (y_pred - y)) + + # 更新权重 + weights -= learning_rate * dw + + return weights + + +# 对率回归预测函数 +def predict_logreg(inX, weights): + """ + 对率回归预测函数。 + + Args: + - inX (numpy array): 输入待分类的样本。 + - weights (numpy array): 训练得到的权重和偏置。 + + Returns: + - int: 预测的分类标签 (0 或 1)。 + """ + # 增加偏置项 + inX = np.append(inX, 1) + linear_model = np.dot(inX, weights) + y_pred = sigmoid(linear_model) + return 1 if y_pred >= 0.5 else 0 + + +# 数据加载函数 +def load_data(filepath): + """ + 从文件中加载数据,处理缺失值,将 ? 替换为 NaN 并填充缺失值。 + + Args: + - filepath (str): 数据文件路径。 + + Returns: + - np.array: 特征数据。 + - np.array: 标签数据。 + """ + # 使用 genfromtxt 读取文件并将缺失值标记为 NaN + data = np.genfromtxt(filepath, delimiter=' ', dtype=float, missing_values='?', filling_values=np.nan) + + # 对每一列的 NaN 值用列的平均值进行填充 + nan_columns = np.isnan(data) + mean_values = np.nanmean(data, axis=0) + data[nan_columns] = np.take(mean_values, np.where(nan_columns)[1]) + + # 分离特征和标签 + X = data[:, :-1] # 所有列(除了最后一列)是特征 + y = data[:, -1] # 最后一列是标签 + return X, y + + +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) + print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}") +