模型学习、调参与对智慧海洋数据建立相应模型

一、模型训练与预测

导入需要的工具库

import gc
import multiprocessing as mp
import os
import pickle
import time
import warnings
from collections import Counter
from copy import deepcopy
from datetime import datetime
from functools import partial
from glob import globimport geopandas as gpd
import lightgbm as lgb
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from gensim.models import FastText, Word2Vec
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
from pyproj import Proj
from scipy import sparse
from scipy.sparse import csr_matrix
from sklearn import metrics
from sklearn.cluster import DBSCAN
from sklearn.decomposition import NMF, TruncatedSVD
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.metrics import f1_score, precision_recall_fscore_support
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
from tqdm import tqdmos.environ['PYTHONHASHSEED'] = '0'
warnings.filterwarnings('ignore')

1.随机森林分类

from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
#数据集导入
iris=datasets.load_iris()
feature=iris.feature_names
X = iris.data
y = iris.target
#随机森林
clf=RandomForestClassifier(n_estimators=200)
train_X,test_X,train_y,test_y = train_test_split(X,y,test_size=0.1,random_state=5)
clf.fit(train_X,train_y)
test_pred=clf.predict(test_X)
#特征的重要性查看
print(str(feature)+'\n'+str(clf.feature_importances_))
#F1-score 用于模型评价
#如果是二分类问题则选择参数‘binary’
#如果考虑类别的不平衡性,需要计算类别的加权平均,则使用‘weighted’
#如果不考虑类别的不平衡性,计算宏平均,则使用‘macro’
score=f1_score(test_y,test_pred,average='macro')
print("随机森林-macro:",score)
score=f1_score(test_y,test_pred,average='weighted')
print("随机森林-weighted:",score)


评分为0.8不算高,但勉强及格,可以看另一个模型的效果。

2.lightGBM模型

import lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.metrics import roc_auc_score, accuracy_score
import matplotlib.pyplot as plt# 加载数据
iris = datasets.load_iris()
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3)
# 转换为Dataset数据格式
train_data = lgb.Dataset(X_train, label=y_train)
validation_data = lgb.Dataset(X_test, label=y_test)
# 参数
results = {}
params = {'learning_rate': 0.1,'lambda_l1': 0.1,'lambda_l2': 0.9,'max_depth': 1,'objective': 'multiclass',  # 目标函数'num_class': 3,'verbose': -1
}
# 模型训练
gbm = lgb.train(params, train_data, valid_sets=(validation_data,train_data),valid_names=('validate','train'),evals_result= results)
# 模型预测
y_pred_test = gbm.predict(X_test)
y_pred_data = gbm.predict(X_train)
y_pred_data = [list(x).index(max(x)) for x in y_pred_data]
y_pred_test = [list(x).index(max(x)) for x in y_pred_test]
# 模型评估
print(accuracy_score(y_test, y_pred_test))
print('训练集',f1_score(y_train, y_pred_data,average='macro'))
print('验证集',f1_score(y_test, y_pred_test,average='macro'))



利用图形查看效果:

# 有以下曲线可知验证集的损失是比训练集的损失要高,所以模型可以判断模型出现了过拟合
lgb.plot_metric(results)
plt.show()

可以尝试将lambda_l2设置为0.9


lgb.plot_metric(results)
plt.show()


绘制重要的特征:

lgb.plot_importance(gbm,importance_type = "split")
plt.show()

lightGBM过拟合处理方案:

  1. 使用较小的 max_bin
  2. 使用较小的 num_leaves
  3. 使用 min_data_in_leaf 和 min_sum_hessian_in_leaf
  4. 通过设置 bagging_fraction 和 bagging_freq 来使用 bagging
  5. 通过设置 feature_fraction 来使用特征子抽样
  6. 使用更大的训练数据
  7. 使用 lambda_l1, lambda_l2 和 min_gain_to_split 来使用正则
  8. 尝试 max_depth 来避免生成过深的树
  9. lightGBM针对更快的训练速度的解决方案
  10. 通过设置 bagging_fraction 和 bagging_freq 参数来使用 bagging 方法
  11. 通过设置 feature_fraction 参数来使用特征的子抽样
  12. 使用较小的 max_bin
  13. 使用 save_binary 在未来的学习过程对数据加载进行加速
  14. 使用并行学习, 可参考 并行学习指南
  15. lightGBM针对更好的准确率
  16. 使用较大的 max_bin (学习速度可能变慢)
  17. 使用较小的 learning_rate 和较大的 num_iterations
  18. 使用较大的 num_leaves (可能导致过拟合)
  19. 使用更大的训练数据
  20. 尝试 dart

3.xgboost模型

from sklearn.datasets import load_iris
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score   # 准确率
# 加载样本数据集
iris = load_iris()
X,y = iris.data,iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565) # 数据集分割
# 算法参数
params = {'booster': 'gbtree','objective': 'multi:softmax','eval_metric':'mlogloss','num_class': 3,'gamma': 0.1,'max_depth': 6,'lambda': 2,'subsample': 0.7,'colsample_bytree': 0.75,'min_child_weight': 3,'eta': 0.1,'seed': 1,'nthread': 4,
}# plst = params.items()train_data = xgb.DMatrix(X_train, y_train) # 生成数据集格式
num_rounds = 500
model = xgb.train(params, train_data) # xgboost模型训练# 对测试集进行预测
dtest = xgb.DMatrix(X_test)
y_pred = model.predict(dtest)# 计算准确率
F1_score = f1_score(y_test,y_pred,average='macro')
print("F1_score: %.2f%%" % (F1_score*100.0))# 显示重要特征
plot_importance(model)
plt.show()

二、交叉验证

交叉验证是验证分类器性能的一种统计分析方法,其基本思想在某种意义下将原始数据进行分组,一部分作为训练集,另一部分作为验证集。首先是用训练集对分类器进行训练,再利用验证集来测试所得到的的模型,以此来作为评价分类器的性能指标。常用的交叉验证方法包括简单交叉验证、K折交叉验证、留一法交叉验证和留P法交叉验证

  1. 简单交叉验证(cross validation)
    简单交叉验证是将原始数据分为两组,一组作为训练集,另一组作为验证集,利用训练集训练分类器,然后利用验证集验证模型,将最后的分类准确率作为此分类器的性能指标。通常是划分30%的数据作为测试数据
  2. K折交叉验证(K-Fold cross validation)
    K折交叉验证是将原始数据分为K组,然后将每个子集数据分别做一次验证集,其余的K-1组子集作为训练集,这样就会得到K个模型,将K个模型最终的验证集的分类准确率取平均值,作为K折交叉验证分类器的性能指标。通常设置为K为5或者10.
  3. 留一法交叉验证(Leave-One-Out Cross Validation,LOO-CV) 留一法交叉验证是指每个训练集由除一个样本之外的其余样本组成,留下的一个样本组成检验集。这样对于N个样本的数据集,可以组成N个不同的训练集和N个不同的验证集,因此该方法会得到N个模型,用N个模型最终的验证集的分类准确率的平均是作为分类器的性能指标。
  4. 留P法交叉验证
    该方法与留一法类似,是从完整数据集中删除P个样本,产生所有可能的训练集和验证集。

1.简单交叉验证

from sklearn.model_selection import train_test_split
from sklearn import datasets
#数据集导入
iris=datasets.load_iris()
feature=iris.feature_names
X = iris.data
y = iris.target
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.4,random_state=0)

2.K折交叉验证

from sklearn.model_selection import KFold
folds = KFold(n_splits=10, shuffle=is_shuffle)

3.留一法交叉验证

from sklearn.model_selection import LeaveOneOut
loo=LeaveOneOut()

4.留P法交叉验证

from sklearn.model_selection import LeavePOut
lpo=LeavePOut(p=5)

三、模型调参

调参就是对模型的参数进行调整,找到使模型最优的超参数,调参的目标就是尽可能达到整体模型的最优。

1. 网格搜索
网格搜索就是一种穷举搜索,在所有候选的参数选择中通过循环遍历去在所有候选参数中寻找表现最好的结果。
2. 学习曲线
学习曲线是在训练集大小不同时通过绘制模型训练集和交叉验证集上的准确率来观察模型在新数据上的表现,进而来判断模型是否方差偏高或偏差过高,以及增大训练集是否可以减小过拟合。

1、当训练集和测试集的误差收敛但却很高时,为高偏差。

左上角的偏差很高,训练集和验证集的准确率都很低,很可能是欠拟合。
我们可以增加模型参数,比如,构建更多的特征,减小正则项。
此时通过增加数据量是不起作用的。

2、当训练集和测试集的误差之间有大的差距时,为高方差。

当训练集的准确率比其他独立数据集上的测试结果的准确率要高时,一般都是过拟合。
右上角方差很高,训练集和验证集的准确率相差太多,应该是过拟合。
我们可以增大训练集,降低模型复杂度,增大正则项,或者通过特征选择减少特征数。
理想情况是是找到偏差和方差都很小的情况,即收敛且误差较小。

3.验证曲线 和学习曲线不同,验证曲线的横轴为某个超参数的一系列值,由此比较不同超参数设置下的模型准确值。从下图的验证曲线可以看到,随着超参数设置的改变,模型可能会有从欠拟合到合适再到过拟合的过程,进而可以选择一个合适的超参数设置来提高模型的性能。

#以Xgboost为例,该网格搜索代码示例如下
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCVcancer = load_breast_cancer()
x = cancer.data[:50]
y = cancer.target[:50]
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0)  # 分训练集和验证集
# 这里不需要Dmatrixparameters = {'max_depth': [5, 10, 15, 20, 25],'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],'n_estimators': [50, 100, 200, 300, 500],'min_child_weight': [0, 2, 5, 10, 20],'max_delta_step': [0, 0.2, 0.6, 1, 2],'subsample': [0.6, 0.7, 0.8, 0.85, 0.95],'colsample_bytree': [0.5, 0.6, 0.7, 0.8, 0.9],'reg_alpha': [0, 0.25, 0.5, 0.75, 1],'reg_lambda': [0.2, 0.4, 0.6, 0.8, 1],'scale_pos_weight': [0.2, 0.4, 0.6, 0.8, 1]
}xlf = xgb.XGBClassifier(max_depth=10,learning_rate=0.01,n_estimators=2000,silent=True,objective='binary:logistic',nthread=-1,gamma=0,min_child_weight=1,max_delta_step=0,subsample=0.85,colsample_bytree=0.7,colsample_bylevel=1,reg_alpha=0,reg_lambda=1,scale_pos_weight=1,seed=1440,missing=None)# 有了gridsearch我们便不需要fit函数
gsearch = GridSearchCV(xlf, param_grid=parameters, scoring='accuracy', cv=3)
gsearch.fit(train_x, train_y)print("Best score: %0.3f" % gsearch.best_score_)
print("Best parameters set:")
best_parameters = gsearch.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):print("\t%s: %r" % (param_name, best_parameters[param_name]))
#极其耗费时间,电脑没执行完

四、智慧海洋数据集模型

lightGBM模型

导入相关库:

import pandas as pd
import numpy as np
from tqdm import tqdm
from sklearn.metrics import classification_report, f1_score
from sklearn.model_selection import StratifiedKFold, KFold,train_test_split
import lightgbm as lgb
import os
import warnings
from hyperopt import fmin, tpe, hp, STATUS_OK, Trials

导入数据:

all_df=pd.read_csv('group_df.csv',index_col=0)

划分训练集和测试集:

use_train = all_df[all_df['label'] != -1]
use_test = all_df[all_df['label'] == -1]#label为-1时是测试集
use_feats = [c for c in use_train.columns if c not in ['ID', 'label']]
X_train,X_verify,y_train,y_verify= train_test_split(use_train[use_feats],use_train['label'],test_size=0.3,random_state=0)

对特征进行特征选择:

##############特征选择参数###################
selectFeatures = 200 # 控制特征数
earlyStopping = 100 # 控制早停
select_num_boost_round = 1000 # 特征选择训练轮次
#首先设置基础参数
selfParam = {'learning_rate':0.01, # 学习率'boosting':'dart', # 算法类型, gbdt,dart'objective':'multiclass', # 多分类'metric':'None','num_leaves':32, # 'feature_fraction':0.7, # 训练特征比例'bagging_fraction':0.8, # 训练样本比例 'min_data_in_leaf':30, # 叶子最小样本'num_class': 3,'max_depth':6, # 树的最大深度'num_threads':8,#LightGBM 的线程数'min_data_in_bin':30, # 单箱数据量'max_bin':256, # 最大分箱数 'is_unbalance':True, # 非平衡样本'train_metric':True,'verbose':-1,
}
# 特征选择 ---------------------------------------------------------------------------------
def f1_score_eval(preds, valid_df):labels = valid_df.get_label()preds = np.argmax(preds.reshape(3, -1), axis=0)scores = f1_score(y_true=labels, y_pred=preds, average='macro')return 'f1_score', scores, Truetrain_data = lgb.Dataset(data=X_train,label=y_train,feature_name=use_feats)
valid_data = lgb.Dataset(data=X_verify,label=y_verify,reference=train_data,feature_name=use_feats)sm = lgb.train(params=selfParam,train_set=train_data,num_boost_round=select_num_boost_round,valid_sets=[valid_data],valid_names=['valid'],feature_name=use_feats,early_stopping_rounds=earlyStopping,verbose_eval=False,keep_training_booster=True,feval=f1_score_eval)
features_importance = {k:v for k,v in zip(sm.feature_name(),sm.feature_importance(iteration=sm.best_iteration))}
sort_feature_importance = sorted(features_importance.items(),key=lambda x:x[1],reverse=True)
print('total feature best score:', sm.best_score)
print('total feature importance:',sort_feature_importance)
print('select forward {} features:{}'.format(selectFeatures,sort_feature_importance[:selectFeatures]))
#model_feature是选择的超参数
model_feature = [k[0] for k in sort_feature_importance[:selectFeatures]]


超参数优化的超参域:

##############超参数优化的超参域###################
spaceParam = {'boosting': hp.choice('boosting',['gbdt','dart']),'learning_rate':hp.loguniform('learning_rate', np.log(0.01), np.log(0.05)),'num_leaves': hp.quniform('num_leaves', 3, 66, 3), 'feature_fraction': hp.uniform('feature_fraction', 0.7,1),'min_data_in_leaf': hp.quniform('min_data_in_leaf', 10, 50,5), 'num_boost_round':hp.quniform('num_boost_round',500,2000,100), 'bagging_fraction':hp.uniform('bagging_fraction',0.6,1)
}
# 超参数优化 ---------------------------------------------------------------------------------
def getParam(param):for k in ['num_leaves', 'min_data_in_leaf','num_boost_round']:param[k] = int(float(param[k]))for k in ['learning_rate', 'feature_fraction','bagging_fraction']:param[k] = float(param[k])if param['boosting'] == 0:param['boosting'] = 'gbdt'elif param['boosting'] == 1:param['boosting'] = 'dart'# 添加固定参数param['objective'] = 'multiclass'param['max_depth'] = 7param['num_threads'] = 8param['is_unbalance'] = Trueparam['metric'] = 'None'param['train_metric'] = Trueparam['verbose'] = -1param['bagging_freq']=5param['num_class']=3 param['feature_pre_filter']=Falsereturn param
def f1_score_eval(preds, valid_df):labels = valid_df.get_label()preds = np.argmax(preds.reshape(3, -1), axis=0)scores = f1_score(y_true=labels, y_pred=preds, average='macro')return 'f1_score', scores, True
def lossFun(param):param = getParam(param)m = lgb.train(params=param,train_set=train_data,num_boost_round=param['num_boost_round'],valid_sets=[train_data,valid_data],valid_names=['train','valid'],feature_name=features,feval=f1_score_eval,early_stopping_rounds=earlyStopping,verbose_eval=False,keep_training_booster=True)train_f1_score = m.best_score['train']['f1_score']valid_f1_score = m.best_score['valid']['f1_score']loss_f1_score = 1 - valid_f1_scoreprint('训练集f1_score:{},测试集f1_score:{},loss_f1_score:{}'.format(train_f1_score, valid_f1_score, loss_f1_score))return {'loss': loss_f1_score, 'params': param, 'status': STATUS_OK}features = model_feature
train_data = lgb.Dataset(data=X_train[model_feature],label=y_train,feature_name=features)
valid_data = lgb.Dataset(data=X_verify[features],label=y_verify,reference=train_data,feature_name=features)best_param = fmin(fn=lossFun, space=spaceParam, algo=tpe.suggest, max_evals=100, trials=Trials())
best_param = getParam(best_param)
print('Search best param:',best_param)



经过特征选择和超参数优化后,最终的模型使用为将参数设置为贝叶斯优化之后的超参数,然后进行5折交叉,对测试集进行叠加求平均。

def f1_score_eval(preds, valid_df):labels = valid_df.get_label()preds = np.argmax(preds.reshape(3, -1), axis=0)scores = f1_score(y_true=labels, y_pred=preds, average='macro')return 'f1_score', scores, Truedef sub_on_line_lgb(train_, test_, pred, label, cate_cols, split,is_shuffle=True,use_cart=False,get_prob=False):n_class = 3train_pred = np.zeros((train_.shape[0], n_class))test_pred = np.zeros((test_.shape[0], n_class))n_splits = 5assert split in ['kf', 'skf'], '{} Not Support this type of split way'.format(split)if split == 'kf':folds = KFold(n_splits=n_splits, shuffle=is_shuffle, random_state=1024)kf_way = folds.split(train_[pred])else:#与KFold最大的差异在于,他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同。folds = StratifiedKFold(n_splits=n_splits,shuffle=is_shuffle,random_state=1024)kf_way = folds.split(train_[pred], train_[label])print('Use {} features ...'.format(len(pred)))#将以下参数改为贝叶斯优化之后的参数params = {'learning_rate': 0.05,'boosting_type': 'gbdt','objective': 'multiclass','metric': 'None','num_leaves': 60,'feature_fraction':0.86,'bagging_fraction': 0.73,'bagging_freq': 5,'seed': 1,'bagging_seed': 1,'feature_fraction_seed': 7,'min_data_in_leaf': 15,'num_class': n_class,'nthread': 8,'verbose': -1,'num_boost_round': 1100,'max_depth': 7,}for n_fold, (train_idx, valid_idx) in enumerate(kf_way, start=1):print('the {} training start ...'.format(n_fold))train_x, train_y = train_[pred].iloc[train_idx], train_[label].iloc[train_idx]valid_x, valid_y = train_[pred].iloc[valid_idx], train_[label].iloc[valid_idx]if use_cart:dtrain = lgb.Dataset(train_x,label=train_y,categorical_feature=cate_cols)dvalid = lgb.Dataset(valid_x,label=valid_y,categorical_feature=cate_cols)else:dtrain = lgb.Dataset(train_x, label=train_y)dvalid = lgb.Dataset(valid_x, label=valid_y)clf = lgb.train(params=params,train_set=dtrain,
#                         num_boost_round=3000,valid_sets=[dvalid],early_stopping_rounds=100,verbose_eval=100,feval=f1_score_eval)train_pred[valid_idx] = clf.predict(valid_x,num_iteration=clf.best_iteration)test_pred += clf.predict(test_[pred],num_iteration=clf.best_iteration) / folds.n_splitsprint(classification_report(train_[label], np.argmax(train_pred,axis=1),digits=4))if get_prob:sub_probs = ['qyxs_prob_{}'.format(q) for q in ['围网', '刺网', '拖网']]prob_df = pd.DataFrame(test_pred, columns=sub_probs)prob_df['ID'] = test_['ID'].valuesreturn prob_dfelse:test_['label'] = np.argmax(test_pred, axis=1)return test_[['ID', 'label']]use_train = all_df[all_df['label'] != -1]
use_test = all_df[all_df['label'] == -1]
# use_feats = [c for c in use_train.columns if c not in ['ID', 'label']]
use_feats=model_feature
sub = sub_on_line_lgb(use_train, use_test, use_feats, 'label', [], 'kf',is_shuffle=True,use_cart=False,get_prob=False)

对智慧海洋数据进行模型建立相关推荐

  1. 【算法竞赛学习】数字中国创新大赛智慧海洋建设-Task4模型建立

    智慧海洋建设-Task4模型建立 此部分为智慧海洋建设竞赛的模型建立模块.在该模块中主要介绍了如何进行模型建立并对模型调优. 学习目标 学习如何选择合适的模型以及如何通过模型来进行特征选择 掌握随机森 ...

  2. 【算法竞赛学习】数字中国创新大赛智慧海洋建设-Task5模型融合

    智慧海洋建设-Task5 模型融合 5.1 学习目标 学习融合策略 完成相应学习打卡任务 5.2 内容介绍 https://mlwave.com/kaggle-ensembling-guide/ ht ...

  3. 【算法竞赛学习】气象海洋预测-Task5 模型建立之 SA-ConvLSTM

    气象海洋预测-Task5 模型建立之 SA-ConvLSTM 该方案中采用的模型是SA-ConvLSTM. 前两个TOP方案中选择将赛题看作一个多输出的任务,通过构建神经网络直接输出24个nino3. ...

  4. 【算法竞赛学习】气象海洋预测-Task4 模型建立之 TCNN+RNN

    气象海洋预测-Task4 模型建立之 TCNN+RNN 该方案中采用的模型是TCNN+RNN. 在Task3中我们学习了CNN+LSTM模型,但是LSTM层的参数量较大,这就带来以下问题:一是参数量大 ...

  5. 对智慧海洋数据进行数据分析

    数据分析 数据获取地址: 链接:https://pan.xunlei.com/s/VMX5JAhFN7ZmPaaCVsHQEVkrA1 提取码:hmtz 一.数据详情 1.导入相关库 #coding: ...

  6. 模型融合(智慧海洋建设为例)

    模型融合(集成)--提高各种 ML 任务准确性的利器 本篇主要源于 Datawhale 智慧海洋建设-Task5 模型融合 最后一次的打卡任务,详细的叙述了关于模型融合的部分知识点. 目录 模型融合( ...

  7. 智慧海洋建设-Task1地理数据分析常用工具

    地理数据分析常用工具 安装geopandas的库时可以参考我的这篇文章<python库geopandas的安装方法>,https://blog.csdn.net/sjjsaaaa/arti ...

  8. 学生酒精消费预警分类模型建立

    本文分析数据是基于这个数据集:https://www.kaggle.com/uciml/student-alcohol-consumption. 1.分析目的和数据集处理 (1)目的 本文希望以两个学 ...

  9. 结构化数据建模——titanic数据集的模型建立和训练(Pytorch版)

    本文参考<20天吃透Pytorch>来实现titanic数据集的模型建立和训练 在书中理论的同时加入自己的理解. 一,准备数据 数据加载 titanic数据集的目标是根据乘客信息预测他们在 ...

最新文章

  1. CSS3支持IE6, 7, and 8的边框属性
  2. java将0到9随机输出_生成0到9之间的随机整数
  3. php arrayaccess 二维,php的ArrayAccess(数组式访问接口)
  4. Codeforces Gym 100650B Countdown (离线)
  5. 日常生活小技巧 -- 虚拟串口工具
  6. 写给准备找工作的同志们!!!!(转载)
  7. Smoothing滤波处理halcon算子,持续更新
  8. static关键字(修饰函数、局部变量、全局变量)
  9. m1 MBA配置Homebrew环境+国内源配置
  10. c语言如何存储已编译内容,二级C语言教程章节测试13.编译预处理和动态存储分配...
  11. 城南云计算中心项目纳入国家储备库
  12. 当spark遇见hbase
  13. cpc客户端紫屏问题解决方法
  14. 看《一人之下:陈朵篇》——架空世界里的真实
  15. PHP合成生成GIF动图
  16. Mac 开启局域网smb文件共享(附全平台连接方法)
  17. JAVA--建立一个可输入个人信息的窗口
  18. (转载)JavaScript:双波浪号“~~“ 与 Math.floor()
  19. EXCEL——图表数据标签——展示两组比较的绝对值和变化率
  20. 一键GHOST的使用方法

热门文章

  1. 推荐一款覆盖足球篮球电竞高清直播源比赛及数据分析的产品
  2. 【Java wrod文档导出 返回浏览器下载读取word文档】文档流转IO流
  3. 弘辽科技:淘宝店铺上下架规则有哪些?规则介绍
  4. MC9S12X系列MCU开发教程第0课:序言
  5. 39、提取人头检测数据集和手机检测,并追加标注手机检测中人头数据
  6. 江西省餐饮油烟治理在线监测平台的研究与应用 油烟监测系统 油烟监测云平台 (安科瑞-须静燕)
  7. 百度地图个性化地图编辑,本地正常,线上失效问题
  8. 3D打印机,固件编程环境
  9. 第27课:Node.js 模块详解
  10. DecimalFormat的用法 Java小数(float、dobule)格式化