[机器学习] 模型融合GBDT(xgb/lgbm/rf)+LR 的原理及实践

article/2025/9/23 12:20:18

目录

一、原理

GBDT + LR 是什么,用在哪

二、说明

 GBDT + LR 的结构

RF + LR ? Xgb + LR?

GBDT + LR 模型提升

三、实践

1 如何获得样本落在哪个叶子节点

2 举例

2.2.1 训练集准备

2.2.2 RF+LR

2.2.3 GBDT+LR

2.2.4 Xgboost+LR

2.2.5 单独使用RF, GBDT和Xgboost

2.2.6 结果对比

三、为什么Xgboost+LR的融合效果没有想象中那么好

参考资料


 

 

一、原理

为什么要使用LR模型进行融合呢?这是因为LR (逻辑回归) 算法简单有效,成为工业界最常用的算法之一。但 LR 算法是线性模型,不能捕捉到非线性信息,需要大量特征工程找到特征组合。为了发现有效的特征组合,Facebook 在 2014年的论文ractical Lessons from Predicting Clicks on Ads at Facebook介绍了通过 GBDT (Gradient Boost Decision Tree)+ LR 的方案 (XGBoost 是 GBDT 的后续发展)。在这篇论文中他们提出了一种将Xgboost作为feature transform的方法。随后在多个Kaggle 竞赛实践中,均证明了此思路的有效性。

GBDT构造组合特征的方式

利用GBDT进行特征构造依据其模型组合方式一共有两种方式:

  1. GBDT + LR

    与原论文的实现方式一样,利用GBDT构造组合特征,再将组合特征进行one-hot编码(本实践代码也属此类);

  2. GBDT + FFM 或者 GBDT + 树模型

    此时,使用利用GBDT构造的组合特征不再进行one-hot编码,而是直接利用输出叶节点的索引信息,如果将GBDT组合特征输出到其他树模型,则可直接利用节点索引信息;若是将GBDT信息输出到FFM中,依旧是利用索引信息,但是需要将索引信息组织成FFM数据输入形式。

大概的思想可以描述为如下:先用已有特征训练Xgboost模型,然后利用Xgboost模型学习到的树来构造新特征,最后把这些新特征加入原有特征一起训练模型。构造的新特征向量是取值0/1的,向量的每个元素对应于Xgboost模型中树的叶子结点。当一个样本点通过某棵树最终落在这棵树的一个叶子结点上,那么在新特征向量中这个叶子结点对应的元素值为1,而这棵树的其他叶子结点对应的元素值为0。新特征向量的长度等于XGBoost模型里所有树包含的叶子结点数之和。最后将新的特征扔到LR模型进行训练。

GBDT + LR 是什么,用在哪

本质上GBDT+LR是一种具有stacking思想的二分类器模型,所以可以用来解决二分类问题。这个方法出自于Facebook 2014年的论文 Practical Lessons from Predicting Clicks on Ads at Facebook 。

GBDT+LR 使用最广泛的场景是CTR点击率预估,即预测当给用户推送的广告会不会被用户点击。

点击率预估模型涉及的训练样本一般是上亿级别,样本量大,模型常采用速度较快的LR。但LR是线性模型,学习能力有限,此时特征工程尤其重要。现有的特征工程实验,主要集中在寻找到有区分度的特征、特征组合,折腾一圈未必会带来效果提升。GBDT算法的特点正好可以用来发掘有区分度的特征、特征组合,减少特征工程中人力成本。

 

 

二、说明

 

 GBDT + LR 的结构

1)为什么要使用集成的决策树模型,而不是单棵的决策树模型:一棵树的表达能力很弱,不足以表达多个有区分性的特征组合,多棵树的表达能力更强一些。可以更好的发现有效的特征和特征组合
2)为什么建树采用GBDT而非RF:RF也是多棵树,但从效果上有实践证明不如GBDT。且GBDT前面的树,特征分裂主要体现对多数样本有区分度的特征;后面的树,主要体现的是经过前N颗树,残差仍然较大的少数样本。优先选用在整体上有区分度的特征,再选用针对少数样本有区分度的特征,思路更加合理,这应该也是用GBDT的原因。

GBDT+LR 由两部分组成,其中GBDT用来对训练集提取特征作为新的训练输入数据,LR作为新训练输入数据的分类器。

具体来讲,有以下几个步骤:

1 GBDT首先对原始训练数据做训练,得到一个二分类器,当然这里也需要利用网格搜索寻找最佳参数组合。

2 与通常做法不同的是,当GBDT训练好做预测的时候,输出的并不是最终的二分类概率值,而是要把模型中的每棵树计算得到的预测概率值所属的叶子结点位置记为1,这样,就构造出了新的训练数据。

举个例子,下图是一个GBDT+LR 模型结构,设GBDT有两个弱分类器,分别以蓝色和红色部分表示,其中蓝色弱分类器的叶子结点个数为3,红色弱分类器的叶子结点个数为2,并且蓝色弱分类器中对0-1 的预测结果落到了第二个叶子结点上,红色弱分类器中对0-1 的预测结果也落到了第二个叶子结点上。那么我们就记蓝色弱分类器的预测结果为[0 1 0],红色弱分类器的预测结果为[0 1],综合起来看,GBDT的输出为这些弱分类器的组合[0 1 0 0 1] ,或者一个稀疏向量(数组)。

这里的思想与One-hot独热编码类似,事实上,在用GBDT构造新的训练数据时,采用的也正是One-hot方法。并且由于每一弱分类器有且只有一个叶子节点输出预测结果,所以在一个具有n个弱分类器、共计m个叶子结点的GBDT中,每一条训练数据都会被转换为1*m维稀疏向量,且有n个元素为1,其余m-n 个元素全为0。

3.3 新的训练数据构造完成后,下一步就要与原始的训练数据中的label(输出)数据一并输入到Logistic Regression分类器中进行最终分类器的训练。思考一下,在对原始数据进行GBDT提取为新的数据这一操作之后,数据不仅变得稀疏,而且由于弱分类器个数,叶子结点个数的影响,可能会导致新的训练数据特征维度过大的问题,因此,在Logistic Regression这一层中,可使用正则化来减少过拟合的风险,在Facebook的论文中采用的是L1正则化。

 

RF + LR ? Xgb + LR?

有心的同学应该会思考一个问题,既然GBDT可以做新训练样本的构造,那么其它基于树的模型,例如Random Forest以及Xgboost等是并不是也可以按类似的方式来构造新的训练样本呢?没错,所有这些基于树的模型都可以和Logistic Regression分类器组合。至于效果孰优孰劣,我个人觉得效果都还可以,但是之间没有可比性,因为超参数的不同会对模型评估产生较大的影响。下图是RF+LR、GBT+LR、Xgb、LR、Xgb+LR 模型效果对比图,然而这只能做个参考,因为模型超参数的值的选择这一前提条件都各不相同。

顺便来讲,RF也是多棵树,但从效果上有实践证明不如GBDT。且GBDT前面的树,特征分裂主要体现对多数样本有区分度的特征;后面的树,主要体现的是经过前N颗树,残差仍然较大的少数样本。优先选用在整体上有区分度的特征,再选用针对少数样本有区分度的特征,思路更加合理,这应该也是用GBDT的原因。

 

 

 

GBDT + LR 模型提升

现在,我们思考这样一个问题,Logistic Regression是一个线性分类器,也就是说会忽略掉特征与特征之间的关联信息,那么是否可以采用构建新的交叉特征这一特征组合方式从而提高模型的效果?

其次,我们已经在2.3小节中了解到GBDT很有可能构造出的新训练数据是高维的稀疏矩阵,而Logistic Regression使用高维稀疏矩阵进行训练,会直接导致计算量过大,特征权值更新缓慢的问题。

针对上面可能出现的问题,可以翻看我之前的文章:FM算法解析及Python实现 ,使用FM算法代替LR,这样就解决了Logistic Regression的模型表达效果及高维稀疏矩阵的训练开销较大的问题。然而,这样就意味着可以高枕无忧了吗?当然不是,因为采用FM对本来已经是高维稀疏矩阵做完特征交叉后,新的特征维度会更加多,并且由于元素非0即1,新的特征数据可能也会更加稀疏,那么怎么办?

所以,我们需要再次回到GBDT构造新训练数据这里。当GBDT构造完新的训练样本后,我们要做的是对每一个特征做与输出之间的特征重要度评估并筛选出重要程度较高的部分特征,这样,GBDT构造的高维的稀疏矩阵就会减少一部分特征,也就是说得到的稀疏矩阵不再那么高维了。之后,对这些筛选后得到的重要度较高的特征再做FM算法构造交叉项,进而引入非线性特征,继而完成最终分类器的训练数据的构造及模型的训练。

 

三、实践


1 如何获得样本落在哪个叶子节点

在实践中的关键点是如何获得每个样本落在训练后的每棵树的哪个叶子结点上。

A、对于xgb/lgbm来说,因为其有sklearn接口和自带接口,因此有两种方法可以获得:

①、sklearn接口。可以设置pre_leaf=True获得每个样本在每颗树上的leaf_Index。(lgbm使用)

②、自带接口。利用apply()方法可以获得leaf indices。(xgb使用)

此过程需注意: 无论是设置pre_leaf=True还是利用apply()方法,获得的都是叶子节点的 index,也就是说落在了具体哪颗树的哪个叶子节点上,并非是0/1变量,因此需要自己动手去做 onehot 编码。onehot 可以在 sklearn 的预处理包中调用即可。

B、对于其它的树模型,如随机森林和GBDT,我们只能使用apply()方法获得leaf indices。


2 举例

接下来,我们举例来说明如何利用树模型,尤其是Xgboost来构建新特征,并且是如何与LR模型进行融合。

    params = {"tree_method": "hist", "n_jobs": 4, "n_estimators":50}xgb = XGBClassifier(**params)xgb.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='auc')print("With XGB Pred")y_train_pred_proba = xgb.predict_proba(X_train)print_eval_metric(y_train, y_train_pred_proba[:, 1])y_test_pred_proba = xgb.predict_proba(X_test)print_eval_metric(y_test, y_test_pred_proba[:, 1])print("---------------")from sklearn.linear_model import LogisticRegressiononehot = OneHotEncoder()X_train_leaves = onehot.fit_transform(xgb.apply(X_train))xgb_lr = LogisticRegression()xgb_lr.fit(X_train_leaves, y_train)print("With XGB + LR Pred")X_train_leaves = onehot.transform(xgb.apply(X_train))y_train_pred_xgb_lr = xgb_lr.predict_proba((X_train_leaves))[:, 1]print_eval_metric(y_train, y_train_pred_xgb_lr)X_test_leaves = onehot.transform(xgb.apply(X_test))y_test_pred_xgb_org_lr = xgb_lr.predict_proba(X_test_leaves)[:, 1]print_eval_metric(y_test, y_test_pred_xgb_org_lr)
XGB (train/test)XGB+ LR (train/test)

观察leaves的形状

In[181]:  y_pred_leaves.shape
Out[181]: (8000, 100)

共有8000个样本,100棵树(在上面的参数中 num_trees=100),观察第 1 个样本y_pred_train[0]的前10个值:

In[182]:  y_pred_leaves[0][:10]
Out[182]: array([31, 29, 29, 32, 38, 46, 35, 36, 36, 42])

其中 第一个数 31 表示这个样本落到了第一颗树的 31 叶子节点,29 表示落到了第二棵树的 29 叶子节点,注意31 、29表示节点编号,从0开始到63

 

LGBM 例子代码

    params = {"n_jobs": 4, "n_estimators": 50,  "max_depth": 3}lgbm = LGBMClassifier(**params)lgbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='auc')y_test_pred_proba = lgbm.predict_proba(X_test)print_eval_metric(y_test, y_test_pred_proba[:, 1])print("---------------")from sklearn.linear_model import LogisticRegressiononehot = OneHotEncoder()X_train_leaves = onehot.fit_transform(lgbm.predict(X_train, pred_leaf=True))lgbm_lr = LogisticRegression()lgbm_lr.fit(X_train_leaves, y_train)X_test_leaves = onehot.transform(lgbm.predict(X_test, pred_leaf=True))y_test_pred_lgbm_org_lr = lgbm_lr.predict_proba(X_test_leaves)[:, 1]

 

2.2.1 训练集准备

从代码中,可以看到,我们对训练集X_train又进行了一次切分,生成了训练集X_train, X_train_lr和测试集y_train, y_train_lr。特别要注意数据集的大小,后续我们会进行分析。

注意:我们设定了n_estimator = 10,这意味着树模型中只有10颗树。

import numpy as np
np.random.seed(10)import matplotlib.pyplot as plt
import xgboost as xgbfrom sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import ( RandomForestClassifier,GradientBoostingClassifier)
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve,  roc_auc_score
from scipy.sparse import hstackX, y = make_classification(n_samples=80000)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)# It is important to train the ensemble of trees on a different subset
# of the training data than the linear regression model to avoid
# overfitting, in particular if the total number of leaves is
# similar to the number of training samples
X_train, X_train_lr, y_train, y_train_lr = train_test_split(X_train, y_train, test_size=0.5)n_estimator = 10'''
X_train为20000*20
X_train_lr为20000*20
y_train为20000*1
y_train_lr为20000*1
y_test 为40000*1
'''

2.2.2 RF+LR

我们首先使用随机森林进行实验。这里我们需要对代码进行一个解读。

 

    # Supervised transformation based on random forestsrf = RandomForestClassifier(max_depth=3, n_estimators=n_estimator)rf_enc = OneHotEncoder()rf_lm = LogisticRegression(solver='lbfgs', max_iter=1000)# 使用随机森林进行训练rf.fit(X_train, y_train)'''rf.apply(X_train)的大小为20000*10,10就是10颗树。rf.apply(X_train)的元素代表了哪一个样本落在了哪一个树的第几个叶子节点上,如32,就代表了落在了一棵树的第32个叶子节点上。rf_enc.fit(rf.apply(X_train))对rf.apply(X_train)进行了onehot编码'''rf_enc.fit(rf.apply(X_train))'''rf_enc.transform(rf.apply(X_train_lr))按照rf.apply(X_train)的编码方式对rf.apply(X_train_lr)进行了onehot编码。这里需要注意得是:我们并没有像常规方式那样对rf.apply(X_train)和rf.apply(X_train_lr)先进行合并再进行onehot,这是因为在训练完成之后随机森林的树模型已经固定,即叶子节点的架构已经确定。因此rf.apply(X_train_lr)的值的范围和rf.apply(X_train)的值的范围必然一样!rf_lm.fit(rf_enc.transform(rf.apply(X_train_lr)), y_train_lr)使用随机森林构造的特征来训练LR'''rf_lm.fit(rf_enc.transform(rf.apply(X_train_lr)), y_train_lr)y_pred_rf_lm = rf_lm.predict_proba(rf_enc.transform(rf.apply(X_test)))[:, 1]fpr_rf_lm, tpr_rf_lm, _ = roc_curve(y_test, y_pred_rf_lm)print("RF+LR的AUC为:", roc_auc_score(y_test, y_pred_rf_lm))

2.2.3 GBDT+LR

我们其次使用随机森林进行实验。其代码与随机森林几乎一样。不再进行代码解读。

# Supervised transformation based on gradient boosted trees
grd = GradientBoostingClassifier(n_estimators=n_estimator)
grd_enc = OneHotEncoder()
grd_lm = LogisticRegression(solver='lbfgs', max_iter=1000)grd.fit(X_train, y_train)
grd_enc.fit(grd.apply(X_train)[:, :, 0])
grd_lm.fit(grd_enc.transform(grd.apply(X_train_lr)[:, :, 0]), y_train_lr)y_pred_grd_lm = grd_lm.predict_proba(grd_enc.transform(grd.apply(X_test)[:, :, 0]))[:, 1]
fpr_grd_lm, tpr_grd_lm, _ = roc_curve(y_test, y_pred_grd_lm)
print("GBT+LR的AUC为:", roc_auc_score(y_test, y_pred_grd_lm))

2.2.4 Xgboost+LR

我们使用Xgboost进行实验。

# Supervised transformation based on xgboost
xgb = xgb.XGBClassifier(nthread=4,     #含义:nthread=-1时,使用全部CPU进行并行运算(默认), nthread=1时,使用1个CPU进行运算。learning_rate=0.08,    #含义:学习率,控制每次迭代更新权重时的步长,默认0.3。调参:值越小,训练越慢。典型值为0.01-0.2。n_estimators=50,       #含义:总共迭代的次数,即决策树的个数max_depth=5,           #含义:树的深度,默认值为6,典型值3-10。调参:值越大,越容易过拟合;值越小,越容易欠拟合gamma=0,               #含义:惩罚项系数,指定节点分裂所需的最小损失函数下降值。subsample=0.9,       #含义:训练每棵树时,使用的数据占全部训练集的比例。默认值为1,典型值为0.5-1。调参:防止overfitting。colsample_bytree=0.5) #训练每棵树时,使用的特征占全部特征的比例。默认值为1,典型值为0.5-1。调参:防止overfitting。xgb_enc = OneHotEncoder()
xgb_lm = LogisticRegression(solver='lbfgs', max_iter=1000)xgb.fit(X_train, y_train)
xgb_enc.fit(xgb.apply(X_train))
xgb_lm.fit(xgb_enc.transform(xgb.apply(X_train_lr)), y_train_lr)y_pred_xgb_lm = xgb_lm.predict_proba(xgb_enc.transform(xgb.apply(X_test)))[:, 1]
fpr_xgb_lm, tpr_xgb_lm, _ = roc_curve(y_test, y_pred_xgb_lm)
print("xgboost+LR的AUC为:", roc_auc_score(y_test, y_pred_xgb_lm))

在之前的代码中,我们只是用树模型构造的新特征来训练LR。

接下来,我们更近一步,将新特征与原始的20个特征进行拼接形成新的数据集来训练LR。

X_train_ext = hstack([xgb_enc.transform(xgb.apply(X_train_lr)), X_train_lr])
X_test_ext = hstack([xgb_enc.transform(xgb.apply(X_test)), X_test])
xgb_lm.fit(X_train_ext, y_train_lr)y_pred_xgb_originalfeature_lm = xgb_lm.predict_proba(X_test_ext)[:, 1]
fpr_xgb_originalfeature_lm, tpr_xgb_originalfeature_lm, _ = roc_curve(y_test, y_pred_xgb_originalfeature_lm)
print("xgboost新特征与原始特征+LR的AUC为:", roc_auc_score(y_test, y_pred_xgb_originalfeature_lm))

 

2.2.5 单独使用RF, GBDT和Xgboost

为了进行对比,我们也输出单独使用RF,GBDT和Xgboost的结果。

# The gradient boosted model by itself
y_pred_grd = grd.predict_proba(X_test)[:, 1]
fpr_grd, tpr_grd, _ = roc_curve(y_test, y_pred_grd)
print("GBT的AUC为:", roc_auc_score(y_test, y_pred_grd))# The random forest model by itself
y_pred_rf = rf.predict_proba(X_test)[:, 1]
fpr_rf, tpr_rf, _ = roc_curve(y_test, y_pred_rf)
print("RF的AUC为:", roc_auc_score(y_test, y_pred_rf))# The xgboost model by itself
xgb.fit(X_train, y_train)
y_pred_xgb = xgb.predict_proba(X_test)[:, 1]
fpr_xgb, tpr_xgb, _ = roc_curve(y_test, y_pred_xgb)
print('xgboost的AUC为:' , roc_auc_score(y_test, y_pred_xgb))

2.2.6 结果对比

我们运行整个代码,结果为:

   RF+LR的AUC为: 0.972532755993GBT+LR的AUC为: 0.984711442675xgboost+LR的AUC为: 0.992587688381xgboost新特征与原始特征+LR的AUC为: 0.992632312284GBT的AUC为: 0.98220013158RF的AUC为: 0.965762807823xgboost的AUC为: 0.99284427301

对于RF和GBT,与LR进行融合后的结果要比单独使用RF和GBT要好。

而对于Xgboost,单独使用Xgboost效果最好,其次是xgboost新特征与原始特征+LR,最后才是xgboost+LR。

这与我们预期不符。为什么会出现这样的结果,值得我们讨论。

画图来进一步看下ROC曲线:
  

plt.figure(1)
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr_rf, tpr_rf, label='RF')
plt.plot(fpr_rf_lm, tpr_rf_lm, label='RF + LR')
plt.plot(fpr_grd, tpr_grd, label='GBT')
plt.plot(fpr_grd_lm, tpr_grd_lm, label='GBT + LR')
plt.plot(fpr_xgb, tpr_xgb, label='XGB')
plt.plot(fpr_xgb_lm, tpr_xgb_lm, label='XGB + LR')
plt.plot(fpr_xgb_originalfeature_lm, tpr_xgb_originalfeature_lm, label='XGB + ori_fea+ LR')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC curve')
plt.legend(loc='best')
plt.show()plt.figure(2)
plt.xlim(0, 0.2)
plt.ylim(0.8, 1)
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr_rf, tpr_rf, label='RF')
plt.plot(fpr_rf_lm, tpr_rf_lm, label='RF + LR')
plt.plot(fpr_grd, tpr_grd, label='GBT')
plt.plot(fpr_grd_lm, tpr_grd_lm, label='GBT + LR')
plt.plot(fpr_xgb, tpr_xgb, label='XGB')
plt.plot(fpr_xgb_lm, tpr_xgb_lm, label='XGB + LR')
plt.plot(fpr_xgb_originalfeature_lm, tpr_xgb_originalfeature_lm, label='XGB + ori_fea + LR')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC curve (zoomed in at top left)')
plt.legend(loc='best')
plt.show()
  1. plt.show()

左边的图为ROC曲线,右边的图是对ROC曲线左上角进行了放大。


三、为什么Xgboost+LR的融合效果没有想象中那么好

仅使用Xgboost的结果反而最好。这是为什么呢?

1. 当xgb模型本来拟合就比较好之后,xgb+lr 效果不一定会更好

2.当训练样本不够时,xgb+lr 效果反而容易变差

 

 

参考资料

[1] CTR预估中GBDT与LR融合方案

[2] 常见计算广告点击率预估算法总结

[3] GBDT+LR算法进行特征扩增

[4] 推荐系统遇上深度学习(十)--GBDT+LR融合方案实战


http://chatgpt.dhexx.cn/article/uhEvtN2u.shtml

相关文章

xgboost 与 lgbm

相关性分析模型可行性报告 基于数值的模型-xgboost 简介 XGBoost是一个优化的分布式梯度提升库,旨在高效,灵活和便携。它在梯度提升框架下实现机器学习算法。XGBoost提供了一个并行树提升(也称为GBDT,GBM)&#xff…

一文彻底看懂LightGBM

本文适合有集成学习与XGBoost基础的读者了解LightGBM算法。 序 LightGBM是基于XGBoost的改进版,在处理样本量大、特征纬度高的数据时,XGBoost效率和可扩展性也不够理想,因为其在对树节点分裂时,需要扫描每一个特征的每一个特征值…

LGBM算法

LGBM 算法定义算法实践其他 算法概念 Light GBM is a gradient boosting framework that uses tree based learning algorithm。 传统的GBDT算法存在的问题: 如何减少训练数据 常用的减少训练数据量的方式是down sample。例如在[5]中,权重小于阈值的…

LGBM调参方法学习

一、了解LGBM参数: LGBM是微软发布的轻量梯度提升机,最主要的特点是快,回归和分类树模型。使用LGBM首先需要查看其参数含义: 微软官方github上的说明: https://github.com/Microsoft/LightGBM/blob/master/docs/Param…

使用线性回归、LGBM对二手车价格进行预测

使用线性回归、LGBM对二手车价格进行预测 目录 使用线性回归、LGBM对二手车价格进行预测说明 数据导入、查看和清洗数据说明导入训练集导入测试集合并数据查看数据整体情况处理数据检查并处理缺失变量 EDA年份和价格地区和价格前任里程和价格燃料类型和价格传动装置类型Mileage…

MFC VS2010 Open CASCADE新建自己的工程

最近磕磕绊绊的去尝试用open cascade建立自己需要的工程文件,终于成功了,一直从网上获取方法,今天自己写一点心得,分享给大家。 一、准备: 1、安装 open cascade , 我安装后目录是: C:\OpenCAS…

[C++] OpenCasCade空间几何库的模型展现

OpenCasCade是什么 Open CASCADE(简称OCC)平台是由法国Matra Datavision公司开发的CAD/CAE/CAM软件平台,可以说是世界上最重要的几何造型基础软件平台之一。开源OCC对象库是一个面向对象C类库,用于快速开发设计领域的专业应用程序…

MFC中使用OpenCasCade示例

目录: 一、OpenCasCade开发环境搭建 二、创建一个MFC应用程序 三、在MFC工程中添加代码 四、画个瓶子 一、OpenCasCade开发环境搭建 参见《OpenCasCade开发环境搭建》,这篇文章最后运行示例前所做的工作为以后开发OpenCasCade工程铺平了路&#xff…

HTML<HBuilder X>

一&#xff1a;网页基本标签元素 HTML常用标签(HTML不是一种编程语言&#xff0c;而是一种标记语言&#xff09;&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>文档标题</title> </head><…

Opencascade 开发 1章

序 这一系列的文章旨在介绍一个方便大家开始开发自己CAD的方法。需要指出的是&#xff0c;本人主要希望通过分享一些相关技术&#xff0c;提升国人软件自主的意识和途径。通过本文构建自己的CAD只是软件自主化的非常非常小的一步&#xff0c;希望大家在不停尝试的过程中有所提…

【OCC学习5】记录最新版本emcc编译occ的bug:opencascade-7.6.0/src/Standard/Standard_Time.hxx:29:25: error: redefinit

1. 在研究OCC与Webassembly结合使用&#xff0c;编译的时候遇到以下问题&#xff1a; C:/workspace/occ_wasm/opencascade-7.6.0/src/Standard/Standard_Integer.hxx:126:25: note: previous definition is here inline Standard_Boolean IsEqual (const Standard_Integer the…

NX二次开发CreateDialog函数在UI.hxx文件和WinUser.h中的冲突

NX二次开发CreateDialog函数在UI.hxx文件和WinUser.h中的冲突 在UG二次开发中&#xff0c;若使用MFC库&#xff0c;一旦加上#include<Afx.h>头文件&#xff0c;或者使用<windows.h>头文件下面这句话就报错 theDialog GetPoints::theUI->CreateDialog(theDlxF…

HLO--XLA

HLO: high level optimizer 高级优化器 XLA&#xff1a; XLA(Accelerated Linear Algebra)-加速线性代数&#xff0c;Google推出的高性能机器学习领域编译器&#xff08;编译型推理引擎&#xff09;&#xff0c;它可以在不更改源代码的条件下加速Tensorflow模型 提高TensorFlo…

C++:C++编译过程:看完还不懂C++编译过程来捶我

1&#xff1a;先看图 2&#xff1a;一个C源文件从文本到可执行文件经历的过程&#xff1a; gcc Hello.cpp 预处理阶段&#xff1a;gcc -E hello.c -o hello.i 对源代码文件中包含关系&#xff08;头文件&#xff09;&#xff0c;预编译语句&#xff08;宏定义&#xff09…

h计算机软件指什么,HXX 文件扩展名: 它是什么以及如何打开它?

解决难以打开 HXX 文件的问题 打开 HXX 文件过程中所遇到的常见问题 MacroMates TextMate 消失 尝试打开 HXX 时&#xff0c;你会遇到一条错误消息&#xff0c;例如 “%%os%% 无法打开 HXX 文件”。 如果是这种情况&#xff0c;通常是因为 你的计算机上没有安装 MacroMates Tex…

神器octotree

在Github上查看源代码的体验十分糟糕&#xff0c;尤其是从一个目录跳转到另一个目录的时候&#xff0c;非常麻烦。 直到遇到这款神器&#xff0c;相见恨晚&#xff01;&#xff01; 具体安装及使用步骤参考&#xff1a; https://www.cnblogs.com/12yang-ting/p/7485264.html …

有用的Chrome扩展介绍 - Octotree - GitHub code tree

明细&#xff1a; 安装之后&#xff0c;Github网站左边会自动出现类似Visual Studio Code的代码显示方式&#xff0c;可以通过树形结构方便地浏览代码&#xff0c;无需重复点击文件夹进入。 树形结构里的图标可以使用各种不同的风格显示&#xff1a; 快捷键&#xff1a;上箭头…

Octotree在GitHub中出错(已解决)

谷歌插件真的是很方便&#xff0c;像Octotree让我们github中的项目浏览起来更加条理&#xff0c;如图 但是当我在github中频繁的切换文件夹的时候&#xff0c;Outotree开始报错&#xff0c;也不显示目录结构&#xff0c;将错误代码放到谷歌翻译如下。 我理解的意思是github需…

Octotree在GitHub中出错

使用octotree 出现Error: Connection error octotree解决办法 解决方法&#xff1a;需要在github设置访问token 登录github&#xff0c;打开https://github.com/settings/profile 依次点击 Settings -> Developer settings -> Personal access tokens -> Generate n…