概览题目要求:
摘要:
- 导入需要用到的相关库,包括pandas、numpy和DecisionTreeClassifier。
- 读取训练集和测试集数据,使用pandas的read_csv()函数。
- 对'udmap'列进行One-Hot编码,并将编码后的特征与原始数据拼接。
- 编码'udmap'是否为空,将布尔值转换为整数。
- 提取'eid'的频次特征,使用map()方法将每个样本的eid映射到训练数据中eid的频次计数。
- 提取'eid'的标签特征,使用groupby()方法按照eid分组,计算每个eid分组的目标值均值。
- 提取时间戳,将时间戳列转换为datetime类型,并提取小时信息存储在新的列'common_ts_hour'中。
- 加载决策树模型进行训练,使用fit方法训练模型。
- 对测试集进行预测,并保存结果到result_df中。
- 将结果文件保存到本地,使用to_csv()方法将结果DataFrame保存为CSV文件。
课外补充:
包括onehot,部分代码解析,和决策树 f1分数
F1 分数是机器学习中用于评估分类模型性能的一种指标,它综合了模型的准确率(Precision)和召回率(Recall)。F1 分数是准确率和召回率的调和平均值,可以在不同类别不平衡的情况下更全面地评估模型的性能。
具体计算 F1 分数的步骤如下:
- 首先,根据分类器的预测结果和真实标签,计算模型的准确率和召回率。
- 准确率(Precision):表示被正确分类的正样本数占所有预测为正样本数的比例,计算公式为:准确率 = TP / (TP + FP),其中 TP 表示真正例(True Positive),FP 表示假正例(False Positive)。
- 召回率(Recall):表示被正确分类的正样本数占所有真实正样本数的比例,计算公式为:召回率 = TP / (TP + FN),其中 FN 表示假反例(False Negative)。
- 然后,使用准确率和召回率来计算 F1 分数。F1 分数是准确率和召回率的调和平均值,计算公式为:F1 = 2 * (准确率 * 召回率) / (准确率 + 召回率)。
F1 分数的取值范围在 0 和 1 之间,数值越高表示模型的性能越好。当准确率和召回率差异较大时,F1 分数可以更好地综合评估模型的性能。
在实际应用中,通过计算各个类别的 F1 分数并进行平均或加权平均,可以得到整体的模型性能评估指标。除了 F1 分数,还有其他常用的分类模型评估指标,如准确率、召回率、精确度、ROC 曲线等,根据具体任务和需求选择适合的评估指标进行模型评估。
在机器学习中,One-Hot 编码是一种常用的特征编码方法,可以将具有多个离散取值的特征转换为二进制向量表示。下面是 One-Hot 编码的具体实现步骤:
假设有一个特征变量 X,它有 K 个不同的离散取值。
创建一个大小为 K 的零向量,用于表示特征的 One-Hot 编码。这个零向量有 K 维,每个维度代表一个离散取值。
找到特征变量 X 的实际取值 v。
将零向量中索引为 v 的元素设为 1,其他元素保持为 0。这样就完成了对特征变量 X 的 One-Hot 编码。
例如,假设特征变量 X 有三个离散取值:A、B、C。对应的 One-Hot 编码可以如下表示:
- 如果 X=A,则 One-Hot 编码为 [1, 0, 0];
- 如果 X=B,则 One-Hot 编码为 [0, 1, 0];
- 如果 X=C,则 One-Hot 编码为 [0, 0, 1]。
在实际应用中,可以使用编程语言或机器学习库提供的函数来实现 One-Hot 编码。例如,Python 中的 scikit-learn 库提供了
OneHotEncoder
类,可以方便地进行 One-Hot 编码操作。需要注意的是,当特征变量 X 具有大量不同的离散取值时,One-Hot 编码可能会导致高维稀疏的特征表示,这可能会增加计算和存储的复杂性。在这种情况下,可以考虑其他编码方法或降维技术来处理特征变量。
决策树分类器是一种基于树结构的有监督学习算法,用于进行分类任务。以下是决策树分类器的实现过程的详细说明:
收集数据集:首先,我们需要收集带有标签的训练数据集,其中每个样本都有特征和对应的类别标签。
特征选择:根据数据集中的特征,选择最佳的特征用于建立决策树。常用的特征选择方法有信息增益、信息增益比、基尼不纯度等。
构建决策树:使用选定的特征作为根节点,将数据集划分为不同的子集。对于每个子集,递归地重复步骤 2 和步骤 3,直到满足某个终止条件(如达到设定的树深度或节点中样本数小于设定阈值)。
终止条件处理:当达到终止条件时,将子集中的样本标记为单一的类别或使用多数表决法确定类别。
决策树剪枝:为了避免过拟合,可以对构建好的决策树进行剪枝操作,即通过降低树的复杂度来提高泛化能力。
预测过程:使用构建完成的决策树对新的样本进行分类预测。根据样本的特征值,沿着决策树的分支逐步向下,直到到达叶子节点,将叶子节点的类别作为预测结果。
决策树的优点是易于理解和解释,可以处理数值型和分类型数据,能够同时处理多个特征,并且在一些情况下具有良好的性能。但也存在着容易过拟合的问题,需要合理地选择特征和剪枝操作来提高泛化能力。
在代码中,我们使用
DecisionTreeClassifier
类来实现决策树分类器。通过调用该类的fit()
方法,将训练集的特征和标签作为输入,训练模型。然后通过调用predict()
方法,将测试集的特征作为输入,得到预测的类别标签。最后,我们可以对预测结果进行评估和分析。
手敲代码:
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
train_data=pd.read_csv("用户新增预测挑战赛公开数据/train.csv")
test_data=pd.read_csv("用户新增预测挑战赛公开数据/test.csv")
def udmap_onehot(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_onehot)))
test_udmap_df=pd.DataFrame(np.vstack(test_data['udmap'].apply(udmap_onehot)))
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)]
train_data=pd.concat([train_data,train_udmap_df],axis=1)
test_data=pd.concat([test_data,test_udmap_df],axis=1)
train_data['udmap_isunknown']=(train_data['udmap']=='unknown').astype(int)
test_data['udmap_isunknown']=(test_data['udmap']=='unknown').astype(int)
train_data['eid_freq']=train_data['eid'].map(train_data['eid'].value_counts())
test_data['eid_freq']=test_data['eid'].map(test_data['eid'].value_counts())
train_data['eid_mean']=train_data['eid'].map(train_data.groupby('eid')['target'].mean())
test_data['eid_mean']=test_data['eid'].map(test_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
clf=DecisionTreeClassifier()
clf.fit(
train_data.drop(['udmap','common_ts','uuic','target'],axis=1),
train_data['target']
)
result_df=pd.DataFrame({
'uuid':test_data['uuid'],
'terget':clf.predict(test_data.drop(['udmap','commos_ts','uuid'],axis=1))
})
result_df.to_csv('submit.csv',index=None)