diff --git a/function.py b/function.py index 7358289..91f3fb4 100644 --- a/function.py +++ b/function.py @@ -2,21 +2,27 @@ import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split -from imblearn.over_sampling import SMOTE # 导入SMOTE id = "202210423130" name = "董秋" def sigmoid(z): + """ + Sigmoid 激活函数。 + """ return 1 / (1 + np.exp(-z)) def train_logreg(X, y, learning_rate=0.01, iterations=1000, lambda_reg=0.01): + """ + 逻辑回归训练函数,随机初始化权重,并在每次迭代前打乱数据。 + """ m, n = X.shape - weights = np.random.randn(n) * 0.01 + weights = np.random.randn(n) * 0.01 # 随机初始化权重,取较小值 for i in range(iterations): + # 每次迭代打乱数据 indices = np.random.permutation(m) X = X[indices] y = y[indices] @@ -25,26 +31,32 @@ def train_logreg(X, y, learning_rate=0.01, iterations=1000, lambda_reg=0.01): predictions = sigmoid(z) gradient = np.dot(X.T, (predictions - y)) / m + # L2正则化 gradient += (lambda_reg / m) * weights + + # 更新权重 weights -= learning_rate * gradient + + # 动态调整学习率,逐渐减小 learning_rate *= 0.99 return weights def predict_logreg(inX, weights): + """ + 逻辑回归预测函数。 + Args: + - inX (numpy array): 输入待分类的样本。 + - weights (numpy array): 训练得到的权重。 + Returns: + - int: 预测的分类标签。 + """ z = np.dot(inX, weights) prediction_prob = sigmoid(z) return 1 if prediction_prob >= 0.5 else 0 -def handle_outliers(df, threshold=3): - z_scores = np.abs((df - df.mean()) / df.std()) - df[z_scores > threshold] = np.nan - df.fillna(df.mean(), inplace=True) - return df - - def load_data(filepath): data = [] labels = [] @@ -53,36 +65,40 @@ def load_data(filepath): with open(filepath, 'r') as f: for line in f: line_number += 1 # 每读取一行,行号加1 - # 检查当前行号,跳过特定行 + # 跳过第三行和第24到28行 if line_number == 3 or line_number in range(24, 29): continue values = line.strip().replace('?', '0').split() try: values = [float(v) for v in values] - if values[22] == 2 or values[22] == 3: + + # 合并特征23的取值 + if values[22] == 2 or values[22] == 3: # 特征23(索引22) labels.append(0) # 死亡 elif values[22] == 1: labels.append(1) # 生存 else: - continue - - values = [np.nan if v == 0 else v for v in values] - data.append(values[:2] + values[3:23]) + continue # 无效标签,丢弃 + + # 用0填充缺失值 + values = [np.nan if v == 0 else v for v in values] # 先标记为NaN + data.append(values[:2] + values[3:23]) # 保留特征1, 2 和特征4-23 except ValueError: continue data = np.array(data) labels = np.array(labels) + # 使用均值填充处理缺失值 df = pd.DataFrame(data) - df.fillna(df.mean(), inplace=True) - df = handle_outliers(df) + df.fillna(df.mean(), inplace=True) # 均值填充 return df.to_numpy(), labels def preprocess_data(X): + # 特征标准化 scaler = StandardScaler() return scaler.fit_transform(X) @@ -95,12 +111,8 @@ 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) - # 使用 SMOTE 进行数据集平衡 - smote = SMOTE(random_state=42) - X_train_balanced, y_train_balanced = smote.fit_resample(X_train, y_train) - # 训练逻辑回归模型 - weights = train_logreg(X_train_balanced, y_train_balanced, learning_rate=0.1, iterations=1000, lambda_reg=0.01) + weights = train_logreg(X_train, y_train, learning_rate=0.1, iterations=1000, lambda_reg=0.01) # 测试单个数据 y_pred = predict_logreg(X_test[11], weights)