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

文章发布时间:

最后更新时间:

页面浏览: 加载中...

评估方法(留出法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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");

评估方法(交叉验证法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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()

线性回归-糖尿病预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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)

逻辑回归-乳腺癌预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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-手写数字识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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 多分类问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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)