个人编程网站

进销存(JXC)软件开发技术积累与分享

进销存系统智能推荐算法设计与实现

智能推荐概述

在进销存系统中,智能推荐可以帮助企业发现销售机会、优化库存结构、提升客户满意度。本文介绍商品推荐、关联销售和用户行为分析的实现方案。

推荐系统架构

推荐系统整体架构包含数据层、算法层、服务层和应用层:

层次 功能 技术选型
数据层 用户行为采集、商品数据存储 MySQL、Redis
算法层 协同过滤、关联规则、排序模型 Python、TensorFlow
服务层 推荐接口、实时推荐、AB测试 Koa.js
应用层 Web端、小程序、APP展示 Vue、React

核心推荐算法

1. 协同过滤推荐

基于用户或商品的相似度进行推荐:

// 协同过滤推荐服务
class CollaborativeFiltering {
  // 计算用户相似度(余弦相似度)
  calculateUserSimilarity(userId1, userId2) {
    const ratings1 = this.getUserRatings(userId1);
    const ratings2 = this.getUserRatings(userId2);

    // 找出两个用户共同评分过的商品
    const commonItems = Object.keys(ratings1).filter(
      item => item in ratings2
    );

    if (commonItems.length === 0) return 0;

    // 构建向量
    const vec1 = commonItems.map(item => ratings1[item]);
    const vec2 = commonItems.map(item => ratings2[item]);

    return this.cosineSimilarity(vec1, vec2);
  }

  // 基于用户的推荐
  getUserBasedRecommendations(userId, topN = 10) {
    // 找到相似用户
    const allUsers = this.getAllUsers();
    const similarities = allUsers
      .filter(id => id !== userId)
      .map(id => ({
        userId: id,
        similarity: this.calculateUserSimilarity(userId, id)
      }))
      .sort((a, b) => b.similarity - a.similarity)
      .slice(0, 20); // 取Top20相似用户

    // 获取目标用户未购买商品
    const userPurchased = this.getUserPurchasedItems(userId);
    const allItems = this.getAllItems();
    const unpurchasedItems = allItems.filter(
      item => !userPurchased.includes(item.id)
    );

    // 计算推荐分数
    const scores = unpurchasedItems.map(item => {
      let score = 0;
      let weightSum = 0;

      similarities.forEach(({ userId, similarity }) => {
        if (similarity > 0) {
          const rating = this.getRating(userId, item.id) || 0;
          score += similarity * rating;
          weightSum += similarity;
        }
      });

      return {
        item,
        score: weightSum > 0 ? score / weightSum : 0
      };
    });

    return scores
      .sort((a, b) => b.score - a.score)
      .slice(0, topN);
  }

  // 余弦相似度计算
  cosineSimilarity(vec1, vec2) {
    const dotProduct = vec1.reduce((sum, v, i) => sum + v * vec2[i], 0);
    const magnitude1 = Math.sqrt(vec1.reduce((sum, v) => sum + v * v, 0));
    const magnitude2 = Math.sqrt(vec2.reduce((sum, v) => sum + v * v, 0));

    if (magnitude1 === 0 || magnitude2 === 0) return 0;
    return dotProduct / (magnitude1 * magnitude2);
  }
}

2. 关联规则挖掘

使用Apriori算法挖掘商品关联关系:

// 关联规则推荐
class AssociationRecommender {
  // Apriori算法 - 找出频繁项集
  apriori(transactions, minSupport = 0.01) {
    // 统计单项支持度
    const itemCounts = {};
    transactions.forEach(t => {
      t.items.forEach(item => {
        itemCounts[item] = (itemCounts[item] || 0) + 1;
      });
    });

    const totalTransactions = transactions.length;
    const frequentItems = Object.entries(itemCounts)
      .filter(([_, count]) => count / totalTransactions >= minSupport)
      .map(([item]) => [item]);

    // 迭代生成候选项集
    let currentFrequent = frequentItems;
    const allFrequent = [currentFrequent];

    while (currentFrequent.length > 0) {
      const candidates = this.generateCandidates(currentFrequent);

      // 统计候选项支持度
      const candidateCounts = {};
      transactions.forEach(t => {
        const itemSet = new Set(t.items);
        candidates.forEach(candidate => {
          if (candidate.every(item => itemSet.has(item))) {
            const key = candidate.join(',');
            candidateCounts[key] = (candidateCounts[key] || 0) + 1;
          }
        });
      });

      currentFrequent = Object.entries(candidateCounts)
        .filter(([_, count]) => count / totalTransactions >= minSupport)
        .map(([key]) => key.split(','));

      if (currentFrequent.length > 0) {
        allFrequent.push(currentFrequent);
      }
    }

    return allFrequent.flat();
  }

  // 生成候选项集
  generateCandidates(prevItemsets) {
    const candidates = [];
    for (let i = 0; i < prevItemsets.length; i++) {
      for (let j = i + 1; j < prevItemsets.length; j++) {
        const combined = [...new Set([...prevItemsets[i], ...prevItemsets[j]])];
        if (combined.length === prevItemsets[0].length + 1) {
          candidates.push(combined.sort());
        }
      }
    }
    return candidates;
  }

  // 计算关联规则置信度
  calculateConfidence(rule, transactions) {
    const { antecedent, consequent } = rule;

    // 支持度 P(A∪B)
    const abSupport = this.getSupport(antecedent.concat(consequent), transactions);

    // 前件支持度 P(A)
    const aSupport = this.getSupport(antecedent, transactions);

    // 置信度 P(B|A) = P(A∪B) / P(A)
    return aSupport > 0 ? abSupport / aSupport : 0;
  }

  // 获取某个项集的支持度
  getSupport(itemset, transactions) {
    let count = 0;
    transactions.forEach(t => {
      const itemSet = new Set(t.items);
      if (itemset.every(item => itemSet.has(item))) {
        count++;
      }
    });
    return count / transactions.length;
  }

  // 生成推荐规则
  generateRules(frequentItemsets, transactions, minConfidence = 0.5) {
    const rules = [];

    frequentItemsets.forEach(itemset => {
      if (itemset.length < 2) return;

      // 生成所有可能的规则
      for (let i = 1; i < itemset.length; i++) {
        const combinations = this.getCombinations(itemset, i);

        combinations.forEach(antecedent => {
          const consequent = itemset.filter(item => !antecedent.includes(item));
          const confidence = this.calculateConfidence(
            { antecedent, consequent },
            transactions
          );

          if (confidence >= minConfidence) {
            rules.push({
              antecedent,
              consequent,
              confidence,
              support: this.getSupport(itemset, transactions)
            });
          }
        });
      }
    });

    return rules.sort((a, b) => b.confidence - a.confidence);
  }
}

3. 基于销售数据的智能补货推荐

结合历史销售数据预测补货需求:

// 智能补货推荐
class ReplenishmentRecommender {
  constructor() {
    this.seasonalFactors = {}; // 季节性因子
  }

  // 计算加权移动平均预测
  predictSales(productId, futureDate) {
    const historicalData = this.getSalesHistory(productId, 90); // 90天历史

    // 权重:近期数据权重更高
    const weights = [0.5, 0.3, 0.2].reverse();
    const recentData = historicalData.slice(-weights.length);

    // 计算基础预测
    const basePred = recentData.reduce(
      (sum, sale, i) => sum + sale.quantity * weights[i],
      0
    );

    // 考虑季节性因子
    const month = new Date(futureDate).getMonth();
    const seasonalFactor = this.getSeasonalFactor(productId, month);

    // 考虑增长趋势
    const trendFactor = this.calculateTrend(historicalData);

    return Math.round(basePred * seasonalFactor * trendFactor);
  }

  // 计算推荐补货量
  calculateReorderQuantity(productId) {
    const currentStock = this.getCurrentStock(productId);
    const safetyStock = this.getSafetyStock(productId); // 安全库存
    const leadTime = this.getSupplierLeadTime(productId); // 供货周期

    // 预测补货周期内的销量
    let predictedDemand = 0;
    for (let i = 1; i <= leadTime; i++) {
      const futureDate = new Date();
      futureDate.setDate(futureDate.getDate() + i);
      predictedDemand += this.predictSales(productId, futureDate);
    }

    // 补货量 = 安全库存 + 预测需求 - 当前库存
    const reorderQty = safetyStock + predictedDemand - currentStock;

    return Math.max(0, Math.ceil(reorderQty));
  }

  // 获取季节性因子
  getSeasonalFactor(productId, month) {
    // 从历史数据计算月度销售占比
    const monthlySales = this.getMonthlySales(productId);
    const totalSales = monthlySales.reduce((sum, m) => sum + m.quantity, 0);

    if (totalSales === 0) return 1;

    const monthSales = monthlySales.find(m => m.month === month);
    return monthSales ? monthSales.quantity / (totalSales / 12) : 1;
  }
}

实时推荐服务

提供API接口供各端调用:

// 推荐API服务
router.get('/api/recommendations', async (ctx) => {
  const userId = ctx.query.userId;
  const type = ctx.query.type || 'personalized';
  const limit = parseInt(ctx.query.limit) || 10;

  let recommendations = [];

  switch (type) {
    case 'personalized':
      // 个性化推荐
      recommendations = await recommender.getPersonalizedRecommendations(
        userId, limit
      );
      break;

    case 'popular':
      // 热销推荐
      recommendations = await recommender.getPopularProducts(limit);
      break;

    case 'similar':
      // 商品相似推荐
      const productId = ctx.query.productId;
      recommendations = await recommender.getSimilarProducts(
        productId, limit
      );
      break;

    case 'frequently_bought':
      // 经常一起购买
      const targetProductId = ctx.query.productId;
      recommendations = await recommender.getFrequentlyBoughtTogether(
        targetProductId
      );
      break;

    case 'replenishment':
      // 补货推荐(管理员)
      if (!await checkAdminPermission(ctx)) {
        ctx.status = 403;
        return;
      }
      recommendations = await replenishmentRecommender.getReplenishmentList();
      break;
  }

  ctx.body = {
    success: true,
    data: recommendations,
    type,
    generatedAt: new Date().toISOString()
  };
});

效果评估与优化

推荐系统需要持续评估和优化:

指标 说明 目标
点击率(CTR) 推荐商品被点击的比例 >15%
转化率 点击后购买的比例 >8%
客单价 使用推荐后的平均订单金额 提升10%+
覆盖率 被推荐到的商品比例 >60%

总结

进销存系统的智能推荐功能可以显著提升销售效率和客户体验。通过协同过滤、关联规则和智能补货等算法,为企业提供精准的商品推荐和库存优化建议。

← 下一篇:进销存系统采购询价与比价管理 上篇:进销存系统数据挖掘与客户价值分析 →