机器学习每周挑战——二手车车辆信息交易售价数据

news2024/11/23 16:43:35

这是数据集的截图

目录

背景描述

数据说明

车型对照:

燃料类型对照:

老规矩,第一步先导入用到的库

 第二步,读入数据:

第三步,数据预处理

第四步:对数据的分析

第五步:模型建立前的准备工作

第六步:多元线性回归模型的建立

第七步:随机森林模型的建立

问题:


背景描述

本数据爬取自印度最大的二手车交易平台 CARS24,包含 8000+ 该平台上交易车辆的关键评估信息。

CARS24 成立于 2015 年,总部位于印度古尔冈,是一个在印度、澳大利亚、泰国和阿联酋运营的二手车交易平台,为用户提供一站式二手车交易服务,包括车辆评估、交易、融资、保险等。CARS24 已成为印度最大的二手车交易平台之一,在印度拥有超过 1000 家线下门店。

数据说明

字段说明
Car Name汽车品牌或汽车型号
Distance行驶里程 (单位:公里)
Year Bought购车年份
Previous Owners前任车主数量
Location车管所所在地
Transmission变速箱类型 (automatic自动 或 manua手动)
Car Type车型
Fuel燃料类型 (汽油、柴油、CNG 等)
Price价格
  • 车型对照:

    英文中文
    sedan轿车
    SUVSUV
    hatchback两厢车
    luxury SUV豪华SUV
    luxury sedan豪华轿车
  • 燃料类型对照:

    英文中文
    petrol汽油
    diesel柴油
    CNG压缩天然气
    other其他

老规矩,第一步先导入用到的库

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import statsmodels.api as sm
from statsmodels.formula.api import ols
from sklearn.preprocessing import StandardScaler,LabelEncoder,OneHotEncoder
from statsmodels.stats.outliers_influence import variance_inflation_factor
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error,r2_score,classification_report
import scipy.stats as stats
from statsmodels.stats.stattools import durbin_watson
from statsmodels.stats.diagnostic import het_breuschpagan
from scipy.stats import kstest
from sklearn.ensemble import RandomForestRegressor
from hyperopt import fmin, tpe, hp,STATUS_OK

 第二步,读入数据:

data = pd.read_csv('cars_24.csv')
pd.set_option('display.max_columns',1000)
pd.set_option('display.max_rows',1000)

plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = ['Microsoft YaHei']

第三步,数据预处理

print(data.info()) # 从这里我们可以看出Location Year Car Name 三列数据有确实值,由于位置信息无法填充,因此我选择将缺失值删除
data.dropna(inplace=True)
for col in data.columns:
    print(col)
    print(data[col].unique())
    print('/'*20)
# 通过上面的循环我们可以了解到所有列的唯一值,排除Index Distance Price这些连续值,我们可以看出其他特征列都有那些值
# 删除包含22-BH的行,因为在印度的车辆注册号码中,BH通常不是一个标准的州或联邦领地代码,这可能是数据有误,这里直接删除
data = data[data['Location'] != '22-BH']
# 由于Car Name名字太多,因此我们只提取品牌,即,第一个空格前面的
data['Brand'] = data['Car Name'].apply(lambda x: x.split()[0]) 
# 有了Brand后,我们将原先的Car Name这一列删除
data = data.drop('Car Name',axis=1)
data['Location'] = data['Location'].apply(lambda x:x[:2])
# print(data['Location'].unique())           # 如果前面我们没发现22-BH这种异常值,我们从这里发现后,我们也可以将其删除
# data['Location'] = [x for x in data['Location'] if x!=22]
# 标签这一列对于我们来说也没有用,因此我们也将其删除
data.drop('Index',axis=1,inplace=True)
# 将年份转换为整数
data['Year'] = data['Year'].astype(int)
# 我们对预处理后的数据进行复制,以便于我们后续对数据进行建模
new_data = data.copy()

第四步:对数据的分析

# 接下来我们对数据进行分析,通过图表来观察他们各个特征之间的关联
plt.figure(figsize=(10,8))
ax = sns.countplot(x='Brand',data=data)
plt.title('不同品牌的分布情况')
plt.xlabel('品牌')
plt.ylabel('品牌数量')
plt.xticks(rotation=90)
plt.tight_layout()

for p in ax.patches:
    ax.annotate(format(p.get_height(), '.0f'),
                (p.get_x() + p.get_width() / 2., p.get_height()),
                ha = 'center', va = 'center',
                xytext = (0, 10),
                textcoords = 'offset points')

plt.show()

所有二手车品牌中,马鲁蒂(Maruti)和现代(Hyundai)的数量是最多的,马鲁蒂是印度的一个知名品牌,所以占比也是最大的

fig,ax = plt.subplots(1,3,figsize=(10,8))
count_year = data['Year'].value_counts()
label = count_year.index
# print(label)
ax[0].pie(count_year,labels=label,autopct='%.2f%%')
ax[0].set_title('各个年份购车数量占比')

ax[1].hist(data['Distance'],bins=30)
ax[1].set_title('车辆行驶距离')

ax[2].hist(data['Price'],bins=30)
ax[2].set_title('购车价格')

plt.tight_layout()
plt.show()

总结:数据集中的车辆大多数是17,18年购买的,有较短的行驶距离,且价格相对较低

fig,ax = plt.subplots(2,2,figsize=(10,8))
owner_plot = sns.countplot(ax=ax[0,0],x='Owner',data=data)
ax[0,0].set_title('前任车主特征分布图')
ax[0,0].set_xlabel('前任车主')
ax[0,0].set_ylabel('总数')
for x in owner_plot.patches:
    owner_plot.annotate(format(x.get_height(),'.0f'),
                        (x.get_x()+x.get_width()/2,x.get_height()),
                        ha='center',va='center',
                        xytext=(0,10),
                        textcoords='offset points')


fuel_plot = sns.countplot(ax=ax[0,1],x='Fuel',data=data)
ax[0,1].set_title('燃料类型特征分布图')
ax[0,1].set_xlabel('燃料类型')
ax[0,1].set_ylabel('总数')
for x in fuel_plot.patches:
    fuel_plot.annotate(format(x.get_height(),'.0f'),
                        (x.get_x()+x.get_width()/2,x.get_height()),
                        ha='center',va='center',
                        xytext=(0,10),
                        textcoords='offset points')


drive_plot = sns.countplot(ax=ax[1,0],x='Drive',data=data)
ax[1,0].set_title('变速器类型特征分布图')
ax[1,0].set_xlabel('变速器类型')
ax[1,0].set_ylabel('总数')
for x in drive_plot.patches:
    drive_plot.annotate(format(x.get_height(),'.0f'),
                        (x.get_x()+x.get_width()/2,x.get_height()),
                        ha='center',va='center',
                        xytext=(0,10),
                        textcoords='offset points')


type_plot = sns.countplot(ax=ax[1,1],x='Type',data=data)
ax[1,1].set_title('车辆类型特征分布图')
ax[1,1].set_xlabel('车辆类型')
ax[1,1].set_ylabel('总数')
for x in type_plot.patches:
    type_plot.annotate(format(x.get_height(),'.0f'),
                        (x.get_x()+x.get_width()/2,x.get_height()),
                        ha='center',va='center',
                        xytext=(0,10),
                        textcoords='offset points')
plt.tight_layout()
plt.show()

 

1.大多数车都是一手车(只有一个前任车主)。

2.大多数车都是使用汽油(Petrol),然后就是柴油(Diesel),天然气(CNG)和液化石油气(LPG)作为燃料类型的车辆数量相对较少。

3.手动挡(Manual)车辆数量大于自动挡(Automatic)车辆数量。

4.掀背车(HatchBack)是最常见的车型,其次是轿车(Sedan)和SUV,豪华SUV(Lux_SUV)和豪华轿车(Lux_sedan)的数量相对较少。

plt.figure(figsize=(10,8))
registration = data['Location'].value_counts().reset_index()
# print(registration)
plt.bar(registration['Location'],registration['count'])
plt.title('车辆注册地址')
plt.xlabel('注册地')
plt.ylabel('数量')
plt.tight_layout()
plt.show()

MH和KA有较多的车辆注册,CH、KL、RJ、BR、AP、MP有较少的车辆注册,较少的注册数量可能表明在某些州二手车市场的规模较小。

plt.figure(figsize=(10,8))
sns.boxplot(x='Brand',y='Price',data=data)
plt.title('品牌和价格分布的箱线图')
plt.xlabel('品牌')
plt.ylabel('价格')
plt.tight_layout()
plt.show()

 可以看到,不同品牌之间的汽车价格有明显差异,达特桑(Datsun)、马鲁蒂(Maruti)价格普遍比较低,吉普(Jeep)、名爵(MG) 价格普遍偏高,当然,这也可能是因为数据样本少导致的,但是从整体上看,可以认为不同品牌之间的汽车价格有明显差异。

plt.figure(figsize=(10,8))
sns.regplot(x='Distance',y='Price',data=data,scatter_kws={'alpha':0.4},line_kws={'color':'red'})
plt.title('行驶距离和价格之间的关系图')
plt.xlabel('行驶距离')
plt.ylabel('价格')
plt.show()

行驶距离和价格之间没有明显的线性关系,虽然价格的整体趋势似乎随行驶距离的增加而下降,但数据点较为分散

plt.figure(figsize=(10,8))
sns.boxplot(x='Year',y='Price',data=data)
plt.title('年份和价格分布的箱线图')
plt.xlabel('年份')
plt.ylabel('价格')
plt.tight_layout()
plt.show()

购买年份是影响二手车价格的一个重要因素,不同年份的车辆价格分布有显著差异,随着购买年份越近,车辆价格也越高。

fig, axes = plt.subplots(2, 2, figsize=(24, 24))

# 前任车主的数量对价格的影响
sns.boxplot(ax=axes[0, 0], x='Owner', y='Price', data=data)
axes[0, 0].set_title('前任车主对价格的影响')
axes[0, 0].set_xlabel('前任车主的数量')
axes[0, 0].set_ylabel('价格')

# 燃料类型对价格的影响
sns.boxplot(ax=axes[0, 1], x='Fuel', y='Price', data=data)
axes[0, 1].set_title('燃料类型对价格的影响')
axes[0, 1].set_xlabel('燃料类型')
axes[0, 1].set_ylabel('价格')

# 变速器类型对价格的影响
sns.boxplot(ax=axes[1, 0], x='Drive', y='Price', data=data)
axes[1, 0].set_title('变速器类型对价格的影响')
axes[1, 0].set_xlabel('变速器类型')
axes[1, 0].set_ylabel('价格')

# 车辆类型对价格的影响
sns.boxplot(ax=axes[1, 1], x='Type', y='Price', data=data)
axes[1, 1].set_title('车辆类型对价格的影响')
axes[1, 1].set_xlabel('车辆类型')
axes[1, 1].set_ylabel('价格')

plt.tight_layout()
plt.show()

 1.前任车主越多,价格越低,至于4手车因为数据样本只有一个,导致价格偏高,但是仍然可以认为前任车主的数量与价格有显著关系。

2.柴油车的价格要高于其他三种类型的汽车,可以认为不同燃料类型之间的汽车价格有明显差异。

3.整体上,自动挡的车价格要高于手动挡的车。

4.豪华版的汽车价格整体上更贵,其次是SUV的价格高于轿车(Sedan),高于掀背车(HatchBack),也就是两厢车,因此可以认为不同类型之间的汽车价格有明显差异。

# 对于价格的影响因素我们可以通过斯皮尔曼来确定
print(data.info())
le = LabelEncoder()
for col in data.columns:
    data[col] = le.fit_transform(data[col])

corr = data.corr(method='spearman')
plt.figure(figsize=(10,8))
sns.heatmap(corr,color='red',annot=True,fmt='.2f')
plt.show()

 通过热力图我们可以发现年份,变速器类型,和车辆类型对价格的影响较高。

第五步:模型建立前的准备工作

new_data = pd.get_dummies(new_data,columns=['Brand','Fuel','Location','Type','Drive'],dtype=int)
# print(new_data.info())
# 对车辆行驶距离进行对数变化处理,因为行驶距离成右偏分布,对数变化可以使得数据更接近正态分布,而且缩小极端值的影响。
new_data['Log_Distance'] = np.log(data['Distance']+1)
# 最后,由于部分特征数据跨度较大,因此我们对数据进行标准化
scaler = StandardScaler()
features_to_scale = ['Year', 'Log_Distance', 'Owner']
new_data[features_to_scale] = scaler.fit_transform(new_data[features_to_scale])
# 由于我们前面对距离这一列进行对数化操作后,将其重新写入数据中,因此我们将原先的数据列删除
new_data.drop(['Distance'], axis=1, inplace=True)

df = new_data.drop('Price',axis=1)
df = sm.add_constant(df)
# 计算VIF值
vif_data = pd.DataFrame()
vif_data['feature'] = df.columns
vif_data['VIF'] = [variance_inflation_factor(df.values,i) for i in range(df.shape[1])]
# print(vif_data)
# 独热编码后又导致了无穷大的多重共线性,这里需要进行处理,直接删除独热编码产生的一个类别(建议选择数量最多的那个),
# 这样删除的好处是,当其他类型都为0的时候,实际上表示了这个被删除的特征。
# for col in df.columns:
#     count = df[col].value_counts()
#     print(count)
# 删除一些独热编码新增的列
new_data.drop(['Brand_Maruti','Fuel_CNG','Location_MH','Type_HatchBack'], axis=1,inplace=True)
df = new_data.drop('Price',axis=1)
df = sm.add_constant(df)
# 计算VIF值,一般来说VIF大于10,这样我们会认为各个特征之间相关性较高,VIF小于5,我们认为各个特征之间相关性较小
vif_data = pd.DataFrame()
vif_data['feature'] = df.columns
vif_data['VIF'] = [variance_inflation_factor(df.values,i) for i in range(df.shape[1])]
# print(vif_data)


这里我们可以对比处理之后的VIF值

原先的

feature

VIF

修改后

feature

VIF

0

const

0.000000e+00

0

const

0.000000

1

Year

1.538487e+00

1

Year

1.539060

2

Owner

1.075933e+00

2

Owner

1.076317

3

Brand_BMW

inf

3

Brand_BMW

1.038786

4

Brand_Datsun

3.657790e+10

4

Brand_Datsun

1.039203

5

Brand_Ford

1.306448e+10

5

Brand_Ford

1.220622

6

Brand_Honda

5.115576e+10

6

Brand_Honda

1.306347

7

Brand_Hyundai

2.004020e+09

7

Brand_Hyundai

1.208989

8

Brand_Jeep

1.508666e+09

8

Brand_Jeep

1.181273

9

Brand_KIA

1.197766e+12

9

Brand_KIA

1.107366

10

Brand_MG

9.025250e+12

10

Brand_MG

1.006706

11

Brand_Mahindra

6.519869e+11

11

Brand_Mahindra

1.541723

12

Brand_Maruti

4.401194e+07

12

Brand_Nissan

1.039784

13

Brand_Nissan

2.334987e+08

13

Brand_Renault

1.137255

14

Brand_Renault

5.922232e+09

14

Brand_Skoda

1.072001

15

Brand_Skoda

1.450388e+11

15

Brand_Tata

1.140520

16

Brand_Tata

7.876965e+09

16

Brand_Toyota

1.194287

17

Brand_Toyota

1.386027e+09

17

Brand_Volkswagen

1.057490

18

Brand_Volkswagen

1.412468e+09

18

Fuel_DIESEL

3.147239

19

Fuel_CNG

2.854194e+05

19

Fuel_LPG

1.015113

20

Fuel_DIESEL

6.822078e+04

20

Fuel_PETROL

2.926265

21

Fuel_LPG

inf

21

Location_AP

1.086004

22

Fuel_PETROL

7.304430e+04

22

Location_BR

1.078538

23

Location_AP

3.756073e+08

23

Location_CH

1.067019

24

Location_BR

3.563682e+08

24

Location_DL

1.447625

25

Location_CH

2.543173e+08

25

Location_GJ

1.431759

26

Location_DL

5.847216e+06

26

Location_HR

1.334937

27

Location_GJ

1.088085e+05

27

Location_KA

1.638158

28

Location_HR

1.314777e+05

28

Location_KL

1.097616

29

Location_KA

1.106656e+05

29

Location_MP

1.087806

30

Location_KL

2.893677e+08

30

Location_PB

1.134487

31

Location_MH

1.778885e+04

31

Location_RJ

1.103258

32

Location_MP

1.712941e+08

32

Location_TN

1.402470

33

Location_PB

1.165631e+07

33

Location_TS

1.417552

34

Location_RJ

7.345066e+08

34

Location_UP

1.282728

35

Location_TN

2.105363e+04

35

Location_WB

1.174599

36

Location_TS

2.822998e+06

36

Type_Lux_SUV

1.627484

37

Location_UP

4.673710e+04

37

Type_Lux_sedan

1.207469

38

Location_WB

2.755977e+05

38

Type_SUV

1.697632

39

Type_HatchBack

5.012798e+03

39

Type_Sedan

1.402544

40

Type_Lux_SUV

5.605885e+09

40

Drive_Automatic

inf

41

Type_Lux_sedan

1.691652e+09

41

Drive_Manual

inf

42

Type_SUV

3.487443e+05

42

Log_Distance

1.348290

43

Type_Sedan

3.064002e+05

44

Drive_Automatic

7.560662e+04

45

Drive_Manual

1.163354e+04

46

Log_Distance

1.346594e+00

可以发现,删除了那几列后,除了常数项的方差膨胀因子(VIF)>10,其他特征均在1-4之间,可以认为这个数据特征不存在多重共线性,因此可以使用多元线性回归模型。

第六步:多元线性回归模型的建立

# 接下来我们开始建立模型
X = new_data.drop('Price',axis=1)
y = new_data['Price']
# 对X,y进行赋值后,我们对数据进行划分
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42)

# 创建模型
Re = LinearRegression()
Re.fit(X_train,y_train)
# 对模型进行训练后,我们需要对残差的正态性分布进行验证,否则多元线性回归模型的预测结果会不准确
pred_y_train = Re.predict(X_train)
residuals = y_train-pred_y_train
# print(len(residuals))
# 绘制残差序列图
plt.figure(figsize=(10,8))
# sns.regplot(x=np.arange(len(residuals)),y=residuals,scatter_kws={'alpha':0.4},line_kws={'color':'yellow'})
plt.plot(residuals,marker='o',linestyle='')
plt.title('残差序列图')
plt.ylabel('残差')
plt.axhline(y=0,color='red',linestyle='-')
# plt.tight_layout()
# plt.show()
# 画出残差图后,我们对残差的独立性进行检验
dw = durbin_watson(residuals)
print('DW检验',dw)
# 接下来,我们判断残差的正态性性分布,这里我们用到了KS检验
ks_statistic,ks_p_values = kstest((residuals - np.mean(residuals))/np.std(residuals),'norm')
print('正态性P值',ks_p_values)
# 验证正态性后,我们还需要验证同方差性
df_ = sm.add_constant(X_train)
bp_test = het_breuschpagan(residuals,df_)
print('同方差P值',bp_test[1])

dw的值在2附近,说明残差的独立性,同时可以从p值看出,残差不符合正态性分布和同方差性分布,因此,不可以用多元线性回归来预测

那我们可以对数据进行优化,比如对因变量(y)进行BOX-COX变换,但是我自己变换后发现还是无法满足正态性分布和同方差性

所以,这里我就不对y进行变换了,不用多元线性回归,我们考虑其他回归模型,比如随机森林,神经网络等

第七步:随机森林模型的建立

Rtree = RandomForestRegressor(random_state=42)
Rtree.fit(X_train,y_train)
y_pred = Rtree.predict(X_test)
# class_report = classification_report(y_test,y_pred)    # 注意 classification_report  是用于分类变量的评价指标,不能用于连续变量
mse = mean_squared_error(y_test,y_pred)
r2 = r2_score(y_test,y_pred)
print('均方根误差:',mse)
print('R2决定系数',r2)

第八步:随机森林模型的优化

# 效果不是很理想,因此我们对随机森林进行优化,这里使用Hyperopt进行优化
def objective(params):
    Rtree = RandomForestRegressor(**params)
    score = -np.mean(cross_val_score(Rtree, X_train, y_train, cv=5, scoring='neg_mean_squared_error'))
    return {'loss': score, 'status': STATUS_OK, 'model': Rtree}

# 设定参数空间
space = {
    'n_estimators': hp.choice('n_estimators', range(10, 500)),
    'max_depth': hp.choice('max_depth', range(1, 50)),
    'min_samples_split': hp.choice('min_samples_split', range(2, 100)),
    'min_samples_leaf': hp.choice('min_samples_leaf', range(2, 100)),
}

# 运行优化
best = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=100)

print("Best parameters found: ", best)

Rtree = RandomForestRegressor(**best)
Rtree.fit(X_train,y_train)
y_pred = Rtree.predict(X_test)
mse = mean_squared_error(y_test,y_pred)
r2 = r2_score(y_test,y_pred)
print('均方根误差:',mse)
print('R2决定系数',r2)


对模型的优化没有没有多大提升,大家可以试着把n_estimators,max_depth等参数适当调大,可能运行时间较长

由于神经网络通常被称为“黑匣子”模型,因为其内部结构复杂,难以直观理解,且代码偏多,因此我会在后续的每周挑战中单独拿出一起来使用神经网络

问题:

这里我发现了一个问题,那就是我使用独热编码时不知道为什么会出现这种情况,但我前面对于人力资源分析这篇文章里面用的就是这个方法,对每一列进行独热编码,删除原先的列,将其经过独热编码的子列加入到数据集。我感觉思路应该没错,有解决思路的可以私聊我,也可以写在评论区。

encode = OneHotEncoder()
for col in new_data.columns:
    if data[col].dtype == object:
        encode_data = encode.fit_transform(new_data[[col]])
        new_data.drop(col, axis=1, inplace=True)
        encoded_columns = [f"{col}_{i}" for i in range(encode_data.shape[1])]
        new_data = pd.concat([new_data, pd.DataFrame(encode_data, columns=encoded_columns)], axis=1)


Traceback (most recent call last):
    new_data = pd.concat([new_data, pd.DataFrame(encode_data, columns=encoded_columns)], axis=1)
  File "D:\pyobject\pythonProject\.venv\lib\site-packages\pandas\core\frame.py", line 867, in __init__
    mgr = ndarray_to_mgr(
  File "D:\pyobject\pythonProject\.venv\lib\site-packages\pandas\core\internals\construction.py", line 336, in ndarray_to_mgr
    _check_values_indices_shape_match(values, index, columns)
  File "D:\pyobject\pythonProject\.venv\lib\site-packages\pandas\core\internals\construction.py", line 420, in _check_values_indices_shape_match
    raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}")
ValueError: Shape of passed values is (7800, 1), indices imply (7800, 4)

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

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

相关文章

会声会影电影片头怎么做 会声会影电影质感调色技巧

片头通常通过一系列的图像、音乐和文字等元素来引入电影的主题和氛围。通过视觉和音频的呈现方式,给观众留下深刻的第一印象,为电影的故事铺设基础。这篇文章来学习一下会声会影片头怎么做,会声会影电影质感调色技巧。 一、会声会影电影片头…

数据库(MySQL)基础:多表查询(一)

一、多表关系 概述 项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:…

npm install digital envelope routines::unsupported解决方法

目录 一、问题描述二、问题原因三、解决方法 一、问题描述 执行命令 npm install 报错:digital envelope routines::unsupported 二、问题原因 Node.js 17 版本引入了 OpenSSL 3.0,它在算法和密钥大小方面实施了更为严格的限制。这一变化导致 npm 的升…

badKarma:一款功能强大的网络侦查GUI工具

关于badKarma badKarma是一款开源的网络侦查工具,该工具基于Python 3开发,提供了友好的图形化用户接口,可以帮助广大渗透测试人员在网络基础设施安全审计过程中执行网络侦查任务。 badKarma是一个模块化工具,基于python3 GTK套件…

【研发管理】产品经理知识体系-产品创新流程

导读:产品创新流程是一个系统性的过程,旨在通过创造和引入新的产品或改进现有产品来满足市场需求、解决用户问题或实现竞争优势。 目录 1、产品创新引论 2、决策基本框架 3、模糊前端 4、产品创新流程模型概论 5、门径管理流程 6、并行工程和集成产…

基于ssm+jsp+mysql+java的人事管理系统

💞文末获取源码联系🙉 👇🏻 精选专栏推荐收藏订阅👇🏻 🎀《Java精选实战项目-计算机毕业设计题目推荐-期末大作业》😘更多实战项目~ https://www.yuque.com/liuyixin-rotwn/ei3euo/d…

设计模式: 工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。 工厂模式属于创建型…

Linux的Shell脚本详解

本文目录 一、什么是 Shell 脚本文件 ?二、编写Shell脚本1. 基本规则2. shell 变量(1)创建变量(2)引用变量(3)删除变量(4)从键盘读取变量(5)特殊变…

PHP的数组练习实验

实 验 目 的 掌握索引和关联数组,以及下标和元素概念; 掌握数组创建、初始化,以及元素添加、删除、修改操作; 掌握foreach作用、语法、执行过程和使用; 能应用数组输出表格和数据。 任务1:使用一维索引数…

一键实现在VS Code中绘制流程图

VS Code是一款常用的IDE,受到许多用户的欢迎和喜爱。而其较为出众的一点,就是较好的可拓展性,即丰富的插件应用,这些应用可以极大地提高生产效率,并优化日常使用。 流程图是一种直观的图示方法,可以用简明…

富文本编辑器 iOS

https://gitee.com/klkxxy/WGEditor-mobile#wgeditor-mobile 采用iOS系统浏览器做的一款富文本编辑器工具。 原理就是使用WKWebView加载一个本地的一个html文件,从而达到编辑器功能的效果! 由于浏览器的一些特性等,富文本编辑器手机端很难做…

wordpress子比主题美化-为图文列表封面添加动态缩略图特效 多种效果演示

wordpress子比主题-为图文列表文章封面添加动态缩略图特效 给自己子比主题加一个列表文章封面添加动态缩略图 直接复制以下代码,添加到主题自定义CSS代码中即可,下图为效果演示 wordpress子比主题-为图文列表文章封面添加动态缩略图特效 给自己子比主题…

SpringData JPA - ORM 框架下,打造高效数据访问层

目录 一、SpringData JPA 概述 1.1、什么是 JPA 1.2、什么是 ORM 1.3、什么是 Hibernate 1.4、JPA 和 Hibernate 的关系 1.5、JPA 的优势 二、SpringData JPA 实战开发 2.1、依赖 2.2、配置文件 2.3、启动类 2.4、创建实体 2.5、基于 JpaRepository 的 CRUD 三、…

空闲缓冲区(empty) 和 非空缓冲区(full) 的的概念和区别【操作系统 生产者——消费者进程】

首先,我们得有个环境——通常是个缓冲池,这个池子里可以塞很多缓冲区,它们是用来存放数据的。生产者就是那个不停造东西的家伙,而消费者则是等着用这些东西的人。 1. 空闲缓冲区(empty): 这玩意…

基于SSM的“大学生创新团队管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“大学生创新团队管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 首页页面 团队风采页面 团队招新页面…

《HCIP-openEuler实验指导手册》1.6 Apache静态资源配置(目录访问)

知识点 常用用途: 软件仓库镜像及提供下载服务: 配置步骤 删除网站主目录中的文件(本实验机目录为/home/source ip为192.168.12.137 端口为81) cd /home/source rm -rf *在主目录中新建6个文件夹如下图 mkdir test{1..6}新建…

Log4Qt日志框架 - 日志输出重定向(03)

Log4Qt日志框架 - 日志格式化(02)https://mp.csdn.net/mp_blog/creation/editor/138417616?spm1011.2266.3001.6217 一、Log4Qt输出重定向 Log4Qt继承关系图 AppenderSkeleton:实现一般的功能DebugAppender:将日志附加到平台调…

第Y9周:重要模块解读

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 目录 以con.py为例: 一、autopad 二、Conv 三、Focus 四、C2f 文件…

C++入门系列-基于范围的for循环(C++11)和指针空值nullptr(C++11)

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 基于范围的for循环 范围for的语法 在C98中如果要遍历一个数组,可以按照以下方式进行: void TestFor() {int array[] { 1,2,3,4,5 };for (int i 1; i …

nuxt3使用记录六:禁用莫名其妙的Tailwind CSS(html文件大大减小)

发现这个问题是因为,今天我突然很好奇,我发现之前构建的自动产生的200.html和404.html足足290k,怎么这么大呢?不是很占用我带宽? 一个啥东西都没有的静态页面,凭啥这么大!所以我就想着手动把他…