Python笔记 之 根据用户订单计算商品同单概率

说明

该算法通过获取用户订单详情(未拆分订单),根据商品关联关系算法计算商品两两同单的概率,并以此为先验概率向用户推荐商品。

算法

ini配置文件

文件名:CFGOracle.ini

;Oracle数据库配置信息  
  
[orcl]  
host = 192.168.0.10 
port = 1521  
sid = orcl  
user = test  
psword = 123456

configparser辅助类

# -*- codeing = utf-8 -*-  
# @File : CCLParameter.py  
# @Author : 一起种梧桐吧  
# @Version : Python 3.10.0  
# @Software : PyCharm  
# @Time : 2022-08-25 14:23  
# @Purpose : 读取ini配置文件  
  
from configparser import ConfigParser as config  
  
  
class Parameter():  
   """读取mysql数据库配置文件'./CFGMysql.ini'"""  
   def __init__(self, section, filename, coding='utf-8'):  
      """初始化参数"""  
      self.section = section  
      self.filename = filename  
      self.coding = coding  
      self.config = config()  
      self.dict = {}  
      self.getOption()  
  
   def getOption(self):  
      """遍历option获取配置文件"""  
      try:  
         self.config.read(self.filename, self.coding)  
         for option in self.config.options(self.section):  
            self.dict[option] = self.config.get(self.section, option)  
      except Exception as err:  
         return str(err)  
      else:  
         return '成功读取"{}"文件"{}"配置'.format(self.filename, self.section)  
  
  
if __name__ == "__main__":  
   p = Parameter('ouser', './CFGMysql.ini')  
   print(p.dict)

数学排列辅助类

# -*- codeing = utf-8 -*-  
# @File : CCLPermutation.py  
# @Author : 一起种梧桐吧  
# @Version : Python 3.10.0  
# @Software : PyCharm  
# @Time : 2022-08-23 16:29  
# @Purpose :  使用Python实现排列算法  
  
class Permutation():  
   """构建数学排列,对一个列表或者元组进行数据分析"""  
   def permute(self, lst):  
      """  
      对数据源进行排列并返回排列列表  
      :param lst: 元素列表  
      :return:所有的排列组合方式  
      """      if len(lst) <= 1: return [[]]  # 列表为空或者单个元素返回空列表  
      if len(lst) == 2: return self.subset(lst)  # 元素个数【1,2】直接调用subset()  
      # 元素个数>=2循环直接调用subset()  
      results = []  
      for i in range(2, len(lst) + 1):  
         results.extend(self.subset(lst, i))  
      return results  
     
   def subset(self, lst, size=2):  
      '''  
      构建指定个数元素的排列方式列表  
      :param lst: 元素列表  
      :param size: 指定长度  
      :return: 所有的排列组合方式  
      '''      if size < 1 or not lst: return [[]]  
      results = []  
      for i in range(len(lst)):  
         pick = lst[i:i + 1]  
         rest = lst[:i] + lst[i + 1:]  
         for x in self.subset(rest, size - 1):  
            results.append(pick + x)  
      return results  
  
  
if __name__ == '__main__':  
   lt = ['a', 'b', 'c']  
   pm = Permutation()  
   print(pm.permute(lt))  
   print(pm.subset(lt, 2))

oracle辅助类

# -*- codeing = utf-8 -*-  
# @File : CCLOracle.py  
# @Author : 一起种梧桐吧  
# @Version : Python 3.10.0  
# @Software : PyCharm  
# @Time : 2022-08-25 14:57  
# @Purpose : 连接指定Oracle数据库并管理指针  
  
import cx_Oracle as oracle  
from CCLParameter import Parameter  
  
defautfile = './Cfg_oracle.ini'  
  
  
class OracleHelper():  
   """获取oracle数据库游标并管理指针"""  
   def __init__(self, section, filename='./CFGOracle.ini', coding='utf-8'):  
      """初始化并读取配置文件"""  
      self.section = section  
      self.config = Parameter(section, filename, coding)  
      self.conn = None  
      self.curs = None  
      self.getCursor()  
   def getCursor(self):  
      """尝试获取游标"""  
      try:  
         dns = oracle.makedsn(self.config.dict['host'],  
                         int(self.config.dict['port']),  
                         self.config.dict['sid'])  
         self.conn = oracle.connect(self.config.dict['user'],  
                              self.config.dict['psword'],  
                              dns)  
         self.curs = self.conn.cursor()  
      except Exception as err:  
         return str(err)  
      else:  
         return '成功连接到Oracle数据库%s' % self.section  
     
   def release(self):  
      """释放游标"""  
      if self.curs:  
         self.curs.close()  
         return '成功释放Oracle数据%s指针' % self.section  
      if self.conn:  
         self.conn.close()  
         return '成功释放Oracle数据%s连接' % self.section  
  
  
if __name__ == '__main__':  
   orcl = OracleHelper('slave01')  
   orcl.release()

计算商品关联关系

# -*- codeing = utf-8 -*-  
# @File : CCLAlgorithm.py  
# @Author : 一起种梧桐吧  
# @Version : Python 3.10.0  
# @Software : PyCharm  
# @Time : 2022-09-09 10:36  
# @Purpose : 计算商品关联关系  
  
from CCLDecorator import decorator  
from CCLOracle import OracleHelper  
from CCLPermutation import Permutation  
  
  
class Algorithm():  
   """    计算商品关联关系  """   
   def __init__(self):  
      self.defaultsize = 200000  
      self.ordercount = 10  
      self.tasks = []  
      self.relations = {}  
      
   def getTasks(self, section='orcl',  
             sql='''Select frmuser, frmtable, sqlread, touser, totable, sqlinsert  
                From ctrl_sqlcommands                Where pjectname = 'hnxhhy'                And sqltype = 'algorithm'                And flag = 1'''):  
      """根据section读取CFGOracle.ini配置文件,读取待执行任务"""  
      client = None  
      try:  
         client = OracleHelper(section)  
         self.tasks = client.curs.execute(sql).fetchall()  
      except Exception as err:  
         return str(err)  
      else:  
         return '获取任务{}条'.format(len(self.tasks))  
      finally:  
         if client: client.release()  
   
   def statistic(self, item):  
      """  
      分析订单数据获取商品之间同单数量  
      :param item:      :return:  
      """      
      frmuser, frmtable, sqlread, touser, totable, sqlinsert = range(6)  
      oracle_read = OracleHelper(item[frmuser])  
      oracle_load = OracleHelper(item[touser])  
      # item[sqlread]在oracle数据库为nclob类型,需要使用read()获取存储的字符串
      oracle_read.curs.execute(item[sqlread].read())  
      soitem = {}  
      ordercode, productid = range(2)  
      for recode in oracle_read.curs.fetchall():  
         if recode[ordercode] in soitem.keys():  
            soitem[recode[ordercode]].add(recode[productid])  
         else:  
            soitem[recode[ordercode]] = {recode[productid], }  
      pm = Permutation()  
      for val in soitem.values():  
         # 判断订单商品数量,如果商品数量小于1继续下一循环  
         if len(val)<=1:  
            continue  
         for rel in pm.subset(list(val), 2):  
            _ = '&'.join(rel)  
            if _ in self.relations.keys():  
               self.relations[_] += 1  
            else:  
               self.relations[_] = 1  
      datas = []  
      for key, val in self.relations.items():  
         # 如果同单次数小于阈值,继续下一循环  
         if val <= self.ordercount:  
            continue  
         _ = key.split('&')  
         _.append(val)  
         datas.append(_)  
      rowcount = len(datas)  
      while len(datas) >= self.defaultsize:  
         slice, datas = datas[:self.defaultsize], datas[self.defaultsize:]  
         oracle_load.curs.executemany(item[sqlinsert].read(), slice)  
         oracle_load.conn.commit()  
      else:  
         if datas:  
            oracle_load.curs.executemany(item[sqlinsert].read(), datas)  
            oracle_load.conn.commit()  
      if oracle_read: oracle_read.release()  
      if oracle_load: oracle_load.release()  
      return "成功从{}.{}传输{}条数据到{}.{}".format(item[frmuser], item[frmtable], rowcount, item[touser], item[totable])  

   def run(self):  
      self.getTasks()  
      if not self.tasks:  
         return '没有待执行任务'  
      for item in self.tasks:  
         self.statistic(item)  
      return '{}条任务执行完成'.format(len(self.tasks))  
  
  
if __name__ == '__main__':  
   worker = Algorithm()  
   worker.getTasks()  
   worker.run()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值