因子分解机——代码

    技术2024-07-22  64

    利用矩阵,梯度下降算法实现的因子分解机  

    import numpy as np

    LEARNING_RATE = 0.95 REGULARIZATION_COEFFICIENT = 0.000001 STEP_THRESHOLD = 300 K = 6

    def sigmoid(x):     return 1/(1+np.exp(-x))

    class factorizationMachine:     #x: a sample in train_set     #cross_v: it is a two-dimensional numpy, whose shape is (k,n).And n is sample's feature number.     def __init__(self, w0, linear_w, cross_v):         self.w0 = w0         self.linear_w = linear_w         self.cross_v = cross_v

        #def pi_map(self, i):          def inference(self, x):         return self.w0 + self.linear_w.dot(x) + np.sum((self.cross_v.dot(x))**2) - np.sum((self.cross_v**2).dot(x**2))          def loss(self, y, x):         # y_ is predicted value, y is real value         y_ = self.inference(x)         #L2 regularization         loss = -log(sigmoid(y*y_)) + REGULARIZATION_COEFFICIENT * (self.w0**2 + np.sum(self.linear_w**2) + np.sum(self.cross_v**2))                  return loss          def sgd(self, x, training_steps):         self.w0 = self.w0 - pow(LEARNING_RATE, training_steps//STEP_THRESHOLD)*(1 + 2*REGULARIZATION_COEFFICIENT*self.w0)         self.linear_w = self.linear_w - pow(LEARNING_RATE, training_steps//STEP_THRESHOLD)*(x + 2*REGULARIZATION_COEFFICIENT*self.linear_w)         # v's gradient descent         X = np.repeat(x.reshape((1,-1)), self.cross_v.shape[0], axis=0)         X_square = X ** 2                  mid_mat = self.cross_v.dot(x)         aux_matrix = np.repeat(mid_mat.reshape((-1, 1)), x.size, axis=1)         self.cross_v =self.cross_v - pow(LEARNING_RATE, training_steps//STEP_THRESHOLD) * (X * aux_matrix - X_square * self.cross_v + 2 * REGULARIZATION_COEFFICIENT * self.cross_v)          if __name__ == "__main__":     #x = np.random.randn(3)     x = np.array([-1.84753684, 1.30561765, 1.95972212])     y = -1     w0 = 0     linear_w = np.zeros(x.size)     #cross_v = np.random.normal(loc=0, scale=1, size=(K, x.size))     cross_v = np.array([[-1.41691403, -1.48210948, -0.88291598],                          [ 1.0972494, 0.99061111, -1.09201868],                          [-0.3598063, 0.93424249, 1.23286087],                          [-0.63127532, 1.55323683 , -0.26382005],                          [ 0.55052691, -1.61802769, -0.50357173],                          [-0.50000688, 2.36227975, -0.42941842]])     fm = factorizationMachine(w0, linear_w, cross_v)          #print(fm.inference(x))     #print("loss is: ", fm.loss(y, x))     print(fm.sgd(x, 10000))     print(fm.cross_v)     print(fm.cross_v - cross_v)

    Processed: 0.149, SQL: 9