前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >推荐算法|FM模型预测多分类python实现

推荐算法|FM模型预测多分类python实现

作者头像
三猫
发布2021-12-06 15:39:31
7560
发布2021-12-06 15:39:31
举报
文章被收录于专栏:机器学习养成记

导读:上一期推荐算法|FM模型预测多分类原理简介中介绍了FM进行多分类预测的原理,这一篇我们就来看下如何通过python实现。

1

softmax溢出

因为softmax函数中存在指数运算,而计算机中存储数据是有长度限制的,因此,如果数据过大或者过小就会出现上/下溢出,即exp(1000)=inf,导致我们训练不出结果。

通过上图可发现,softmax不受偏移影响,因此我们把softmax(x)变为softmax(x-z),其中z为x中的最大值,便可同时解决上、下溢出问题。

2

python实现

我们使用鸢尾花数据进行展示,完整代码如下。

代码语言:javascript
复制
class Softmax:
    '''
    digits:x变量,dataframe类型
    labels:y标签,dataframe类型,取值为0,1,2...表示不同类别
    '''
    def softmax(self, X):   #softmax函数
        m_max = np.max(X)
        return np.exp(X-m_max) / np.sum(np.exp(X-m_max))#防止溢出
#         return np.exp(X) / np.sum(np.exp(X))
    
    def FM_train(self, digits, labels, maxIter = 100, alpha = 0.01,k = 10):
        
        n, m = np.shape(digits) #样本数和特征数
        c = labels.drop_duplicates().shape[0] #分类的类别数
    
        #1、初始化参数
        self.w = np.zeros(( m,c))
        self.v = normalvariate(0, 0.2) * np.ones((c, m, k))
        self.w_0 = np.zeros((1,c))
        #2、迭代更新
        for iter in range(maxIter):
            for i in range(n):
                x = digits.iloc[i,:]
                y = np.zeros(c)
                y[labels.iloc[i,0]] = 1
                inter_1 = np.dot(x,self.v)
                inter_2 = np.dot(np.multiply(x, x),np.multiply(self.v, self.v))
                #完成交叉项
                interaction = np.sum((np.multiply(inter_1, inter_1) - inter_2),axis=1) / 2.  
                s = self.w_0+np.dot(x,self.w) + interaction  
                p = self.softmax(s)
                #w0更新
                self.w_0 -= alpha * (p - y)
                for z in range(m):   
                    if x[z] != 0:
                        #w更新
                        self.w[z] -= (alpha * (x[z]*(p - y)))[0]
                        for j in range(k):
                            #v更新
                            self.v[:, z, j] -= alpha * (x[z] * inter_1[:,j] - self.v[:, z, j] * x[z] * x[z])*(p-y)[0]
        print(self.w_0)
        return self.w_0,self.w,self.v
    
    def Assessment(self, digits, classLabels):
        n, m = shape(digits)
        allItem = 0
        error = 0
        result = []
        for i in range(n):
            allItem += 1
            x = digits.iloc[i,:]
            inter_1 = np.dot(x,self.v)
            inter_2 = np.dot(np.multiply(x, x),np.multiply(self.v, self.v))
            interaction = np.sum((np.multiply(inter_1, inter_1) - inter_2),axis=1)
            s = self.w_0+np.dot(x,self.w) + interaction 
            p = self.softmax(s)
            pre = np.argmax(p)#返回最大值
            result.append(pre)
            if pre != classLabels.iloc[i,0] :
                error += 1
            else:
                continue
        return result,float(error) / allItem

往期推荐:

推荐算法概述

推荐算法|矩阵分解模型

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器学习养成记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档