一、项目背景

数据来源:使用的是kaggle的一个竞赛数据,具体官网地址为https://www.kaggle.com/c/avazu-ctr-prediction 。
训练和测试数据分别为train.csv和test.csv。官网提供的数据比较大,压缩之后的已经达到1G以上。为了确保可以在本机上无障碍去调模型,在此项目中,我特意去采样了一部分数据。 采样的规则为:从train.csv文件中读取头400000个样本,并重命名为train_subset.csv。 之后在这个数据的基础上我们会进一步分为训练集和测试集。

这个项目的主要的目的是通过给定的广告信息和用户信息来预测一个广告被点击与否。 如果广告有很大概率被点击就展示广告,如果概率低,就不展示。 因为如果广告没有被点击,对双方(广告主、平台)来讲都没有好处。所以预测这个概率非常重要,也是此项目的目标。

在这个项目中,主要做了如下几个方面的工作:

  1. 数据的读取和理解: 把给定的.csv文件读入到内存,并通过pandas做数据方面的统计以及可视化来更深入地理解数据。
  2. 特征构造: 从原始特征中衍生出一些新的特征。
  3. 特征的转化: 特征一般分为连续型(continuous)和类别型(categorical), 需要分别做不同的处理。
  4. 特征选择: 从已有的特征中选择合适的特征。
  5. 模型训练与评估: 通过交叉验证方式来训练模型,使用到了网格搜索的技术。

二、数据的读取

# 导入基本的库,每个项目的必备
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import f1_score
from sklearn.metrics import classification_report
from sklearn.tree import DecisionTreeClassifier
from xgboost import XGBClassifier
import warnings
#将warning过滤掉
warnings.filterwarnings('ignore')
# 设置matplotlib的模式
%matplotlib inline
# 设置matplot的样式
matplotlib.style.use('ggplot')
#导入成功
print('导入成功!')
data_df = pd.read_csv("./train.csv",nrows=400000)
data_df.head()

在写入csv文件的时候,默认会自动加入新的一列,Unnamed,
解决方案:to_csv()时候,设置index=False。或者加上index=True, index_label=“id”

# 将读出来的数据保存为新表
data_df.to_csv("train_subset.csv",index=False)
# 通过pandas读取.csv文件,并展示头几个样本。
data_df = pd.read_csv('train_subset.csv')
#展示前五个样本
data_df.head()

data_df.shape
(400000, 24)
# 查看一下每一个特征的类型以及是否存在null
data_df.info(null_counts=True)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000000 entries, 0 to 999999
Data columns (total 24 columns):
id                  1000000 non-null float64
click               1000000 non-null int64
hour                1000000 non-null int64
C1                  1000000 non-null int64
banner_pos          1000000 non-null int64
site_id             1000000 non-null object
site_domain         1000000 non-null object
site_category       1000000 non-null object
app_id              1000000 non-null object
app_domain          1000000 non-null object
app_category        1000000 non-null object
device_id           1000000 non-null object
device_ip           1000000 non-null object
device_model        1000000 non-null object
device_type         1000000 non-null int64
device_conn_type    1000000 non-null int64
C14                 1000000 non-null int64
C15                 1000000 non-null int64
C16                 1000000 non-null int64
C17                 1000000 non-null int64
C18                 1000000 non-null int64
C19                 1000000 non-null int64
C20                 1000000 non-null int64
C21                 1000000 non-null int64
dtypes: float64(1), int64(14), object(9)
memory usage: 183.1+ MB

hour数据类型转换

# TODO 把hour特征格式化成 '%y%m%d%H'形式。
#将hour数据由整型转换为字符串
data_df['hour'].astype(str)
#使用to_datetime方法,将hour特征由字符串转换为datetime数据格式,format设置为%y%m%d%H'
data_df['hour'] = pd.to_datetime(data_df['hour'],format='%y%m%d%H')
#显示转换后的hour
data_df['hour'].unique()
array(['2014-10-21T00:00:00.000000000', '2014-10-21T01:00:00.000000000','2014-10-21T02:00:00.000000000'], dtype='datetime64[ns]')
# 重新打印一下是否有改变
data_df.head()


分两次展示所有特征

data_df.iloc[:, :12].head()

data_df.iloc[:, 12:].head()


从上述数据中,发现大量的特征为类别型特征,而且很多特征已经被编码成看不懂的字符串(这些都是为了不公开用户数据),但即便如此,也可以把它们直接看成是类别型特征。

三、数据的理解

id

len(data_df['id'].unique())
400000

说明该特征没有意义,予以删除

#删除id列
data_df.drop('id',axis=1,inplace=True)
#重新查看数据
data_df.head()

click
对标签分布的理解是必不可少的,因为这直接跟样本不平衡相关。

#提取标签中0和1的数量,并存入df_click中
df_click = data_df['click'].value_counts()
#打印结果
print(df_click)
#计算1、0的占比
pos_proportion = df_click[1]/(df_click[1] + df_click[0])
neg_proportion = df_click[0]/(df_click[1] + df_click[0])
#打印结果
print('正样本比例为:%.2f'%(pos_proportion))
print('负样本比例为:%.2f'%(neg_proportion))
0    333644
1     66356
Name: click, dtype: int64
正样本比例为:0.17
负样本比例为:0.83
#可视化结果
plt.figure(figsize=(10,6))
df_click.plot(kind = 'bar', width = 0.2, rot = 0)
plt.title('正负样本分布',fontsize=16)
# 添加y轴标签
plt.ylabel('样本数量',fontsize=14)
# 为每个条形图添加数值标签
for x,y in enumerate(df_click.values):plt.text(x,y+1000,'%s'%y,ha='center',fontsize=13)
plt.savefig('./图片1')


通过上述的数据,可以很容易看出被点击的次数要远小于没有被点击的次数。所以这个数据是不平衡的数据。但这个不平衡还没有那么严重。其实不平衡严重时,负样本和正样本比例有可能1000:1, 甚至更悬殊。 由于样本的不平衡,使用准确率是不明智的,所以评估指标我们选用F1-score.

hour

count                  400000
unique                      3
top       2014-10-21 02:00:00
freq                   143552
first     2014-10-21 00:00:00
last      2014-10-21 02:00:00
Name: hour, dtype: object

从上述的结果中可以看到,时间的区间为10-21的00点到10-21的02点,也就是2个小时的间隔。所以在使用这个特征的时候,可以把小时的特征提取出来,因为日期都是一样的

banner_pos
这是广告投放的位置,从直观上来看对广告点击的结果影响比较大,所以做一下可视化的分析并更好地理解这个特征。首先来看一下banner_pos的取值范围

data_df['banner_pos'].value_counts()
0    316027
1     83440
5       363
2       122
7        33
4        15
Name: banner_pos, dtype: int64
Name: banner_pos, dtype: int64

这个结果里可以看出,它的范围是0-7, 但中间不包含3和6。 对于这些数据请不要理所当然地理解为它表示的是具体的位置信息,比如1代表最前面的位置… 因为我们也不知道它的编码规则是怎么样的。但不管怎样,我们可以通过可视化方式来大概了解一下每一个位置对点击率的影响。

data_df.shape
(400000, 23)
#将data_df按照banner_pos分组(分成0、1、2、4、5、7六个组),并对每组中click(0、1)计数
df_banner = data_df.groupby('banner_pos')['click'].value_counts().unstack()
#展示分组计数后的结果
df_banner

#可视化结果
df_banner.plot(kind = 'bar',figsize = (10,6),colormap = 'summer',width = 0.5,grid = True,stacked = True,alpha = 0.75,title = 'Visualization of Banner Position and Click Events',rot=0)
plt.savefig('./图片')


由于该特征分布不均衡,所以应该可视化百分比,而不是数量

#在df_banner中创建sum列,为每个banner_pos种类的点击数量总和
df_banner['sum'] = df_banner[0] + df_banner[1]
#计算点击0的概率,并重新传给df_banner[0]
df_banner[0] = df_banner[0]/df_banner['sum']
#计算点击1的概率,并重新传给df_banner[1]
df_banner[1] = df_banner[1]/df_banner['sum']
#删除sum列
df_banner.drop('sum',axis=1,inplace=True)
#展示最终占比结果
df_banner

#可视化结果
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use("ggplot")
df_banner.plot(kind = 'bar',figsize = (10,6),colormap="summer",rot=0,width = 0.5,stacked = True,alpha = 0.8,title = '各位置广告被点击概率')
plt.savefig('./图片2')


site相关特征

site_features = ['site_id', 'site_domain', 'site_category']
data_df[site_features].describe()


app相关特征

app_features = ['app_id', 'app_domain', 'app_category']
data_df[app_features].describe()


这里重点研究一下,app_category特征,看是否跟标签有比较强的关系。 为了理解这一点,对于每一种类型的app_category值,请画出histogram,展示每一种取值条件下样本被点击或者没有被点击的概率。

#将data_df按照app_category分组,并对每组中点击数(click值为0、1)计数
df_appCategory = data_df.groupby('app_category')['click'].value_counts().unstack()
#将数据中NaN替换为0
df_appCategory.fillna(0,inplace=True)
#在df_appCategory中创建sum列,为每个app_category种类的点击数总和
df_appCategory['sum'] = df_appCategory[0] + df_appCategory[1]
#计算0的概率,并重新传给df_appCategory[0]
df_appCategory[0] = df_appCategory[0]/df_appCategory['sum']
#计算1的概率,并重新传给df_appCategory[1]
df_appCategory[1] = df_appCategory[1]/df_appCategory['sum']
#删除sum列
df_appCategory.drop('sum',axis=1,inplace=True)
#展示df_appCategory
df_appCategory

#可视化结果
df_appCategory.plot(kind = 'bar',figsize = (10,6),colormap = 'summer',width = 0.5,stacked = True,alpha = 0.8,title = 'CTR for app_category feature')
plt.savefig('./图片3')

device相关的特征

device_features = ['device_id', 'device_ip', 'device_model', 'device_type', 'device_conn_type']
data_df[device_features].astype('object').describe()

#将data_df按照device_conn_type分组,并对每组中点击数(click值为0、1)计数
df_deviceConnType = data_df.groupby(by='device_conn_type')['click'].value_counts().unstack()
#在df_deviceConnType中创建sum列,为每个device_conn_type种类的点击数总和
df_deviceConnType['sum'] = df_deviceConnType[0] + df_deviceConnType[1]
#计算点击0的概率,并将结果重新传给df_deviceConnType[0]
df_deviceConnType[0] = df_deviceConnType[0]/df_deviceConnType['sum']
#计算点击1的概率,并将结果重新传给df_deviceConnType[1]
df_deviceConnType[1] = df_deviceConnType[1]/df_deviceConnType['sum']
#删除sum列
del df_deviceConnType['sum']
#展示结果
df_deviceConnType

#可视化结果
df_deviceConnType.plot(kind='bar',figsize=(10,6),colormap='summer',width = 0.3,grid = True,stacked = True,alpha = 0.8,title = 'CTR for device_conn_type feature',rot=0)
plt.savefig('./图片4')


C1, C14-C21 特征
这些特征没有具体被标记到底是什么意思,有可能是涉及到公司的隐私。 当然,理解一个特征的含义其实挺重要的,但对于这个问题没办法,毕竟他们没有提供描述。但无论如何,也可以通过可视化分析去理解这些特征是否影响点击率。

c_features = ['C1', 'C14', 'C15', 'C16', 'C17', 'C18', 'C19', 'C20', 'C21']
data_df[c_features].astype('object').describe()

#将data_df按照C1分组,并对每组中点击数(click值为0、1)计数
df_C1 = data_df.groupby(by='C1')['click'].value_counts().unstack()
#将df_C1创建sum列,为每个C1种类的点击数总和
df_C1['sum'] = df_C1[0] + df_C1[1]
#计算点击0的概率,并将结果重新传给df_C1[0]
df_C1[0] = df_C1[0]/df_C1['sum']
#计算点击1的概率,并将结果重新传给df_C1[1]
df_C1[1] = df_C1[1]/df_C1['sum']
#删除sum列
del df_C1['sum']
#展示结果
df_C1

#可视化结果
df_C1.plot(kind='bar',figsize=(10,6),colormap='summer',width = 0.5,stacked = True,alpha = 0.8,title = 'CTR for C1 feature',rot=0)
plt.savefig('./图片5')

四、特征的构造

特征构造对于一个机器学习建模非常重要。它的意思就是基于原有给定的特征基础上构造一些新的特征。构造特征的方法有很多: 1. 在原有的特征基础上做一些转换从而提取特征 2. 不同特征之间利用常规的运算来构造更复杂的特征(比如有特征f1, f2, 则可以通过f1 * f2操作生成新的特征)。

转换hour特征

data_df["hour"] = data_df["hour"].astype("category").cat.codes
data_df.head(5)


独热编码

# 由于这些特征的稀疏性,从特征库中去掉。 但如果计算资源允许,可以加入进来。
data_df.drop('device_id', axis=1, inplace=True)
data_df.drop('device_ip', axis=1, inplace=True)
data_df.drop('device_model', axis=1, inplace=True)
data_df.drop('site_id', axis=1, inplace=True)
data_df.drop('site_domain', axis=1, inplace=True)
data_df.drop('app_id', axis=1, inplace=True)
#选择data_df中除click外的所有特征进行独热编码转换
columns = data_df.columns[1:]
#调用pandas的get_dummies方法进行独热编码转换
data_df = pd.get_dummies(data_df,columns=columns)
#展示转换结果
data_df.shape
(400000, 1077)
# 构造训练数据和测试数据
feature_names = data_df.columns[data_df.columns != 'click']
#构造样本数据
X_sample = data_df[feature_names].values
y_sample = data_df['click'].values
#将样本数据分为训练及测试数据集,将stratify参数设置为y_sample,按照y_sample中的0、1比例分配
X_train, X_test, y_train, y_test = train_test_split(X_sample,y_sample,test_size=0.25,random_state=2019,stratify=y_sample)
#打印训练及测试数据形状
print (X_train.shape, X_test.shape, y_train.shape, y_test.shape)

五、特征选择

这里使用的模型是逻辑回归 + L1的正则。 我们都知道L1正则会产生稀疏解,相当于帮我们选出特征。具体的方法是: 对于每一种可能的C值(代表正则的强弱)做交叉验证,从中选择效果最好的C值, 而且对于这个C值,我们有对应的选出来的特征。

# 重新导入一下各种包(主要是练习一下)
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import f1_score
from sklearn.model_selection import KFold
model.fit(X_train,y_train)
GridSearchCV(cv=KFold(n_splits=4, random_state=None, shuffle=False),error_score='raise-deprecating',estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='warn',n_jobs=None, penalty='l1', random_state=None, solver='warn',tol=0.0001, verbose=0, warm_start=False),fit_params=None, iid='warn', n_jobs=3,param_grid={'C': array([1.00000e-04, 3.59381e-04, 1.29155e-03, 4.64159e-03, 1.66810e-02,5.99484e-02, 2.15443e-01, 7.74264e-01, 2.78256e+00, 1.00000e+01])},pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',scoring=None, verbose=0)
print(model.best_params_)
{'C': 0.05994842503189409}
# 通过最好的惩罚项系数,重新在整个X_train里做训练,并选出特征
c_best = model.best_params_["C"]
lr_clf = LogisticRegression(penalty="l1",C=c_best)
lr_clf.fit(X_train, y_train)select_model = SelectFromModel(lr_clf,prefit=True)
select_features = select_model.get_support() # 被选出来的特征
关于SelectFromModel可以参考这篇链接:[添加链接描述](https://zhuanlan.zhihu.com/p/72092241)
# 重新构造feature_names
feature_names = feature_names[select_features]
# 重新构造训练数据和测试数据
X_train = X_train[:,select_features]
X_test = X_test[:,select_features]#打印新数据特征数量
print(X_train.shape)
print(X_test.shape)
(300000, 144)
(100000, 144)

六、模型训练与评估

6.1 使用逻辑回归模型

在我们选择特征的时候其实也用了逻辑回归,但选特征的时候用的是L1的正则。但是在真正来训练最终版本模型的时候我们通常都是使用L2正则。

params_c_l2 = np.logspace(-5,2,10)
#创建逻辑回归模型,penalty取l2正则,solver选择liblinear,class_weight选择balanced
lr_clf_l2 = LogisticRegression(penalty='l2',solver='liblinear',class_weight='balanced')
#需要优化的参数取值
param_grid_l2 = {'C':params_c_l2}
#通过GridSearchCV进行5折交叉验证,评价标准为f1_score
grid_l2 = GridSearchCV(estimator=lr_clf_l2,param_grid=param_grid_l2,cv=5,scoring='f1')
#进行网格搜索
grid_l2.fit(X_train,y_train)
#用grid.best_params_方法得到最佳参数,并打印展示
print('最佳参数是:{}'.format(grid_l2.best_params_))
#用grid.best_score_方法得到最佳得分,并打印展示
print('最佳得分是:{}'.format(grid_l2.best_score_))
#用grid.best_estimator_方法得到最佳模型,并打印展示
print('最佳模型是:{}'.format(grid_l2.best_estimator_))
最佳参数是:{'C': 100.0}
最佳得分是:0.38442188804689237
最佳模型是:LogisticRegression(C=100.0, class_weight='balanced', dual=False,fit_intercept=True, intercept_scaling=1, max_iter=100,multi_class='warn', n_jobs=None, penalty='l2', random_state=None,solver='liblinear', tol=0.0001, verbose=0, warm_start=False)
#建立最佳模型
model_l2 = grid_l2.best_estimator_
#通过测试数据进行预测
predictions_l2 = model_l2.predict(X_test)
#得出测试结果,生成报告
print(classification_report(y_test, predictions_l2))precision    recall  f1-score   support0       0.92      0.58      0.71     834111       0.26      0.73      0.38     16589micro avg       0.60      0.60      0.60    100000macro avg       0.59      0.66      0.54    100000
weighted avg       0.81      0.60      0.65    100000

6.2 使用决策树模型

#创建决策树模型
dt_clf = DecisionTreeClassifier(class_weight='balanced')
# 用于指定根节点或中间节点能够继续分割的最小样本量
params_min_samples_split = [5,10,15,20]
#叶子节点所需的最小样本数
params_min_samples_leaf = [2,4,6,8,10]
#树的最大深度
params_max_depth = [4,6,8,10]
#创建参数网格
param_grid_dt = {'min_samples_split' : params_min_samples_split,'min_samples_leaf' : params_min_samples_leaf,'max_depth' : params_max_depth}
#通过GridSearchCV进行5折交叉验证
grid_dt = GridSearchCV(estimator=dt_clf,param_grid=param_grid_dt,cv=5,scoring='f1')
#进行网格搜索
grid_dt.fit(X_train,y_train)
#用grid.best_params_方法得到最佳参数,并打印展示
print('最佳参数是:{}'.format(grid_dt.best_params_))
#用grid.best_score_方法得到最佳得分,并打印展示
print('最佳得分是:{}'.format(grid_dt.best_score_))
#用grid.best_estimator_方法得到最佳模型,并打印展示
print('最佳模型是:{}'.format(grid_dt.best_estimator_))
最佳参数是:{'max_depth': 10, 'min_samples_leaf': 10, 'min_samples_split': 20}
最佳得分是:0.38866377057923884
最佳模型是:DecisionTreeClassifier(class_weight='balanced', criterion='gini',max_depth=10, max_features=None, max_leaf_nodes=None,min_impurity_decrease=0.0, min_impurity_split=None,min_samples_leaf=10, min_samples_split=20,min_weight_fraction_leaf=0.0, presort=False, random_state=None,splitter='best')
#建立最佳模型
model_dt = grid_dt.best_estimator_
#通过测试数据进行预测
predictions_dt = model_dt.predict(X_test)
#得出测试结果,生成报告
print(classification_report(y_test, predictions_dt))precision    recall  f1-score   support0       0.91      0.61      0.73     834111       0.27      0.71      0.39     16589micro avg       0.62      0.62      0.62    100000macro avg       0.59      0.66      0.56    100000
weighted avg       0.81      0.62      0.67    100000

6.3 使用XGBoost做分类

#创建xgboost模型,booster为gbtree,学习率设为0.1
#由于样本中1和0的占比接近于1比5,将scale_pos_weight设为5
xgb_clf = XGBClassifier(objective ='binary:logistic',booster='gbtree',n_jobs=-1,learning_rate=0.1,scale_pos_weight=5)
#树的深度
params_max_depth = [4,6,8,10]
#树的个数
params_n_estimators = [100,200,300,400]
#训练每棵树时,使用的特征占全部特征的比例
params_colsample_bytree = [0.3,0.5,0.7,0.9]
#训练每棵树时,使用的样本占全部特征的比例
params_subsample = [0.3,0.5,0.7,0.9]
#创建参数网格
param_grid_xgb = {'max_depth' : params_max_depth,'n_estimators' : params_n_estimators,'colsample_bytree' : params_colsample_bytree,'subsample' : params_subsample}
#通过GridSearchCV进行5折交叉验证,评价标准为f1_score
grid_xgb = GridSearchCV(estimator=xgb_clf,param_grid=param_grid_xgb,cv=5,scoring='f1')
#进行网格搜索
grid_xgb.fit(X_train,y_train)
#用grid.best_params_方法得到最佳参数,并打印展示
print('最佳参数是:{}'.format(grid_xgb.best_params_))
#用grid.best_score_方法得到最佳得分,并打印展示
print('最佳得分是:{}'.format(grid_xgb.best_score_))
#用grid.best_estimator_方法得到最佳模型,并打印展示
print('最佳模型是:{}'.format(grid_xgb.best_estimator_))
#建立最佳模型
model_xgb = grid_xgb.best_estimator_
#通过测试数据进行预测
predictions_xgb = model_xgb.predict(X_test)
#得出测试结果,生成报告
print(classification_report(y_test, predictions_xgb))

由于自己的笔记本电脑计算能力有限,上述交叉验证执行了很长时间没有结果(即使是在调用了电脑所有的cpu的情况下),等有时间我将减少一些参数重新运行一下。

广告点击率预测(kaggle)相关推荐

  1. 广告点击率预测 [离线部分]

    广告点击率预测 [离线部分] 2014-05-08 23:08:45|  分类: 计算广告学 |  标签:计算广告学  rtb  dsp  |举报|字号 订阅 下载LOFTER我的照片书  | 广告点 ...

  2. 广告点击率预测问题初探

    广告点击率预测问题初探 国庆7天参加了一个广告点击率预测的小竞赛,作为只看过机器学习实战的小白,纯粹抱着学习的心态去开眼,果然被大神按在地上虐呢,不过也学到了很多知识.感谢很多大佬都开源并分享了他们的 ...

  3. python广告点击率预测_推荐系统中的点击率预估 – Advertising Recommendation

    推荐系统的框架模式大致是:多种召回策略(触发层),一种融合排序策略(排序层),也可认为两阶段排序模型[33]: 召回策略方法繁多(例如常见的协同过滤中的item-based,user-based,以及 ...

  4. 广告点击率预测-项目介绍

    项目介绍 项目介绍 KDD CUP 2012 Track2 1.给定查询和用户信息后预测广告点击率 搜索广告是近年来互联网的主流营收来源之一.在搜索广告背后,一个关键技术就是点击率预测-–pCTR(p ...

  5. 广告点击率预测_精品案例|在线广告点击率预测

    目录 数据说明 数据查看 数据预处理   3.1 处理非数值特征 初步建立模型查看效果 探索性分析和特征工程   5.1 特征分布可视化   5.2 处理取值不均匀特征   5.3 特征相关性 模型训 ...

  6. spark mllib实现 广告点击率预测

    本文尝试使用Spark提供的机器学习算法 Gradient-Boosted Trees来预测一个用户是否会点击广告. 训练和测试数据使用Kaggle Avazu CTR 比赛的样例数据,下载地址:ht ...

  7. 广告点击率预测_用于广告点击率预测的逻辑回归你会了吗?

    随着计算能力的大幅提升,AI的热潮只涨不跌,监督学习.无监督学习耳熟能详,一时间很多人都投身ML.DL,形形色色.我之前也是学过一点相关算法,蓝皮书和Ng大佬的课程也假装刷过,回归.分类.神经网络也都 ...

  8. 分享Spark MLlib训练的广告点击率预测模型

    2015年,全球互联网广告营收接近600亿美元,比2014年增长了近20%.多家互联网巨头都依赖于广告营收,如谷歌,百度,Facebook,互联网新贵们也都开始试水广告业,如Snapchat, Pin ...

  9. kaggle案例:广告点击率预估+LR

    一.业务背景 传统广告与在线广告区别? 传统广告: 类似电视广告,报纸媒体.杂志.广播.户外媒体等. 在线广告: 类似百度搜索广告,facebook页面展示广告. 区别:在线广告更多与用户相关,例,在 ...

最新文章

  1. 技术图文:C# 语言中的扩展方法
  2. mysql noinstall_免安装版MySql安装与配置
  3. 万方数据知识平台 TFHpple +Xpath解析
  4. ABP领域层——工作单元
  5. python命名空间(五分钟读懂)
  6. mysql分组统计查询 张三_MySQL 怎样分组查询
  7. linux中指令简约版
  8. 14.6.4 Configuring the Memory Allocator for InnoDB 配置InnoDB 内存分配器
  9. 对象取值操作Object.values()
  10. i3能装Linux虚拟机,使用i3wm重新安装Ubuntu
  11. n986原生android,【极光ROM】-【三星NOTE20U(国行/港版/台版/韩版/美版) N986X-高通865P】-【V4.0 Android-R-UA3】...
  12. 几种不同的json格式解析
  13. 【Rust日报】2022-09-13 Stabilize GAT
  14. matlab 非线性方程组 最小值,如何在matlab中求解非线性方程组的参数值
  15. 平台建设的7大问题:蚂蚁AI平台实践深度总结
  16. 在photoshop中,从1寸到24寸的大小是多少
  17. 2021多益网络春季校园招聘游戏研发笔试题(回忆版)
  18. 【Win 10应用开发】如何知道UAP在哪个平台上运行
  19. 励志!从职高到杭电、浙大、MIT计算机博士!
  20. 信息安全导论 实验四 RSA算法(不要求支持大数)

热门文章

  1. 我玩《盟军敢死队》的后遗症
  2. html页面引入ts文件,如何将ts文件中收到的参数显示到html页面
  3. 一、HTTPS详解SSL TLS
  4. 【带你装逼带你飞】吐血总结了这五大常用算法技巧,让你在同事/面试官面前惊艳全场!
  5. canvas绘制2048游戏的背景
  6. 用计算机解锁ipad密码忘了怎么办,iPad密码忘记了怎么办?分享解决办法给你
  7. uni-app text、文本、selectable、自定义长按选择菜单、修改系统菜单键(双端)
  8. 《深入设计模式》笔记 -创建型模式二、工厂方法模式
  9. 技术派-IEEE standard for floating-point arithmetic
  10. MXNet中使用卷积神经网络textCNN对文本进行情感分类