零基础入门金融风控之贷款违约预测挑战赛——简单实现

news2025/4/14 19:41:00

零基础入门金融风控之贷款违约预测挑战赛

赛题理解

赛题以金融风控中的个人信贷为背景,要求选手根据贷款申请人的数据信息预测其是否有违约的可能,以此判断是否通过此项贷款,这是一个典型的分类问题。通过这道赛题来引导大家了解金融风控中的一些业务背景,解决实际问题,帮助竞赛新人进行自我练习、自我提高。

项目地址:https://github.com/datawhalechina/team-learning-data-mining/tree/master/FinancialRiskControl

比赛地址:https://tianchi.aliyun.com/competition/entrance/531830/introduction

数据形式

对于训练集数据来说,其中有特征如下:

  • id 为贷款清单分配的唯一信用证标识
  • loanAmnt 贷款金额
  • term 贷款期限(year)
  • interestRate 贷款利率
  • installment 分期付款金额
  • grade 贷款等级
  • subGrade 贷款等级之子级
  • employmentTitle 就业职称
  • employmentLength 就业年限(年)
  • homeOwnership 借款人在登记时提供的房屋所有权状况
  • annualIncome 年收入
  • verificationStatus 验证状态
  • issueDate 贷款发放的月份
  • purpose 借款人在贷款申请时的贷款用途类别
  • postCode 借款人在贷款申请中提供的邮政编码的前3位数字
  • regionCode 地区编码
  • dti 债务收入比
  • delinquency_2years 借款人过去2年信用档案中逾期30天以上的违约事件数
  • ficoRangeLow 借款人在贷款发放时的fico所属的下限范围
  • ficoRangeHigh 借款人在贷款发放时的fico所属的上限范围
  • openAcc 借款人信用档案中未结信用额度的数量
  • pubRec 贬损公共记录的数量
  • pubRecBankruptcies 公开记录清除的数量
  • revolBal 信贷周转余额合计
  • revolUtil 循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额
  • totalAcc 借款人信用档案中当前的信用额度总数
  • initialListStatus 贷款的初始列表状态
  • applicationType 表明贷款是个人申请还是与两个共同借款人的联合申请
  • earliesCreditLine 借款人最早报告的信用额度开立的月份
  • title 借款人提供的贷款名称
  • policyCode 公开可用的策略_代码=1新产品不公开可用的策略_代码=2
  • n系列匿名特征 匿名特征n0-n14,为一些贷款人行为计数特征的处理

还有一列为目标列isDefault代表是否违约。

预测指标

赛题要求采用AUC作为评价指标。

具体算法

导入相关库

import pandas as pd
import numpy as np
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score, roc_curve, mean_squared_error,mean_absolute_error, f1_score
import lightgbm as lgb
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor as rfr
from sklearn.linear_model import LinearRegression as lr
from sklearn.model_selection import  KFold, StratifiedKFold,GroupKFold, RepeatedKFold
import warnings
 
warnings.filterwarnings('ignore') #消除warning

读入数据

train_data = pd.read_csv("train.csv")
test_data = pd.read_csv("testA.csv")
print(train_data.shape)
print(test_data.shape)

(800000, 47)
(200000, 47)

数据处理

由于等下需要对特征进行变化,因此我先将训练集和测试集堆叠在一起,一起处理才方便,再加入一列作为区分即可。

target = train_data["isDefault"]
train_data["origin"] = "train"
test_data["origin"] = "test"
del train_data["isDefault"]

data = pd.concat([train_data, test_data], axis = 0, ignore_index = True)
data.shape

(1000000, 47)

那么接下来就是对data进行处理,可以先看看其大致的信息:

data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000000 entries, 0 to 999999
Data columns (total 47 columns):
 #   Column              Non-Null Count    Dtype  
---  ------              --------------    -----  
 0   id                  1000000 non-null  int64  
 1   loanAmnt            1000000 non-null  float64
 2   term                1000000 non-null  int64  
 3   interestRate        1000000 non-null  float64
 4   installment         1000000 non-null  float64
 5   grade               1000000 non-null  object 
 6   subGrade            1000000 non-null  object 
 7   employmentTitle     999999 non-null   float64
 8   employmentLength    941459 non-null   object 
 9   homeOwnership       1000000 non-null  int64  
 10  annualIncome        1000000 non-null  float64
 11  verificationStatus  1000000 non-null  int64  
 12  issueDate           1000000 non-null  object 
 13  purpose             1000000 non-null  int64  
 14  postCode            999999 non-null   float64
 15  regionCode          1000000 non-null  int64  
 16  dti                 999700 non-null   float64
 17  delinquency_2years  1000000 non-null  float64
 18  ficoRangeLow        1000000 non-null  float64
 19  ficoRangeHigh       1000000 non-null  float64
 20  openAcc             1000000 non-null  float64
 21  pubRec              1000000 non-null  float64
 22  pubRecBankruptcies  999479 non-null   float64
 23  revolBal            1000000 non-null  float64
 24  revolUtil           999342 non-null   float64
 25  totalAcc            1000000 non-null  float64
 26  initialListStatus   1000000 non-null  int64  
 27  applicationType     1000000 non-null  int64  
 28  earliesCreditLine   1000000 non-null  object 
 29  title               999999 non-null   float64
 30  policyCode          1000000 non-null  float64
 31  n0                  949619 non-null   float64
 32  n1                  949619 non-null   float64
 33  n2                  949619 non-null   float64
 34  n3                  949619 non-null   float64
 35  n4                  958367 non-null   float64
 36  n5                  949619 non-null   float64
 37  n6                  949619 non-null   float64
 38  n7                  949619 non-null   float64
 39  n8                  949618 non-null   float64
 40  n9                  949619 non-null   float64
 41  n10                 958367 non-null   float64
 42  n11                 912673 non-null   float64
 43  n12                 949619 non-null   float64
 44  n13                 949619 non-null   float64
 45  n14                 949619 non-null   float64
 46  origin              1000000 non-null  object 
dtypes: float64(33), int64(8), object(6)
memory usage: 358.6+ MB

最重要的是对缺失值和异常值的处理,那么来看看哪些特征的缺失值和异常值最多:

missing = data.isnull().sum() / len(data)
missing = missing[missing > 0 ]
missing.sort_values(inplace = True)
x = np.arange(len(missing))
fig, ax = plt.subplots()
ax.bar(x,missing)
ax.set_xticks(x)
ax.set_xticklabels(list(missing.index), rotation = 90, fontsize = "small")

异常值

可以发现那些匿名特征的异常值都是很多的,还有employmentLength特征的异常值也很多。后续会进行处理。

另外,还有很多特征并不是能够直接用来训练的特征,因此需要对其进行处理,比如grade、subGrade、employmentLength、issueDate、earliesCreditLine,需要进行预处理.

print(sorted(data['grade'].unique()))
print(sorted(data['subGrade'].unique()))
['A', 'B', 'C', 'D', 'E', 'F', 'G']
['A1', 'A2', 'A3', 'A4', 'A5', 'B1', 'B2', 'B3', 'B4', 'B5', 'C1', 'C2', 'C3', 'C4', 'C5', 'D1', 'D2', 'D3', 'D4', 'D5', 'E1', 'E2', 'E3', 'E4', 'E5', 'F1', 'F2', 'F3', 'F4', 'F5', 'G1', 'G2', 'G3', 'G4', 'G5']

那么现在先对employmentLength特征进行处理:

data['employmentLength'].value_counts(dropna=False).sort_index()
1 year        65671
10+ years    328525
2 years       90565
3 years       80163
4 years       59818
5 years       62645
6 years       46582
7 years       44230
8 years       45168
9 years       37866
< 1 year      80226
NaN           58541
Name: employmentLength, dtype: int64
# 对employmentLength该列进行处理
data["employmentLength"].replace(to_replace="10+ years", value = "10 years",
                                      inplace = True)
data["employmentLength"].replace(to_replace="< 1 year", value = "0 years",
                                      inplace = True)
def employmentLength_to_int(s):
    if pd.isnull(s):
        return s # 如果是nan还是nan
    else:
        return np.int8(s.split()[0])  # 按照空格分隔得到第一个字符
    
data["employmentLength"] = data["employmentLength"].apply(employmentLength_to_int)

转换后的效果为:

0.0      80226
1.0      65671
2.0      90565
3.0      80163
4.0      59818
5.0      62645
6.0      46582
7.0      44230
8.0      45168
9.0      37866
10.0    328525
NaN      58541
Name: employmentLength, dtype: int64

下面是对earliesCreditLine这个时间列进行处理:

data['earliesCreditLine'].sample(5)
375743    Jun-2003
361340    Jul-1999
716602    Aug-1995
893559    Oct-1982
221525    Nov-2004
Name: earliesCreditLine, dtype: object

为了简便起见,我们就只选取年份:

data["earliesCreditLine"] = data["earliesCreditLine"].apply(lambda x:int(x[-4:]))

效果为:

data['earliesCreditLine'].value_counts(dropna=False).sort_index()
1944        2
1945        1
1946        2
1949        1
1950        7
1951        9
1952        7
1953        6
1954        6
1955       10
1956       12
1957       18
1958       27
1959       52
1960       67
1961       67
1962      100
1963      147
1964      215
1965      301
1966      307
1967      470
1968      533
1969      717
1970      743
1971      796
1972     1207
1973     1381
1974     1510
1975     1780
1976     2304
1977     2959
1978     3589
1979     3675
1980     3481
1981     4254
1982     5731
1983     7448
1984     9144
1985    10010
1986    11415
1987    13216
1988    14721
1989    17727
1990    19513
1991    18335
1992    19825
1993    27881
1994    34118
1995    38128
1996    40652
1997    41540
1998    48544
1999    57442
2000    63205
2001    66365
2002    63893
2003    63253
2004    61762
2005    55037
2006    47405
2007    35492
2008    22697
2009    14334
2010    13329
2011    12282
2012     8304
2013     4375
2014     1863
2015      251
Name: earliesCreditLine, dtype: int64

接下来就是对一些类别的特征进行处理,争取将其转换为ont-hot向量:

cate_features = ["grade",
                "subGrade",
                "employmentTitle",
                "homeOwnership",
                "verificationStatus",
                "purpose",
                "postCode",
                "regionCode",
                "applicationType",
                "initialListStatus",
                "title",
                "policyCode"]
for fea in cate_features:
    print(fea, " 类型数目为:", data[fea].nunique())
grade  类型数目为: 7
subGrade  类型数目为: 35
employmentTitle  类型数目为: 298101
homeOwnership  类型数目为: 6
verificationStatus  类型数目为: 3
purpose  类型数目为: 14
postCode  类型数目为: 935
regionCode  类型数目为: 51
applicationType  类型数目为: 2
initialListStatus  类型数目为: 2
title  类型数目为: 47903
policyCode  类型数目为: 1

可以看到其中一些特征的类别数目比较少,就适合转换成one-hot向量,但是那些类别数目特别多的就不适合,那么参考baseline采取的做法就是增加计数和排序两类特征。

先将部分转换为one-hot向量:

data = pd.get_dummies(data, columns = ['grade', 'subGrade', 
                                             'homeOwnership', 'verificationStatus', 
                                             'purpose', 'regionCode'],
                     drop_first = True)
# drop_first就是k个类别,我只用k-1个来表示,那个没有表示出来的类别就是全0

对特别高维的:

# 高维类别特征需要进行转换
for f in ['employmentTitle', 'postCode', 'title']:
    data[f+'_cnts'] = data.groupby([f])['id'].transform('count')
    data[f+'_rank'] = data.groupby([f])['id'].rank(ascending=False).astype(int)
    del data[f]
    
# cnts的意思就是:对f特征的每一个取值进行计数,例如取值A有3个,B有5个,C有7个
# 那么那些f特征取值为A的,在cnt中就是取值为3,B的就是5,C的就是7
# 而rank就是对取值为A的三个排序123,对B的排12345,C的排1234567,各个取值内部排序
# 然后ascending=False就是从后面开始给,最后一个取值为A的给1,倒数第二个给2,倒数第三个给3

处理过后得到的数据为:

data.shape
(1000000, 154)

那么再划分为训练数据和测试数据:

train = data[data["origin"] == "train"].reset_index(drop=True)
test = data[data["origin"] == "test"].reset_index(drop=True)
features = [f for f in data.columns if f not in ['id','issueDate','isDefault',"origin"]]  # 这些特征不用参与训练
x_train = train[features]
y_train = target
x_test = test[features]

选取模型

我选取了xgboost和lightgbm,然后进行模型融合,后续有时间再尝试其他的组合吧:

lgb_params = {
                'boosting_type': 'gbdt',
                'objective': 'binary',
                'metric': 'auc',
                'min_child_weight': 5,
                'num_leaves': 2 ** 5,
                'lambda_l2': 10,
                'feature_fraction': 0.8,
                'bagging_fraction': 0.8,
                'bagging_freq': 4,
                'learning_rate': 0.1,
                'seed': 2020,
                'nthread': 28,
                'n_jobs':24,
                'verbosity': 1,
                'verbose': -1,
            }
folds = StratifiedKFold(n_splits=5, shuffle=True, random_state=1)
valid_lgb = np.zeros(len(x_train))
predict_lgb = np.zeros(len(x_test))
for fold_, (train_idx,valid_idx) in enumerate(folds.split(x_train, y_train)):
    print("当前第{}折".format(fold_ + 1))
    train_data_now = lgb.Dataset(x_train.iloc[train_idx], y_train[train_idx])
    valid_data_now = lgb.Dataset(x_train.iloc[valid_idx], y_train[valid_idx])
    watchlist = [(train_data_now,"train"), (valid_data_now, "valid_data")]
    num_round = 10000
    lgb_model = lgb.train(lgb_params, train_data_now, num_round, 
                        valid_sets=[train_data_now, valid_data_now], verbose_eval=500,
                       early_stopping_rounds = 800)
    valid_lgb[valid_idx] = lgb_model.predict(lgb.Dataset(x_train.iloc[valid_idx]),
                                           ntree_limit = lgb_model.best_ntree_limit)
    predict_lgb += lgb_model.predict(lgb.Dataset(x_test), num_iteration=
                                           lgb_model.best_iteration) / folds.n_splits

这部分训练过程在我之前的集成学习实战博客中已经介绍了,因此也是套用那部分思路。

同样,也可以看看特征重要性:

pd.set_option("display.max_columns", None)  # 设置可以显示的最大行和最大列
pd.set_option('display.max_rows', None)  # 如果超过就显示省略号,none表示不省略
#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
df = pd.DataFrame(data[features].columns.tolist(), columns=['feature'])
df['importance'] = list(lgb_model.feature_importance())
df = df.sort_values(by = "importance", ascending=False)
plt.figure(figsize = (14,28))
sns.barplot(x = 'importance', y = 'feature', data = df.head(50))
plt.title('Features importance (averaged/folds)')
plt.tight_layout()  # 自动调整适应范围

特征重要性

# xgboost模型

xgb_params = {'booster': 'gbtree',
                      'objective': 'binary:logistic',
                      'eval_metric': 'auc',
                      'gamma': 1,
                      'min_child_weight': 1.5,
                      'max_depth': 5,
                      'lambda': 10,
                      'subsample': 0.7,
                      'colsample_bytree': 0.7,
                      'colsample_bylevel': 0.7,
                      'eta': 0.04,
                      'tree_method': 'exact',
                      'seed': 1,
                      'nthread': 36,
                      "verbosity": 1,
                      }
folds = StratifiedKFold(n_splits=5, shuffle=True, random_state=1)
valid_xgb = np.zeros(len(x_train))
predict_xgb = np.zeros(len(x_test))
for fold_, (train_idx,valid_idx) in enumerate(folds.split(x_train, y_train)):
    print("当前第{}折".format(fold_ + 1))
    train_data_now = xgb.DMatrix(x_train.iloc[train_idx], y_train[train_idx])
    valid_data_now = xgb.DMatrix(x_train.iloc[valid_idx], y_train[valid_idx])
    watchlist = [(train_data_now,"train"), (valid_data_now, "valid_data")]
    xgb_model = xgb.train(dtrain = train_data_now, num_boost_round = 3000,
                         evals = watchlist, early_stopping_rounds = 500,
                         verbose_eval = 500, params = xgb_params)
    valid_xgb[valid_idx] =xgb_model.predict(xgb.DMatrix(x_train.iloc[valid_idx]),
                                           ntree_limit = xgb_model.best_ntree_limit)
    predict_xgb += xgb_model.predict(xgb.DMatrix(x_test),ntree_limit 
                                     = xgb_model.best_ntree_limit) / folds.n_splits
   

放一下部分训练过程吧:

当前第5[0]	train-auc:0.69345	valid_data-auc:0.69341
[500]	train-auc:0.73811	valid_data-auc:0.72788
[1000]	train-auc:0.74875	valid_data-auc:0.73066
[1500]	train-auc:0.75721	valid_data-auc:0.73194
[2000]	train-auc:0.76473	valid_data-auc:0.73266
[2500]	train-auc:0.77152	valid_data-auc:0.73302
[2999]	train-auc:0.77775	valid_data-auc:0.73307

那么接下来的模型融合我就采用了简单的逻辑回归:

# 模型融合
train_stack = np.vstack([valid_lgb, valid_xgb]).transpose()
test_stack = np.vstack([predict_lgb, predict_xgb]).transpose()
folds_stack = RepeatedKFold(n_splits = 5, n_repeats = 2, random_state = 1)
valid_stack = np.zeros(train_stack.shape[0])
predict_lr2 = np.zeros(test_stack.shape[0])

for fold_, (train_idx, valid_idx) in enumerate(folds_stack.split(train_stack, target)):
    print("当前是第{}折".format(fold_+1))
    train_x_now, train_y_now = train_stack[train_idx], target.iloc[train_idx].values
    valid_x_now, valid_y_now = train_stack[valid_idx], target.iloc[valid_idx].values
    lr2 = lr()
    lr2.fit(train_x_now, train_y_now)
    valid_stack[valid_idx] = lr2.predict(valid_x_now)
    predict_lr2 += lr2.predict(test_stack) / 10
    
print("score:{:<8.8f}".format(roc_auc_score(target, valid_stack)))
score:0.73229269

预测与保存

testA = pd.read_csv("testA.csv")
testA['isDefault'] = predict_lr2
submission_data = testA[['id','isDefault']]
submission_data.to_csv("myresult.csv",index = False)

接下来就可以去提交啦!

完结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/43921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux中less和more的区别

总结下more和less的区别(less is more)&#xff1a; 1、less可以按键盘上下方向键显示上下文内容&#xff0c;more不能通过上下方向键控制显示&#xff08;但是可以用b实现向上翻页&#xff0c;空格键实现向下翻页&#xff09; 2、less不必读整个文件&#xff0c;加载速度会比…

数码视讯Q5、Q7_晶晨S905L/M/M2_nandemmc通刷_完美精简线刷固件

数码视讯Q5、Q7_晶晨S905L/M/M2_nand&emmc通刷_完美精简线刷固件 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xf…

一道有趣的最长子序列问题

一道有趣的最长子序列问题 – 潘登同学的金融经济学笔记 文章目录一道有趣的最长子序列问题 -- 潘登同学的金融经济学笔记来源求解递推公式算法实现来源 前几天在刷视频的时候&#xff0c;发现了这样一道题 所谓子序列就是一个序列 ai1,ai2,⋯,aina_{i1},a_{i2},\cdots,a_{in}…

【5w字】SpringBoot源码分析

Spring Boot源码分析 文章目录Spring Boot源码分析启动类分析SpringBootConfigurationEnableAutoConfigurationComponentScanSpringBoot启动流程1. 准备SpringApplication获取当前 web 应用类型设置初始化器设置监听器推导主应用程序类2. Spring Boot的运行创建计时器并启动设置…

开源工具 | ASV-Subtools更新:runtime模块重磅发布

ASV-Subtools更新 - runtime模块重磅发布 - ASV-Subtools是厦门大学智能语音实验室&#xff08;XMUSPEECH&#xff09;于2020年6月推出的一套高效、易于扩展的声纹识别开源工具&#xff0c;该工具是基于Kaldi与Pytorch开发的&#xff0c;充分结合了Kaldi 在语音信号和后端处理…

Fe3+-多巴胺修饰Pluronic的多功能性水凝胶/多巴胺修饰聚丙烯微孔膜表面的研究

下面整理了Fe3-多巴胺修饰Pluronic的多功能性水凝胶/多巴胺修饰聚丙烯微孔膜表面&#xff0c;和小编一起来看&#xff01; Fe3-多巴胺修饰Pluronic多功能性水凝胶 利用对硝基苯基氯酸甲酯作为聚合物Pluronic F127端羟基活化剂,与盐酸多巴胺直接反应制备末端多巴胺修饰的Pluron…

【web课程设计网页规划与设计】基于HTML+CSS+JavaScript火车票网上预订系统网站(4个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Part4_场景_第52章 场景描述第53章 柏林I:BVG场景第54章 柏林II:CEMDAP-Matsim-Cadyts方案

第52章 场景概述 本书的最后一部分总结了MATSIM场景,如图52.1中的地图所示,并在http://matsim.org/scolutions中列出。 尽管存在基于免费和公共数据的真实场景,如圣地亚哥或科特布斯场景(第84或66章),但由于数据隐私问题,许多场景是不公开的。 然而,了解适用于情景创建…

【STM32备忘录】二、FSMC做LCD控制器,使用stm32cube配置示例

文章目录1. FSMC框图2. 配置示例(1) cube配置(2) 代码参考*疑问1. FSMC框图 如果屏幕接口8位数据宽度访问&#xff0c;地址线FSMC_A[25:0], 一共26位&#xff0c;一个块22667108864Byte64MB&#xff0c;如果屏幕接口16位数据宽度访问&#xff0c;地址线FSMC_A[25:0], 一共26位&…

远程访问数据库,快解析助力疫情防控远程办公

当前&#xff0c;国内疫情形势不容乐观&#xff0c;企业的经营发展再一次面临巨大挑战。虽然“远程办公”早已不是新鲜词&#xff0c;但依然有大量企业没有做好随时切换到远程办公的准备。如遇疫情风险&#xff0c;企业运营很容易陷入瘫痪。 企业一般在内网部署服务器、视频监…

【Java并发入门】01 并发编程Bug的源头

一、根本原因 「CPU、内存、磁盘之间的速度差异」 为了能同时执行多个任务&#xff0c;CPU 发展出时间片轮转、多核等CPU 要从内存中读数据太慢了&#xff0c;所以给自己设置了缓存CPU 读磁盘更慢了&#xff0c;所以可以让该线程阻塞 二、直接原因 缓存导致的可见性问题 C…

函数 function

一、创建函数方法 1.基本语法 函数是引用数据类型 1.1有函数名称的叫具名函数 function 函数名称&#xff08;&#xff09;{ }&#xff1b; 调用函数&#xff1a; 函数名&#xff08;&#xff09;&#xff1b; <script>function fnl( ){var a 2;var b 5…

教你快速搭建微服务环境

目录 一、项目搭建 1.父项目搭建 2.子项目的搭建 二、项目展示 一、项目搭建 1.父项目搭建 步骤&#xff1a; 1 选择maven项目作为父项目&#xff0c;修改为1.8之后直接点击next 2 定义父项目的名称&#xff0c;修改Artifct Coordinates ---> GroupId 然后点击finsh就可…

现代营销杂志现代营销杂志社现代营销编辑部2022年第11期目录

财务金融《现代营销》投稿&#xff1a;cnqikantg126.com 我国中小企业货币资金管理分析 安宁; 1-3 企业财务管理转型路径探讨 秦春; 4-6 互联网背景下电商企业税务风险研究 何秋梅; 7-9 目标成本管理在企业经济管理中的应用分析 艾蕾梅; 10-12 关于我国发展…

CentOS7.9集群部署(配置hosts、集群免密、时间同步)

在上一篇我们介绍了如何在windows下安装虚拟机&#xff0c;在虚拟机上安装CentOS7.9&#xff0c;并且在系统安装完成后配置了固定ip和系统时间。 在食用本篇之前&#xff0c;如果上述操作没有做过&#xff0c;可以先移步 windows安装VMware虚拟机(附带CentOS7部署) 但是在分布式…

文献阅读总结(3)Neural Graph Collaborative Filtering

1、Introduction 左图u1&#xff0c;右图从左图的u1开始展开 图反应的信息&#xff1a; 1、从路径u1->i2->u2,可以反映出u1和u2的相似性&#xff1b; 2、u1和i4之间有两条路径&#xff0c;而u1和i5之间只有一条路径&#xff0c;可以反应u1对i4的兴趣比u1对i5的兴趣更高…

[附源码]Python计算机毕业设计Django-Steam游戏平台系统论文

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【web网页设计期末课程大作业】基于HTML+CSS+JavaScript仿山东传媒职业学院网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

梯度下降原理+梯度消失和爆炸

梯度下降算法&#xff08;Gradient Descent)的原理和实现步骤 - 知乎 (zhihu.com) 梯度&#xff08;gradient&#xff09;到底是个什么东西&#xff1f;物理意义和数学意义分别是什么&#xff1f; - 知乎 (zhihu.com) 目的&#xff1a;最小化损失函数&#xff0c;一个优化的思…

流媒体传输 - RTSP 协议报文分析

在流媒体传输 - RTSP 协议中&#xff0c;我们分析 RTSP 协议交互的整个流程&#xff0c;在本篇文章中&#xff0c;我们对交互中携带的报文进行详细分析。 Request Request Request-Line ; Section 6.1*( general-header ; Section 5…