关于用户新增预测
数据收集:收集与用户新增相关的数据。包括用户的基本信息(如年龄、性别、地理位置等)、行为数据(如浏览历史、购买记录等)以及时间序列数据(如用户注册日期、活跃度等)。
数据预处理:在构建模型之前对数据进行预处理。这可能包括缺失值处理、异常值处理、数据标准化、特征选择等。确保数据集是准确、完整和一致的。
特征工程:根据业务需求和数据特点,提取有意义的特征。包括基于统计的方法(如相关系数、协方差等)或基于领域知识的方法(如聚类分析、主成分分析等)。
选择模型:根据问题类型(如回归、分类等)和数据特点,选择合适的预测模型。包括线性回归、决策树、随机森林、支持向量机、神经网络等。对于时间序列数据,还可以考虑使用ARIMA、LSTM等模型。
训练模型:将数据集划分为训练集和测试集,使用训练集对模型进行训练。在训练过程中,需要调整模型的超参数以获得最佳性能。
模型评估:使用测试集对模型进行评估,以确定模型的准确性、召回率、F1分数等指标。如果模型的性能不佳,可以尝试更换模型或调整超参数。
预测用户新增情况:使用训练好的模型对未来的用户新增情况进行预测。可以将预测结果可视化以便更好地理解模型的预测能力。
模型更新:随着时间的推移,需要定期更新模型以适应用户行为的变化。可以通过重新训练模型或使用在线学习算法来实现。
2.1:数据分析与可视化
8月19日,进行数据探索。
实践步骤:
- 导入必要的库,特别是画图库。
- 计算特征与标签之间的相关性,展示热力图。
- 展示特征与标签分组统计tu。
# 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 读取训练集和测试集文件
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')
# 相关性热力图
sns.heatmap(train_data.corr().abs(), cmap='YlOrRd')
# x7分组下标签均值
sns.barplot(x='x7', y='target', data=train_data)
读取训练集和测试集数据,然后绘制训练集数据的相关性热力图以及x7分组下标签均值的柱状图。
下面是研究时的运行过程:
- 使用seaborn库的heatmap函数绘制训练集数据的相关性热力图,其中cmap参数设置为'YlOrRd'表示使用黄绿色调。
- 使用seaborn库的barplot函数绘制x7分组下标签均值的柱状图,其中x参数设置为'x7',y参数设置为'target',数据来源为train_data。
2.2:模型交叉验证
8月20日,探索不同模型的精度。
实操步骤:
- 加载数据集,并对数据进行编码
- 导入多个模型进行交叉验证
- 比较模型的F1精度
解决问题:
- 字段x1至x8为用户相关的属性,为匿名处理字段。添加代码对这些数据字段的取值分析,那些字段为数值类型?那些字段为类别类型?
分析可得,x1, x2, x3, x4, x5, x6, x7, x8为类别类型,x3,x4,x5为数值类型
- 从common_ts中提取小时,绘制每小时下标签分布的变化。
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6),dpi=80)
train_data['common_ts'] = pd.to_datetime(train_data['common_ts'], unit='ms')
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
sns.countplot(x="common_ts_hour",hue='target', data=train_data,ax = axes[0])
new_df = (train_data.groupby('common_ts_hour')['target']
.value_counts(normalize=True)
.sort_index()
.unstack()
)
new_df.plot.bar(stacked=True,ax = axes[1])
- 对udmap进行onehot,统计每个key对应的标签均值,绘制直方图。
# 导入库
import pandas as pd
import numpy as np
# 读取训练集和测试集文件
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')
# 提取udmap特征,人工进行onehot
def udmap_onethot(d):
v = np.zeros(9)
if d == 'unknown':
return v
d = eval(d)
for i in range(1, 10):
if 'key' + str(i) in d:
v[i-1] = d['key' + str(i)]
return v
train_udmap_df = pd.DataFrame(np.vstack(train_data['udmap'].apply(udmap_onethot)))
test_udmap_df = pd.DataFrame(np.vstack(test_data['udmap'].apply(udmap_onethot)))
train_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
test_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
# 编码udmap是否为空
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)
# udmap特征和原始数据拼接
train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)
# 提取eid的频次特征
train_data['eid_freq'] = train_data['eid'].map(train_data['eid'].value_counts())
test_data['eid_freq'] = test_data['eid'].map(train_data['eid'].value_counts())
# 提取eid的标签特征
train_data['eid_mean'] = train_data['eid'].map(train_data.groupby('eid')['target'].mean())
test_data['eid_mean'] = test_data['eid'].map(train_data.groupby('eid')['target'].mean())
# 提取时间戳
train_data['common_ts'] = pd.to_datetime(train_data['common_ts'], unit='ms')
test_data['common_ts'] = pd.to_datetime(test_data['common_ts'], unit='ms')
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour
# 导入模型
from sklearn.linear_model import SGDClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import MultinomialNB
from sklearn.ensemble import RandomForestClassifier
# 导入交叉验证和评价指标
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import classification_report
# 训练并验证SGDClassifier
pred = cross_val_predict(
SGDClassifier(max_iter=10),
train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))
# 训练并验证DecisionTreeClassifier
pred = cross_val_predict(
DecisionTreeClassifier(),
train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))
# 训练并验证MultinomialNB
pred = cross_val_predict(
MultinomialNB(),
train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))
# 训练并验证RandomForestClassifier
pred = cross_val_predict(
RandomForestClassifier(n_estimators=5),
train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
train_data['target']
)
print(classification_report(train_data['target'], pred, digits=3))
读取训练集和测试集数据,并对数据进行预处理,包括提取udmap特征、编码udmap是否为空、提取eid的频次特征和标签特征、提取时间戳等。然后导入模型(SGDClassifier、DecisionTreeClassifier、MultinomialNB、RandomForestClassifier),并使用交叉验证和评价指标对模型进行训练和验证。最后输出各个模型的分类报告。
最初在pycharm本地环境下运行:
编写代码回答下面的问题:
- 在上面模型中哪一个模型的macro F1效果最好,为什么这个模型效果最好?
可以看出决策树的F1分数最好。在决策树中,macro F1效果最好的原因是因为macro F1是一种宏观指标,它可以同时考虑模型在各个类别上的性能,而不仅仅是在某个特定类别上的性能。macro F1还可以用于比较不同模型之间的性能,因为它可以消除不同模型在不同类别上的性能差异对总体性能的影响。
- 使用树模型训练,然后对特征重要性进行可视化;
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf.fit(
train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1), # 特征数据:移除指定的列作为特征
train_data['target']
)
# s树的特征重要性可视化
def plot_feature_importances_cancer(model):
n_features = train_data.shape[1]-4
plt.barh(range(n_features),model.feature_importances_,align = 'center')
plt.yticks(np.arange(n_features),train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1).columns)
plt.xlabel("Feature importance")
plt.ylabel("Feature")
plot_feature_importances_cancer(clf)
- 再加入3个模型训练,对比模型精度;
加入3个模型训练,对比模型精度。这里分别采用默认参数的岭回归分类器、极度随机树和梯度提升树进行训练运行得到如下:
2.3:特征工程
8月22日,探索不同特征的效果。
实操步骤:
common_ts_day
特征:从时间戳common_ts
中提取出日期部分的天数,以创建一个新的特征表示访问日期。x1_freq
和x1_mean
特征:计算特征x1
在训练集中的频次(出现次数)以及在训练集中对应的目标列target
的均值。这些特征可以捕捉x1
特征的重要性和与目标的关系。- 类似地,对于其他
x2
、x3
、x4
、x6
、x7
和x8
特征,进行了类似的操作,分别计算它们在训练集中的频次和均值。
train_data['common_ts_day'] = train_data['common_ts'].dt.day
test_data['common_ts_day'] = test_data['common_ts'].dt.day
train_data['x1_freq'] = train_data['x1'].map(train_data['x1'].value_counts())
test_data['x1_freq'] = test_data['x1'].map(train_data['x1'].value_counts())
train_data['x1_mean'] = train_data['x1'].map(train_data.groupby('x1')['target'].mean())
test_data['x1_mean'] = test_data['x1'].map(train_data.groupby('x1')['target'].mean())
train_data['x2_freq'] = train_data['x2'].map(train_data['x2'].value_counts())
test_data['x2_freq'] = test_data['x2'].map(train_data['x2'].value_counts())
train_data['x2_mean'] = train_data['x2'].map(train_data.groupby('x2')['target'].mean())
test_data['x2_mean'] = test_data['x2'].map(train_data.groupby('x2')['target'].mean())
train_data['x3_freq'] = train_data['x3'].map(train_data['x3'].value_counts())
test_data['x3_freq'] = test_data['x3'].map(train_data['x3'].value_counts())
train_data['x4_freq'] = train_data['x4'].map(train_data['x4'].value_counts())
test_data['x4_freq'] = test_data['x4'].map(train_data['x4'].value_counts())
train_data['x6_freq'] = train_data['x6'].map(train_data['x6'].value_counts())
test_data['x6_freq'] = test_data['x6'].map(train_data['x6'].value_counts())
train_data['x6_mean'] = train_data['x6'].map(train_data.groupby('x6')['target'].mean())
test_data['x6_mean'] = test_data['x6'].map(train_data.groupby('x6')['target'].mean())
train_data['x7_freq'] = train_data['x7'].map(train_data['x7'].value_counts())
test_data['x7_freq'] = test_data['x7'].map(train_data['x7'].value_counts())
train_data['x7_mean'] = train_data['x7'].map(train_data.groupby('x7')['target'].mean())
test_data['x7_mean'] = test_data['x7'].map(train_data.groupby('x7')['target'].mean())
train_data['x8_freq'] = train_data['x8'].map(train_data['x8'].value_counts())
test_data['x8_freq'] = test_data['x8'].map(train_data['x8'].value_counts())
train_data['x8_mean'] = train_data['x8'].map(train_data.groupby('x8')['target'].mean())
test_data['x8_mean'] = test_data['x8'].map(train_data.groupby('x8')['target'].mean())
对数据进行预处理,包括提取特定列的频次特征和标签特征。然后对特定列进行分组并计算均值。最后输出各个列的频次特征和均值。
修改测试集中的x3_freq和x4_freq存在为nan的值的这两个特征:
解决问题:
- 加入特征之后模型的精度有什么变化?
加入特征后,模型的精度有所提高。因为更多的特征可以帮助模型更好地捕捉数据中的模式和关系,并减少过拟合的风险。加入新的特征可能会增加模型的容量,使其能够更好地适应复杂的数据集。也会导致模型更加强大和可靠,从而提高预测结果的准确性。
最后提交结果,可以看到评分从0.62644到了0.73415: