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:
|
with open(filepath, 'r') as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
fields = line.strip().split()
|
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)
|
features = np.array(fields[:-1], dtype=float)
|
||||||
label = int(fields[-1]) # 确保标签未合并
|
label = int(fields[-1])
|
||||||
data.append(features)
|
data.append(features)
|
||||||
labels.append(label)
|
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_samples, n_features = X.shape
|
||||||
n_classes = len(np.unique(y))
|
n_classes = len(np.unique(y))
|
||||||
weights = np.zeros((n_classes, n_features))
|
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 _ in range(iterations):
|
||||||
for idx, x_i in enumerate(X):
|
# 计算预测值
|
||||||
for c in range(n_classes):
|
margins = y_one_vs_rest * (X @ weights.T)
|
||||||
y_i = 1 if y[idx] == c else -1
|
mask = margins < 1
|
||||||
if y_i * (np.dot(weights[c], x_i)) < 1:
|
grad = -np.einsum('ij,ik->kj', y_one_vs_rest * mask, X) / n_samples
|
||||||
weights[c] += learning_rate * (y_i * x_i - (2 * 1/iterations) * weights[c])
|
weights -= learning_rate * (grad + regularization_strength * weights)
|
||||||
else:
|
|
||||||
weights[c] -= learning_rate * (2 * 1/iterations) * weights[c]
|
|
||||||
|
|
||||||
return weights
|
return weights
|
||||||
|
|
||||||
def predict_svm(inX, weights):
|
def predict_svm(X, weights):
|
||||||
scores = [np.dot(w, inX) for w in weights]
|
scores = X @ weights.T
|
||||||
return np.argmax(scores)
|
return np.argmax(scores, axis=1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user