Skip to content

Commit 1e42129

Browse files
Create ridge_regression_train.py
1 parent 96f8640 commit 1e42129

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# coding:UTF-8
2+
'''
3+
Date:20160928
4+
@author: zhaozhiyong
5+
'''
6+
7+
import numpy as np
8+
9+
def load_data(file_path):
10+
'''导入训练数据
11+
input: file_path(string):训练数据
12+
output: feature(mat):特征
13+
label(mat):标签
14+
'''
15+
f = open(file_path)
16+
feature = []
17+
label = []
18+
for line in f.readlines():
19+
feature_tmp = []
20+
lines = line.strip().split("\t")
21+
feature_tmp.append(1) # x0
22+
for i in xrange(len(lines) - 1):
23+
feature_tmp.append(float(lines[i]))
24+
feature.append(feature_tmp)
25+
label.append(float(lines[-1]))
26+
f.close()
27+
return np.mat(feature), np.mat(label).T
28+
29+
def ridge_regression(feature, label, lam):
30+
'''最小二乘的求解方法
31+
input: feature(mat):特征
32+
label(mat):标签
33+
output: w(mat):回归系数
34+
'''
35+
n = np.shape(feature)[1]
36+
w = (feature.T * feature + lam * np.mat(np.eye(n))).I * feature.T * label
37+
return w
38+
39+
def get_gradient(feature, label, w, lam):
40+
'''计算导函数的值
41+
input: feature(mat):特征
42+
label(mat):标签
43+
output: w(mat):回归系数
44+
'''
45+
err = (label - feature * w).T
46+
left = err * (-1) * feature
47+
return left.T + lam * w
48+
49+
def get_result(feature, label, w, lam):
50+
'''
51+
input: feature(mat):特征
52+
label(mat):标签
53+
output: w(mat):回归系数
54+
'''
55+
left = (label - feature * w).T * (label - feature * w)
56+
right = lam * w.T * w
57+
return (left + right) / 2
58+
59+
def get_error(feature, label, w):
60+
'''
61+
input: feature(mat):特征
62+
label(mat):标签
63+
output: w(mat):回归系数
64+
'''
65+
m = np.shape(feature)[0]
66+
left = (label - feature * w).T * (label - feature * w)
67+
return (left / (2 * m))[0, 0]
68+
69+
70+
def bfgs(feature, label, lam, maxCycle):
71+
'''利用bfgs训练Ridge Regression模型
72+
input: feature(mat):特征
73+
label(mat):标签
74+
lam(float):正则化参数
75+
maxCycle(int):最大迭代次数
76+
output: w(mat):回归系数
77+
'''
78+
n = np.shape(feature)[1]
79+
# 1、初始化
80+
w0 = np.mat(np.zeros((n, 1)))
81+
rho = 0.55
82+
sigma = 0.4
83+
Bk = np.eye(n)
84+
k = 1
85+
while (k < maxCycle):
86+
print "\titer: ", k, "\terror: ", get_error(feature, label, w0)
87+
gk = get_gradient(feature, label, w0, lam) # 计算梯度
88+
dk = np.mat(-np.linalg.solve(Bk, gk))
89+
m = 0
90+
mk = 0
91+
while (m < 20):
92+
newf = get_result(feature, label, (w0 + rho ** m * dk), lam)
93+
oldf = get_result(feature, label, w0, lam)
94+
if (newf < oldf + sigma * (rho ** m) * (gk.T * dk)[0, 0]):
95+
mk = m
96+
break
97+
m = m + 1
98+
99+
# BFGS校正
100+
w = w0 + rho ** mk * dk
101+
sk = w - w0
102+
yk = get_gradient(feature, label, w, lam) - gk
103+
if (yk.T * sk > 0):
104+
Bk = Bk - (Bk * sk * sk.T * Bk) / (sk.T * Bk * sk) + (yk * yk.T) / (yk.T * sk)
105+
106+
k = k + 1
107+
w0 = w
108+
return w0
109+
110+
def lbfgs(feature, label, lam, maxCycle, m=10):
111+
'''利用lbfgs训练Ridge Regression模型
112+
input: feature(mat):特征
113+
label(mat):标签
114+
lam(float):正则化参数
115+
maxCycle(int):最大迭代次数
116+
m(int):lbfgs中选择保留的个数
117+
output: w(mat):回归系数
118+
'''
119+
n = np.shape(feature)[1]
120+
# 1、初始化
121+
w0 = np.mat(np.zeros((n, 1)))
122+
rho = 0.55
123+
sigma = 0.4
124+
125+
H0 = np.eye(n)
126+
127+
s = []
128+
y = []
129+
130+
k = 1
131+
gk = get_gradient(feature, label, w0, lam) # 3X1
132+
print gk
133+
dk = -H0 * gk
134+
# 2、迭代
135+
while (k < maxCycle):
136+
print "iter: ", k, "\terror: ", get_error(feature, label, w0)
137+
m = 0
138+
mk = 0
139+
gk = get_gradient(feature, label, w0, lam)
140+
# 2.1、Armijo线搜索
141+
while (m < 20):
142+
newf = get_result(feature, label, (w0 + rho ** m * dk), lam)
143+
oldf = get_result(feature, label, w0, lam)
144+
if newf < oldf + sigma * (rho ** m) * (gk.T * dk)[0, 0]:
145+
mk = m
146+
break
147+
m = m + 1
148+
149+
# 2.2、LBFGS校正
150+
w = w0 + rho ** mk * dk
151+
152+
# 保留m个
153+
if k > m:
154+
s.pop(0)
155+
y.pop(0)
156+
157+
# 保留最新的
158+
sk = w - w0
159+
qk = get_gradient(feature, label, w, lam) # 3X1
160+
yk = qk - gk
161+
162+
s.append(sk)
163+
y.append(yk)
164+
165+
# two-loop
166+
t = len(s)
167+
a = []
168+
for i in xrange(t):
169+
alpha = (s[t - i - 1].T * qk) / (y[t - i - 1].T * s[t - i - 1])
170+
qk = qk - alpha[0, 0] * y[t - i - 1]
171+
a.append(alpha[0, 0])
172+
r = H0 * qk
173+
174+
for i in xrange(t):
175+
beta = (y[i].T * r) / (y[i].T * s[i])
176+
r = r + s[i] * (a[t - i - 1] - beta[0, 0])
177+
178+
if yk.T * sk > 0:
179+
print "update OK!!!!"
180+
dk = -r
181+
182+
k = k + 1
183+
w0 = w
184+
return w0
185+
186+
def save_weights(file_name, w0):
187+
'''保存最终的结果
188+
input: file_name(string):需要保存的文件
189+
w0(mat):权重
190+
'''
191+
f_result = open("weights", "w")
192+
m, n = np.shape(w0)
193+
for i in xrange(m):
194+
w_tmp = []
195+
for j in xrange(n):
196+
w_tmp.append(str(w0[i, j]))
197+
f_result.write("\t".join(w_tmp) + "\n")
198+
f_result.close()
199+
200+
201+
if __name__ == "__main__":
202+
# 1、导入数据
203+
print "----------1.load data ------------"
204+
feature, label = load_data("data.txt")
205+
# 2、训练模型
206+
print "----------2.training ridge_regression ------------"
207+
method = "lbfgs" # 选择的方法
208+
if method == "bfgs": # 选择BFGS训练模型
209+
w0 = bfgs(feature, label, 0.5, 1000)
210+
elif method == "lbfgs": # 选择L-BFGS训练模型
211+
w0 = lbfgs(feature, label, 0.5, 10, m=10)
212+
else: # 使用最小二乘的方法
213+
w0 = ridge_regression(feature, label, 0.5)
214+
# 3、保存最终的模型
215+
print "----------3.save model ------------"
216+
save_weights("weights", w0)

0 commit comments

Comments
 (0)