diff --git a/function.py b/function.py index edcfb86..ad2882c 100644 --- a/function.py +++ b/function.py @@ -1,76 +1,68 @@ -import numpy as np id = "202210423201" name = "陈瑞琪祥" +import numpy as np +from sklearn.svm import SVC +from sklearn.model_selection import train_test_split +from sklearn.metrics import classification_report, accuracy_score +from sklearn.preprocessing import StandardScaler + +# 数据加载函数 def load_data(filepath): - try: - # 使用numpy的genfromtxt函数加载数据,并处理缺失值 - data = np.genfromtxt(filepath, delimiter=',', dtype=float, filling_values=np.nan) - except Exception as e: - print(f"数据加载错误,可能是由于数据格式不正确:{e}") - return None - - # 检查数据是否为二维数组 - if data is None or data.ndim != 2: - print("数据不是二维数组,无法继续处理。") - return None - - # 确保所有行都有相同数量的列 - if data.shape[1] < 2: - print("数据列数不正确,无法继续处理。") - return None - - # 分离特征和标签 - X = data[:, :-1] - y = data[:, -1].astype(int) - return X, y - -def train_svm(X, y, learning_rate=0.01, iterations=1000, regularization=1.0): - n_samples, n_features = X.shape - weights = np.zeros(n_features) - bias = 0 - - for _ in range(iterations): - for idx, x_i in enumerate(X): - condition = y[idx] * (np.dot(x_i, weights) - bias) >= 1 - if condition: - weights -= learning_rate * (2 * regularization * weights) + data = [] + labels = [] + + with open(filepath, 'r') as file: + for line in file: + fields = line.strip().split() + fields = [0 if f == '?' else float(f) for f in fields] + + label = int(fields[-6]) + features = np.array(fields[:-6] + fields[-5:], dtype=float) + + if label in [1, 2, 3]: + label = {1: 0, 2: 1, 3: 2}[label] + data.append(features) + labels.append(label) else: - weights -= learning_rate * (2 * regularization * weights - np.dot(x_i, y[idx])) - bias -= learning_rate * y[idx] + print(f"无效标签,跳过此样本:{label}") + + return np.array(data), np.array(labels) - return weights, bias +def train_svm(X, y): + """ + 支持向量机训练函数。 + """ + scaler = StandardScaler() + X_scaled = scaler.fit_transform(X) + + model = SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42) + model.fit(X_scaled, y) + return model, scaler -def predict_svm(inX, weights, bias): - return np.sign(np.dot(inX, weights) - bias) - -def evaluate_svm(X_test, y_test, weights, bias): - if X_test is None or y_test is None: - print("测试数据加载失败,无法评估。") - return 0 - - correct = 0 - for i in range(len(X_test)): - if predict_svm(X_test[i], weights, bias) == y_test[i]: - correct += 1 - accuracy = correct / len(X_test) - return accuracy +def predict_svm(model, scaler, X): + X_scaled = scaler.transform(X) + return model.predict(X_scaled) if __name__ == "__main__": - # 加载训练集 - X_train, y_train = load_data("./data/horse-colic.data") - if X_train is None: - print("训练数据加载失败。") - else: - # 加载测试集 - X_test, y_test = load_data("./data/horse-colic.test") - if X_test is None: - print("测试数据加载失败。") - else: - # 训练支持向量机模型 - weights, bias = train_svm(X_train, y_train, learning_rate=0.01, iterations=1000) - - # 评估模型 - accuracy = evaluate_svm(X_test, y_test, weights, bias) - print(f"模型准确率: {accuracy}") \ No newline at end of file + # 加载数据 + X, y = load_data("./data/horse-colic.data") + + # 分割数据集 + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + + # 训练SVM模型 + svm_model, scaler = train_svm(X_train, y_train) + + # 预测测试集 + y_pred = predict_svm(svm_model, scaler, X_test) + + # 评估模型 + accuracy = accuracy_score(y_test, y_pred) + print(f"测试集准确率: {accuracy * 100:.2f}%") + + # 测试单个数据 + test_sample = X_test[11] # 选择第12个样本(从0开始计数) + y_pred_single = predict_svm(svm_model, scaler, test_sample.reshape(1, -1)) + print(f"\n单个样本预测结果: {y_pred_single[0]}, 实际结果: {y_test[11]}") \ No newline at end of file