如何理解关联法则中的三个判断准则

本文深入解析了关联规则分析中的三个核心指标:support、confidence及lift,并通过实例展示了这些指标如何帮助我们理解商品间的关联性。此外,还探讨了关联规则分析的优点与局限。

关联法则中,我们最常用到的无外乎是三种判断的准则:support,confidence和lift。

先给出三个判断标准的公式:

1.support(A)= number of A/total items

   support(B)= number of B/total items

   support(A=>B)= support(B=>A)= number of A and B/total items

2.confidence(A=>B)= number of A and B/number of A

   confidence(A=>B)!=  confidence(B=>A)

3.lift(A=>B)= confidence(A=>B)/support(B)

   lift(A=>B)= lift(B=>A)

对三个准则的解释:

support很简单,就是单一商品或者rule出现的概率。我们认为某条规则(rule)出现的次数需要达到一定程度,才能认为这条规则有足够的支持度来支撑其是真实存在的,而不仅仅是因为偶然出现了几次就认为这是一条普遍存在的规则。support是第一道过滤的准则,能够在繁杂众多的交易中过滤出值得我们关注的潜在规则。

confidence我们认为代表着“给定consequent的情况下,antecedent出现的概率”,也就是说是判断规则中两边存在的联系。confidence越高越好,一个高的confidence证明当交易出现了某个antecedent的时候,很大可能会出现某个consequent,也就是某条规则成立的概率越大。

lift融合了support和confidence,代表一条规则中,antecedent和consequent的依赖性,当lift=1的时候,代表给定一个antecedent,某个consequent出现的概率是随机的,也就是说antecedent和consequent相互独立,两者没有任何依赖性,规则不成立。当lift<1的时候,证明antecedent和consequent之间可能存在负依赖性,两者同时存在的概率甚至小于随机选择,若果lift大大小于1,有可能两者是替代商品。当lift>1的时候,则代表两者可能存在正依赖性,顾客买antecedent的时候更倾向于同时购买consequent。

举一个例子似乎更容易说明问题:

假设有两个商品A和B,商品A的support是40%,商品B的support是95%,表明40%的交易里面存在A,95%的交易里面存在B,注意,A和B之间在这里仅仅代表自己,40%和95%这两个数值并不代表他们之间存在联系。假如confidence(A=>B)=80%,表明如果顾客购买了A,有80%的顾客同时有购买了B。又假设support(A=>B)足够高,这似乎看起来support和confidence都很高的情况下,A=>B这条规则是很有可能成立的。然而lift只有confidence(A=>B)/support(B)= 80% / 95% =0.8421,也就是说lift不太支持这条规则成立,因为顾客普遍都会买B,导致了support和confidence都偏高而lift则不高。


PS:上述例子的数据没有在乎细节^_^(例如,上面的support(A)=40%,confidence(A=>B)=80%,那么support(A=>B)就会是320%^_^,所以不要在乎细节)


总结关联法则的优劣点:

优点:1.结果一般清晰易懂

   2.规则容易转化成实际操作

缺点:1.如果数据量很大,需要很大的计算量

   2.很多得出的规则都是显而易见的,要不就是不能解释的

<think>好的,我需要详细分析用户的问题,并结合提供的引用内容来回答关于C++中的法则和五法则。用户之前询问了如何强制生成默认构造函数,现在他们想了解三/五法则,涉及默认构造函数、析构函数、拷贝构造、拷贝赋值、移动构造、移动赋值等。 首先,回顾之前的回答,我已经提到过三/五法则与`=default`的关系,现在需要深入展开。根据提供的引用,特别是引用[2]和[4],三法则主要涉及析构函数、拷贝构造函数、拷贝赋值运算符,而五法则加入了移动构造和移动赋值。这些法则的核心在于资源管理,特别是当类包含指针成员时,需要手动管理这些资源以避免浅拷贝等问题。 接下来,需要明确三法则和五法则的定义、应用场景以及它们与默认构造函数的关系。例如,引用[2]提到,如果类有指针成员,通常需要定义析构函数、拷贝构造函数和拷贝赋值运算符,以正确管理资源。而五法则在C++11后引入移动语义,增加了移动构造函数和移动赋值运算符,以优化资源转移。 用户的问题还涉及默认构造函数,需要说明在遵循这些法则时,是否需要显式定义默认构造函数。例如,当用户声明了其他构造函数,编译器可能不会生成默认构造函数,这时如果需要默认构造,必须显式使用`=default`。 此外,引用[3]中的代码示例展示了各个函数的调用情况,可以引用来说明移动构造和移动赋值的使用场景。而引用[4]提到的RAII原则和三法则的关系,需要强调资源管理的重要性。 需要组织回答的结构,分点解释三法则、五法则,它们的用途,以及何时需要遵循这些法则。同时,结合用户之前的提问,说明如何通过`=default`和`=delete`来控制这些特殊成员函数的生成,以符合法则的要求。 最后,确保回答包含相关的问题,引导用户进一步学习,如如何实现移动语义、何时需要自定义析构函数等。同时,保持语言简洁,符合中文表达习惯,正确使用LaTeX格式,并引用提供的参考文献。</think>#### 一、C++ 三/五法则核心概念 三法则(Rule of Three)和五法则(Rule of Five)是 **资源管理类设计** 的核心准则,主要针对以下特殊成员函数: - **三法则**(C++98):析构函数、拷贝构造函数、拷贝赋值运算符 - **五法则**(C++11新增):移动构造函数、移动赋值运算符 适用场景:**类包含指针成员或管理外部资源**(如动态内存、文件句柄等)时,需手动定义这些函数以避免资源泄漏或浅拷贝问题[^2][^4]。 --- #### 二、三法则详解 **核心逻辑**:若需自定义以下任意一个函数,通常需同时定义其他两个: 1. **析构函数** 释放资源(如 `delete` 指针) ```cpp ~MyClass() { delete[] data_; } // 释放动态内存 ``` 2. **拷贝构造函数** 深拷贝资源 ```cpp MyClass(const MyClass& other) { data_ = new int[capacity_]; memcpy(data_, other.data_, sizeof(int)*capacity_); } ``` 3. **拷贝赋值运算符** 处理自我赋值并深拷贝 ```cpp MyClass& operator=(const MyClass& other) { if (this != &other) { // 防止自我赋值 delete[] data_; // 释放旧资源 data_ = new int[other.capacity_]; memcpy(data_, other.data_, sizeof(int)*capacity_); } return *this; } ``` **未遵循三法则的风险**: 默认生成的拷贝操作执行 **浅拷贝**,导致多个对象共享同一资源,可能引发双重释放(Double Free)或内存泄漏[^1]。 --- #### 三、五法则扩展(C++11+) **新增移动语义**:通过转移资源所有权提升性能: 4. **移动构造函数** 接管右值引用的资源 ```cpp MyClass(MyClass&& other) noexcept : data_(other.data_), capacity_(other.capacity_) { other.data_ = nullptr; // 置空源对象指针 } ``` 5. **移动赋值运算符** 转移资源并处理自我移动 ```cpp MyClass& operator=(MyClass&& other) noexcept { if (this != &other) { delete[] data_; // 释放当前资源 data_ = other.data_; // 接管资源 capacity_ = other.capacity_; other.data_ = nullptr; } return *this; } ``` **关键优势**: - 减少不必要的深拷贝(如返回临时对象时触发移动构造) - 支持高效资源转移(如 `std::vector` 扩容时使用移动而非拷贝) --- #### 四、默认构造函数的关联性 1. **自动生成条件** 若未声明 **任何构造函数**,编译器生成默认构造函数 (与三/五法则无关,但可能影响类初始化行为) 2. **与法则的协同** - 声明其他构造函数(如拷贝构造)会 **抑制默认构造** 的生成 - 需显式使用 `= default` 强制生成默认构造: ```cpp class Resource { public: Resource() = default; // 强制生成默认构造 Resource(const Resource&); // 拷贝构造 // 其他五法则函数... }; ``` --- #### 五、应用场景对比表 | 类型 | 三法则场景 | 五法则场景 | |-----------------------|-----------------------------------|-----------------------------------| | 资源管理需求 | 动态内存、文件句柄等 | 同左,且需优化大对象转移效率 | | 关键操作 | 深拷贝 | 移动语义 + 深拷贝 | | 性能特征 | 拷贝成本高 | 移动成本低(仅指针交换) | | 典型错误示例 | 默认浅拷贝导致双重释放 | 未定义移动操作导致不必要的深拷贝 | --- #### 六、代码示例(五法则完整实现) ```cpp class DynamicArray { public: // 默认构造 DynamicArray() = default; // 拷贝构造 DynamicArray(const DynamicArray& other) : size_(other.size_) { data_ = new int[size_]; std::copy(other.data_, other.data_ + size_, data_); } // 移动构造 DynamicArray(DynamicArray&& other) noexcept : data_(other.data_), size_(other.size_) { other.data_ = nullptr; other.size_ = 0; } // 拷贝赋值 DynamicArray& operator=(const DynamicArray& other) { if (this != &other) { delete[] data_; size_ = other.size_; data_ = new int[size_]; std::copy(other.data_, other.data_ + size_, data_); } return *this; } // 移动赋值 DynamicArray& operator=(DynamicArray&& other) noexcept { if (this != &other) { delete[] data_; data_ = other.data_; size_ = other.size_; other.data_ = nullptr; other.size_ = 0; } return *this; } // 析构 ~DynamicArray() { delete[] data_; } private: int* data_ = nullptr; size_t size_ = 0; }; ``` --- #### 七、设计决策指南 1. **不需要三/五法则的情况** - 类仅包含简单类型(如 `int`, `double`) - 类使用智能指针管理资源(如 `std::unique_ptr`) 2. **必须遵循三/五法则的情况** - 直接管理原始指针或外部资源 - 需要精确控制对象拷贝/移动行为(如线程安全容器) 3. **现代C++优化建议** - 优先使用移动语义替代深拷贝 - 用 `= default` 保留编译器优化空间 - 用 `= delete` 阻止不需要的操作(如禁用拷贝) --- --相关问题-- 1. 如何通过智能指针简化资源管理类的设计? 2. `noexcept` 关键字在移动操作中的作用是什么? 3. 什么时候应该禁用类的拷贝语义? 4. 移动语义如何提升STL容器的性能? [^1]: 引用自站内《C++拷贝构造函数、拷贝赋值函数与析构函数》 [^2]: 引用自站内《C++三/五法则详解》 [^4]: 引用自站内《C++五法则与RAII机制》
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值