generated from LufsX/Challenge-SVM
This commit is contained in:
+23
-15
@@ -34,33 +34,41 @@ def load_data(filepath):
|
||||
with open(filepath, 'r') as file:
|
||||
for line in file:
|
||||
fields = line.strip().split()
|
||||
if '?' in fields: # 处理缺失值
|
||||
fields = [0 if f == '?' else float(f) for f in fields]
|
||||
fields = [0 if f == '?' else float(f) for f in fields] # 缺失值填充
|
||||
features = np.array(fields[:-1], dtype=float)
|
||||
label = int(fields[-1]) # 确保标签未合并
|
||||
label = int(fields[-1])
|
||||
data.append(features)
|
||||
labels.append(label)
|
||||
return np.array(data), np.array(labels)
|
||||
labels = np.array(labels)
|
||||
|
||||
def train_svm(X, y, learning_rate=0.01, iterations=1000):
|
||||
# 检查标签是否为三类
|
||||
unique_labels = np.unique(labels)
|
||||
if len(unique_labels) != 3:
|
||||
raise ValueError("标签数量不为3,请确保标签未合并!")
|
||||
|
||||
return np.array(data), labels
|
||||
|
||||
def train_svm(X, y, learning_rate=0.01, iterations=1000, regularization_strength=0.01):
|
||||
n_samples, n_features = X.shape
|
||||
n_classes = len(np.unique(y))
|
||||
weights = np.zeros((n_classes, n_features))
|
||||
|
||||
# 将标签转化为多类别(one-vs-rest)形式
|
||||
y_one_vs_rest = np.array([[1 if y[i] == c else -1 for c in range(n_classes)] for i in range(n_samples)])
|
||||
|
||||
for _ in range(iterations):
|
||||
for idx, x_i in enumerate(X):
|
||||
for c in range(n_classes):
|
||||
y_i = 1 if y[idx] == c else -1
|
||||
if y_i * (np.dot(weights[c], x_i)) < 1:
|
||||
weights[c] += learning_rate * (y_i * x_i - (2 * 1/iterations) * weights[c])
|
||||
else:
|
||||
weights[c] -= learning_rate * (2 * 1/iterations) * weights[c]
|
||||
# 计算预测值
|
||||
margins = y_one_vs_rest * (X @ weights.T)
|
||||
mask = margins < 1
|
||||
grad = -np.einsum('ij,ik->kj', y_one_vs_rest * mask, X) / n_samples
|
||||
weights -= learning_rate * (grad + regularization_strength * weights)
|
||||
|
||||
return weights
|
||||
|
||||
def predict_svm(inX, weights):
|
||||
scores = [np.dot(w, inX) for w in weights]
|
||||
return np.argmax(scores)
|
||||
def predict_svm(X, weights):
|
||||
scores = X @ weights.T
|
||||
return np.argmax(scores, axis=1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user