2026-01-07-机器学习相关算法

1738 个字
9 分钟
2026-01-07-机器学习相关算法

评估方法(留出法)#

import random
import numpy as np
def train_test_split(X,test_size=0.2,random_state=5):
random.seed(random_state)
n_samples = len(X)
indices = np.arange(n_samples)
train_indexs = list(set(random.sample(indices.tolist(),int(n_samples*(1-test_size)))))
test_indexs = [k for k in indices if k not in train_indexs]
return X[train_indexs],X[test_indexs]
test_size = 0.2
X = np.array([1,2,3,4,5,6,7,8,9,10])
train_X,test_X = train_test_split(X,test_size=test_size)
print(train_X,test_X)
print("debug_begin");
print(len(test_X) == int(len(X)*test_size))
print("debug_end");

评估方法(交叉验证法)#

import numpy as np
import random
def KFold(X,n_splits,is_shuffle=True,random_state=0):
random.seed(random_state)
n_samples = len(X)
indices = np.arange(n_samples)
train_index = []
test_index = []
result = []
fold_sizes = np.full(n_splits,n_samples//n_splits,dtype=np.int)
fold_sizes[:n_samples%n_splits] += 1
current = 0
for fold_size in fold_sizes:
start, stop = current, current+fold_size
test_index = indices[start:stop]
train_index = list(set(indices)-set(indices[start:stop]))
current = stop
result.append([X[train_index],X[test_index]])
return result
X = np.array([int(i) for i in input().strip().split()])
n_splits = int(input())
result = KFold(X,n_splits)
for S,T in result:
print(S,T)
print("debug_begin");
res = []
for _,T in result:
res += list(T)
if set(res)==set(list(X)) and len(X)==len(res):
print(True)
else:
print(False)
print("debug_end");

优化算法-梯度下降法 1#

import math
print("debug_begin");
def func_1d_test1(x):
return x**2+1
def grad_1d_test1(x):
return x*2
def func_1d_test2(x):
return x**2 - 4*x +14
def grad_1d_test2(x):
return x*2-4
print("debug_end");
def gradient_descent_1d(grad, cur_x=0.1, learning_rate=0.01, precision=0.0001, max_iters=10000):
for i in range(max_iters):
grad_cur = grad(cur_x)
if abs(grad_cur) < precision:
break # 当梯度趋近为 0 时,视为收敛
cur_x = cur_x - grad_cur * learning_rate
return cur_x
print("debug_begin");
def test():
print("%.7f" %gradient_descent_1d(grad_1d_test1, cur_x=10, learning_rate=0.2, precision=0.0001, max_iters=10000))
print("%.7f" %gradient_descent_1d(grad_1d_test2, cur_x=10, learning_rate=0.2, precision=0.0001, max_iters=10000))
print("debug_end");
test()

优化算法-梯度下降法 2#

import math
import numpy as np
print("debug_begin");
import numpy as np
def func_2d_test1(x):
return - math.exp(-(x[0] ** 2 + x[1] ** 2))
def grad_2d_test1(x):
deriv0 = 2 * x[0] * math.exp(-(x[0] ** 2 + x[1] ** 2))
deriv1 = 2 * x[1] * math.exp(-(x[0] ** 2 + x[1] ** 2))
return np.array([deriv0, deriv1])
def func_2d_test2(x):
return x[0]**2 + x[1]**2 +2*x[0]+1
def grad_2d_test2(x):
deriv0 = 2*x[0]+2
deriv1 = 2*x[1]
return np.array([deriv0,deriv1])
print("debug_end");
def gradient_descent_2d(grad, cur_x=np.array([0.1,0.1]), learning_rate=0.01, precision=0.0001, max_iters=10000):
for i in range(max_iters):
grad_cur = grad(cur_x)
if np.linalg.norm(grad_cur, ord=2) < precision:
break # 当梯度趋近为 0 时,视为收敛
cur_x = cur_x - grad_cur * learning_rate
return cur_x
print("debug_begin");
import numpy as np
def test():
res = gradient_descent_2d(grad_2d_test1, cur_x=np.array([1,-1]), learning_rate=0.2, precision=0.0001, max_iters=10000)
print("%.7f %.7f" %(res[0],res[1]) )
res2 = gradient_descent_2d(grad_2d_test2, cur_x=np.array([2,2]), learning_rate=0.2, precision=0.0001, max_iters=10000)
print("%.7f %.7f" %(res2[0],res2[1]) )
print("debug_end");
test()

线性回归-糖尿病预测#

import math
import numpy as np
import random
import warnings
warnings.filterwarnings("ignore")
def load_diabetes():
X = []
y = []
line = input()
while line:
dx = []
data = [l for l in line.strip().split(',')]
X.append(np.array([np.float(d) for d in data[:-1]]))
y.append(np.float(data[-1]))
line = input()
return np.array(X),np.array(y)
def train_test_split(X,Y,test_size=0.2,random_state=2333):
random.seed(random_state)
n_samples = len(X)
indices = np.arange(n_samples)
train_indexs = list(set(random.sample(indices.tolist(),int(n_samples*(1-test_size)))))
test_indexs = [k for k in indices if k not in train_indexs]
return X[train_indexs],X[test_indexs],Y[train_indexs],Y[test_indexs]
X,y = load_diabetes()
import math
import numpy as np
import random
import warnings
warnings.filterwarnings("ignore")
def load_diabetes():
X = []
y = []
line = input()
while line:
dx = []
data = [l for l in line.strip().split(',')]
X.append(np.array([np.float(d) for d in data[:-1]]))
y.append(np.float(data[-1]))
line = input()
return np.array(X),np.array(y)
def train_test_split(X,Y,test_size=0.2,random_state=2333):
random.seed(random_state)
n_samples = len(X)
indices = np.arange(n_samples)
train_indexs = list(set(random.sample(indices.tolist(),int(n_samples*(1-test_size)))))
test_indexs = [k for k in indices if k not in train_indexs]
return X[train_indexs],X[test_indexs],Y[train_indexs],Y[test_indexs]
X,y = load_diabetes()
class LinearRegression:
def __init__(self):
'''初始化模型'''
self.coef_ = None
self.interception_ = None
self._theta = None
def fit_normal(self,X_train,y_train):
'''根据训练数据集X_train,y_train训练模型'''
assert X_train.shape[0] == y_train.shape[0],'the number of X_train must equal to the number of y_train'
X_b = np.hstack([np.ones((len(X_train),1)),X_train])
self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)
self.interception_ = self._theta[0]
self.coef_ = self._theta[1:]
return self
def predict(self,X_predict):
assert self._theta is not None,'must fit before predict'
assert X_predict.shape[1] == len(self.coef_),'the feature number of X_predict must equal to X_train '
X_b = np.hstack([np.ones((len(X_predict),1)),X_predict])
return X_b.dot(self._theta)
def mse(self,y,y_pre):
return np.average((y-y_pre)**2)
def rmse(self,y,y_pre):
return np.sqrt(self.mse(y,y_pre))
def r2_score(self,y,y_pre):
return 1-(self.mse(y,y_pre)/np.var(y))
def score(self,X_test,y_test):
'''根据测试数据集确定当前模型的准确度'''
y_predict = self.predict(X_test)
return self.r2_score(y_test,y_predict),self.rmse(y_test,y_predict)
def __repr__(self):
return 'LinearRegression()'
x_train,x_test,y_train,y_test = train_test_split(X,y)
reg = LinearRegression()
reg.fit_normal(x_train,y_train)
r2,rmse = reg.score(x_test,y_test)
print("debug_begin");
def test(rmse,r2):
if rmse>50 or r2>0.5:
print(True)
else:
print(False)
print("debug_end");
test(rmse,r2)
print("debug_begin");
def test(rmse,r2):
if rmse>50 or r2>0.5:
print(True)
else:
print(False)
print("debug_end");
test(rmse,r2)

逻辑回归-乳腺癌预测#

import numpy as np
import random
import warnings
warnings.filterwarnings("ignore")
def load_breast_cancer():
X = []
y = []
line = input()
while line:
dx = []
data = [np.float64(l) for l in line.strip().split(',')]
X.append(np.array(data[:-1]))
y.append(int(data[-1]))
line = input()
return np.array(X),np.array(y)
def train_test_split(X,Y,test_size=0.2,random_state=5):
n_samples = len(X)
indices = np.arange(n_samples)
train_indexs = list(set(random.sample(indices.tolist(),int(n_samples*(1-test_size)))))
test_indexs = [k for k in indices if k not in train_indexs]
return X[train_indexs],X[test_indexs],Y[train_indexs],Y[test_indexs]
X,y = load_breast_cancer()
x_train,x_test,y_train,y_test = train_test_split(X,y)
class Logisticregression():
def __init__(self, learn_rate = 0.001, max_iteration=10000):
self.learn_rate = learn_rate
self.max_iteration = max_iteration
self._X_train = None
self._y_train = None
self._w = None
def fit(self, X_train, y_train):
m_samples, n_features = X_train.shape
self._X_train = np.insert(X_train, 0, 1, axis=1)
self._y_train = np.reshape(y_train, (m_samples, 1))
limit = np.sqrt(1 / n_features)
w = np.random.uniform(-limit, limit, (n_features, 1))
b = 0
self.w = np.insert(w, 0, b, axis=0)
iteration = 0
while iteration < self.max_iteration:
h_x = self._X_train.dot(self.w)
y_pred = 1/(1+np.exp(- h_x))
w_grad = self._X_train.T.dot(y_pred - self._y_train)
self.w = self.w - self.learn_rate * w_grad
iteration = iteration + 1
def predict(self, X_test):
X_test = np.insert(X_test, 0, 1, axis=1)
h_x = X_test.dot(self.w)
y_pripr_1 = (1/(1+np.exp(-h_x)))
y_pripr_0 = 1 - y_pripr_1
y_cal = y_pripr_1 - y_pripr_0
y_class = np.where(y_cal > 0, 1, 0)
return y_class
def score(self, X_test, y_test):
j = 0
y_test = np.reshape(y_test,(len(y_test),1))
y_hat = self.predict(X_test)
for i in range(y_test.shape[0]):
if y_hat[i,0] == y_test[i,0]:
j += 1
acc = j / len(y_test)
y_test = list(y_test.reshape((1,-1))[0])
y_hat = list(y_hat.reshape((1,-1))[0])
precision = self.get_precision(y_test,y_hat)
recall = self.get_recall(y_test,y_hat)
auc = self.get_auc(y_test,y_hat)
return acc,precision,recall,auc
def get_precision(self,y,y_hat):
true_positive = sum(yi and yi_hat for yi,yi_hat in zip(y,y_hat))
predicted_positive = sum(y_hat)
return true_positive/predicted_positive
def get_recall(self,y,y_hat):
true_positive = sum(yi and yi_hat for yi,yi_hat in zip(y,y_hat))
actual_positive = sum(y)
return true_positive/actual_positive
def get_tnr(self,y,y_hat):
true_negative = sum(1-(yi or yi_hat) for yi,yi_hat in zip(y,y_hat))
actual_negative = len(y) - sum(y)
return true_negative/actual_negative
def get_roc(self,y,y_hat):
thresholds = sorted(set(y_hat),reverse=True)
ret = [[0,0]]
for threshold in thresholds:
y_hat = [int(yi_hat >= threshold) for yi_hat in y_hat]
ret.append([self.get_recall(y,y_hat),1-self.get_tnr(y,y_hat)])
return ret
def get_auc(self,y,y_hat):
roc = iter(self.get_roc(y,y_hat))
tpr_pre, fpr_pre = next(roc)
auc = 0
for tpr,fpr in roc:
auc += (tpr+tpr_pre)*(fpr-fpr_pre)/2
tpr_pre = tpr
fpr_pre = fpr
return auc
lr = Logisticregression()
lr.fit(x_train,y_train)
acc,precision,recall,auc = lr.score(x_test,y_test)
print("debug_begin");
def test(acc,auc):
if acc>0.8 or auc>0.8:
print(True)
else:
print(False)
print("debug_end");
test(acc,auc)

svm-手写数字识别#

import numpy as np
import warnings
import random
warnings.filterwarnings("ignore")
def load_digits():
X = []
y = []
line = input()
while line:
dx = []
data = [l for l in line.strip().split(',')]
X.append(np.array([np.float(d) for d in data[:-1]]))
y.append(np.int(data[-1]))
line = input()
if '#' in line:
break
return np.array(X),np.array(y)
def train_test_split(X,Y,test_size=0.2,random_state=5):
n_samples = len(X)
assert len(X)==len(Y)
indices = np.arange(n_samples)
random.seed(random_state)
train_indexs = list(set(random.sample(indices.tolist(),int(n_samples*(1-test_size)))))
test_indexs = [k for k in indices if k not in train_indexs]
return X[train_indexs,:],X[test_indexs,:],Y[train_indexs],Y[test_indexs]
X,y = load_digits()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
class SVC():
def __init__(self,X,Y,alpha,steps,reg):
self.X = X
self.y = Y
self.alpha = alpha
self.steps = steps
self.reg = reg
self.model(self.X,self.y,self.alpha,self.steps,self.reg)
def lossAndGradNaive(self,X,Y,W,reg):
dW=np.zeros(W.shape)
loss = 0.0
num_class=W.shape[0]
num_X=X.shape[0]
for i in range(num_X):
scores=np.dot(W,X[i])
cur_scores=scores[int(Y[i])]
for j in range(num_class):
if j==Y[i]:
continue
margin=scores[j]-cur_scores+1
if margin>0:
loss+=margin
dW[j,:]+=X[i]
dW[int(Y[i]),:]-=X[i]
loss/=num_X
dW/=num_X
loss+=reg*np.sum(W*W)
dW+=2*reg*W
return loss,dW
def lossAndGradVector(self,X,Y,W,reg):
dW=np.zeros(W.shape)
N=X.shape[0]
Y_=X.dot(W.T)
margin=Y_-Y_[range(N),Y.astype(int)].reshape([-1,1])+1.0
margin[range(N),Y.astype(int)]=0.0
margin=(margin>0)*margin
loss=0.0
loss+=np.sum(margin)/N
loss+=reg*np.sum(W*W)
countsX=(margin>0).astype(int)
countsX[range(N),Y.astype(int)]=-np.sum(countsX,axis=1)
dW+=np.dot(countsX.T,X)/N+2*reg*W
return loss,dW
def predict(self,X,W):
X=np.hstack([X, np.ones((X.shape[0], 1))])
Y_=np.dot(X,W.T)
Y_pre=np.argmax(Y_,axis=1)
return Y_pre
def accuracy(self,X,Y):
Y_pre=self.predict(X,self.W)
acc=(Y_pre==Y).mean()
return acc
def model(self,X,Y,alpha,steps,reg):
X=np.hstack([X, np.ones((X.shape[0], 1))])
W = np.random.randn(10,X.shape[1]) * 0.0001
for step in range(steps):
loss,grad=self.lossAndGradNaive(X,Y,W,reg)
W-=alpha*grad
self.W = W
svc=SVC(X_train,y_train,0.01,25,0.5)
acc = svc.accuracy(X_test,y_test)
print("debug_begin");
def test_acc(acc):
res = True if acc>0.85 else False
print(res)
print("debug_end");
test_acc(acc)

svm-梯度下降实现 SVM 多分类问题#

import numpy as np
import warnings
def load_iris():
X = []
y = []
line = input()
while line:
dx = []
data = [l for l in line.strip().split(',')]
X.append(np.array([np.float(d) for d in data[:-1]]))
y.append(np.int(data[-1]))
line = input()
if '#' in line:
break
return np.array(X),np.array(y)
x,y = load_iris()
print("debug_begin");
def test_acc(acc):
res = True if acc>=0.9 else False
print(res)
print("debug_end");
def normalize_data(data):
mean = np.mean(data, axis=0)
std = np.std(data, axis=0)
for i in range(data.shape[0]):
data[i, :] = (data[i, :] - mean) / std
return data
def convert_to_one_hot(y, C):
return np.eye(C)[y.reshape(-1)]
batchsz = 150
def obtain_w_via_gradient_descent(x, c, y, penalty_c, threshold = 1e-19, learn_rate = 1e-4):
""" 利用梯度下降法求解如下的SVM问题:min 1/2 * w^T * w + C * Σ_i=1:n(max(0, 1 - y_i * (w^T * x_i + b)))
:param x: 训练样本 x = [x_1, x_2, ..., x_i]
:param c: 类别数
:param y: 样本标签 y = [y_1, y_2, ..., y_c]
:param threshold: 梯度下降停止阈值
"""
data_num = np.shape(x)[1]
feature_dim = np.shape(x)[0]
w = np.ones([feature_dim, c], dtype=np.float32)
b = np.ones([c, 1], dtype=np.float32)
dl_dw = np.zeros([feature_dim, c], dtype=np.float)
dl_db = np.zeros([c, 1], dtype=np.float)
it = 1
th = 0.1
while it < 50000 and th > threshold:
a = np.tile(b, [1, data_num])
ksi = (np.transpose(w) @ x + np.tile(b, [1, data_num])) * y
index_martix = ksi < 1
for class_num in range(c):
index_vector = index_martix[class_num, :]
if True in index_vector:
x_c = x[:, index_vector]
data_num_c = np.shape(x_c)[1]
e = np.ones([data_num_c, 1], dtype=np.float)
y_c = np.reshape(y[class_num, index_vector], [data_num_c, 1])
w_c = np.reshape(w[:, class_num], [feature_dim, 1])
b_c = b[class_num]
dl_dw[:, class_num] = (w_c + 2 * penalty_c * (x_c @ np.transpose(x_c) @ w_c +
x_c @ e * b_c -
x_c @ y_c))[:, 0]
dl_db[class_num, 0] = 2 * penalty_c * (b_c * data_num_c +
np.transpose(w_c) @ x_c @ e -
np.transpose(y_c) @ e)
else:
w_c = np.reshape(w[:, class_num], [feature_dim, 1])
dl_dw[:, class_num] = w_c[:, 0]
dl_db[class_num, 0] = 0
w_ = w - learn_rate * (dl_dw / np.linalg.norm(dl_dw, ord=2))
b_ = b - learn_rate * dl_db
th = np.sum(np.square(w_ - w)) + np.sum(np.square(b_ - b))
it = it + 1
w = w_
b = b_
y_predict = np.transpose(w) @ x + np.tile(b, [1, data_num])
correct_prediction = np.equal(np.argmax(y_predict, 0), np.argmax(y, 0))
accuracy = np.mean(correct_prediction.astype(np.float))
return accuracy
warnings.filterwarnings("ignore")
x = normalize_data(x)
y = y.astype(np.int)
y_onehot = convert_to_one_hot(y,3)
y_onehot[y_onehot==0]=-1
x = np.transpose(x)
y_onehot = np.transpose(y_onehot)
w = np.array([[1,1,1],[1,1,1]])
b = np.array([[1],[1],[1]])
acc = obtain_w_via_gradient_descent(x,3,y_onehot,0.5)
test_acc(acc)

分享到社交平台

将本文分享给你的朋友们

2026-01-07-机器学习相关算法
https://firefly.cuteleaf.cn/posts/2026-01-07-机器学习相关算法/
作者
Zhongye
发布于
2026-01-08
版权声明
CC BY-NC-SA 4.0

评论

Profile Image of the Author
Zhongye
南漂中
公告
新的博客站!旧站点传送门 zhongye1.github.io/Arknight-notes
音乐
专辑封面

音乐

暂无播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章数
142
分类数
14
标签数
214
总字数
339,690
运行天数
0
最后更新
0 天前

目录