基础DataWhale夏令营第三期学习笔记(贼基础)

目录

一.想法

二.1赛题的介绍与分析

 二.2机器学习解题基本流程

知识点补充(决策树):

 三.代码详解

 1.导入库

2.读取训练集和测试集

 3.将 'udmap' 列进行 One-Hot 编码 

4. 构建新的特征列 eid_freq、eid_mean、udmap_isunknown 和 common_ts_hour

 5.导入模型库并训练模型

 四.总结


一.想法

自大一习 Python基础语法,对爬虫,数据分析感兴趣起来,做过简单的爬虫和数据分析,此后ai科技发展迅速,曾几次有学习 ai 相关知识,但是知识体系既庞大,我也不知从哪里入手,就没有继续精进。这次 DataWhale 夏令营提供了 baseline ,我想就让我从代码逐行解读开始。

二.1赛题的介绍与分析

用户新增预测挑战赛:

2023 iFLYTEK A.I.开发者大赛-讯飞开放平台

举办方:科大讯飞

  1. 赛题:用户新增预测,此大赛提供了海量的应用数据作为训练样本,基于提供的样本构建模型,预测用户的新增情况。
  2. 数据集:约62万条训练集、20万条测试集数据组成,共包含13个字段。数据中有(uuid,eid,udmap,udmap中key1~key9,common_ts,x1~x8,target),其中uuid为样本唯一标识,eid为访问行为ID,udmap为行为属性,其中的key1到key9表示不同的行为属性,如项目名、项目id等相关字段,common_ts为应用访问记录发生时间(毫秒时间戳),其余字段x1至x8为用户相关的属性,为匿名处理字段。target字段为预测目标,即是否为新增用户。
  3. 本次竞赛的评价标准采用f1_score,分数越高,效果越好:

 二.2机器学习解题基本流程

许多机器学习问题中,特征工程的重要性不容忽视。如果特征工程能够充分捕捉数据的关键特征,那么机器学习算法也能够表现很好。这里我们是使用决策树模型进行。

知识点补充(决策树):

决策树是一种用于分类和回归分析的机器学习方法。它以类似于树状结构的方式进行决策,每个内部节点代表一个属性或特征,每个分支代表该属性的一个取值,而每个叶子节点则代表一个分类结果或值。

决策树的构建过程基于对训练数据集的分析与处理。最常用的算法是ID3、C4.5和CART。这些算法根据不同的指标(如信息增益、基尼系数等)来选择最佳的属性进行划分,以便在每个节点上获得最大的分类准确性。

形如以下:

决策树具有以下优点

  1. 易于理解和解释:决策树的结构类似于人类思维过程,易于解释和理解。
  2. 可处理离散和连续特征:决策树可以处理离散特征和连续特征,无需对数据进行过多的预处理。
  3. 能够处理大规模数据集:决策树算法具有较高的效率,能够处理包含大量样本的数据集。

然而,决策树也存在一些限制

  1. 容易发生过拟合:决策树容易在训练数据上过拟合,导致在新数据上的表现不佳。可以通过剪枝等技术来解决过拟合问题。
  2. 对输入数据的变化敏感:输入数据的微小变化可能会导致完全不同的决策树结构,这使得决策树相对不稳定。

 三.代码详解

以下是基础版本的Baseline,与我的解析,我会尽可能实现最详细:

import pandas as pd
import numpy as np

train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

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')

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)]


train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

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())

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['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour

import lightgbm as lgb
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier

clf = DecisionTreeClassifier()
clf.fit(
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)

pd.DataFrame({
    'uuid': test_data['uuid'],
    'target': clf.predict(test_data.drop(['udmap', 'common_ts', 'uuid'], axis=1))
}).to_csv('submit.csv', index=None)

 1.导入库

 A.pandas库:用于数据处理和分析

pandas是一个用于数据分析和处理的Python库。它提供了高性能、易于使用的数据结构和数据分析工具,使得数据清洗、转换、分析和可视化变得更加简单和高效。

pandas库主要包含两种核心数据结构:Series和DataFrame

  1. Series:Series是一维带标签的数组,类似于带有索引的列表。它可以保存任意数据类型的元素,并且每个元素都对应一个唯一的标签(索引)。可以通过索引对Series中的元素进行访问、修改和删除。

  2. DataFrame:DataFrame是一个二维的表格型数据结构,类似于关系型数据库中的表或Excel中的表格。它由多个Series组成,每个Series代表一个列,而整个DataFrame则包含多个列。DataFrame的行索引和列索引分别对应数据的观测和特征。可以方便地对DataFrame进行增删改查、合并、筛选、排序等操作。

除了这两种核心数据结构之外,pandas还提供了丰富的数据处理和分析工具,例如数据读取和写入、数据清洗和转换、数据聚合和分组、数据透视表、时间序列分析、缺失值处理、数据可视化等功能。通过pandas库,你可以更加方便地进行数据分析和处理,提高工作效率。

可能文字理解比较困难,我来基础使用演示pandas库会便于理解:

# 导入pandas库,让pd作为它的别名
import pandas as pd

# 使用pandas的DataFrame函数来创建一个DataFrame对象。
# DataFrame可以从各种数据源中创建,例如列表、字典、CSV文件等。
# 这里我们以字典的形式创建一个DataFrame对象
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David'],
        'Age': [25, 32, 18, 47],
        'City': ['New York', 'London', 'Paris', 'Tokyo']}
df = pd.DataFrame(data)
'''上述代码中,我们创建了一个包含"Name"、"Age"和"City"三个列的DataFrame对象。
每列对应一个键值对,键是列名,值是一个列表,表示该列中的数据。
'''

#DataFrame的columns属性是用于获取和设置DataFrame对象的列索引(列名)的属性。
#要获取DataFrame的列索引,可以通过访问columns属性来实现。
print(df.columns) # Index(['Name', 'Age', 'City'], dtype='object')
'''你可以使用该属性对列索引进行访问、修改或删除。下面是一些常见的用法示例:
访问列索引:可以通过columns属性和索引位置访问特定的列索引值。
例如,df.columns[0]会返回第一个列索引的名称。
修改列索引:可以通过将columns属性赋予一个新的列索引列表来修改列索引的名称。
例如,df.columns = ['Name', 'Age', 'Location']会将列索引的名称修改为新的名称。
删除列索引:可以使用drop函数来删除一个或多个列索引。
例如,df.drop(['Age', 'City'], axis=1)会删除列索引中的'Age'和'City'两列。
需要注意的是,当你修改列索引时,必须确保新的索引列表长度和DataFrame的列数相同,否则会引发错误。
'''
# 我们可以查看DataFrame的内容。可以使用head()方法查看前几行,默认为前5行
print(df.head())
'''这里只有四行
结果为:
      Name  Age      City
0    Alice   25  New York
1      Bob   32    London
2  Charlie   18     Paris
3    David   47     Tokyo
'''

# 还可以获取DataFrame的维度信息,使用shape属性
print(df.shape)
'''输出结果为(4, 3),表示该DataFrame有4行和3列。'''

# 还可以对DataFrame进行筛选、排序、添加或删除列等操作。
# 筛选Age大于30的行
filtered_df = df[df['Age'] > 30]

# 按照Age列进行升序排序
sorted_df = df.sort_values('Age')

# 添加一个新列,作为Age加上10的结果
df['Age_plus_10'] = df['Age'] + 10

# 删除City列
df = df.drop('City', axis=1)


 友情提示:动手自己跑代码才能真正的提升,快去动手试试吧(记得先导入pandas库)

B.numpy库:用于科学计算和多维数组操作

NumPy是Python中一个重要的科学计算库,它提供了高性能的多维数组对象(ndarray),以及对这些数组进行操作的各种工具和函数。下面是对NumPy库的一些解析:

  1. 多维数组(ndarray):NumPy中最重要的数据结构是ndarray(N-dimensional array,多维数组)。它是一个由相同类型的元素组成的表格,可以是一维、二维或更高维度的数组。ndarray具有以下特点:

    • 元素类型统一:ndarray中的元素必须是相同类型,通常为数值类型(如整数、浮点数等)。
    • 固定大小:ndarray一经创建,其大小就是固定的,不能动态改变。
  2. 数组创建:NumPy提供了多种方式来创建数组,例如:

    • 通过列表或元组创建:可以通过将列表或元组传递给numpy.array()函数来创建数组。
    • 使用特定函数创建:如numpy.zeros()numpy.ones()numpy.arange()等,分别用于创建全零数组、全一数组和指定范围的数组。
    • 从已有数组创建:例如通过numpy.copy()函数或ndarray.copy()方法创建一个现有数组的副本。
  3. 数组操作:NumPy提供了广泛的数组操作函数和方法,包括:

    • 数组索引和切片:可以通过索引和切片操作来获取和修改数组中的元素。
    • 数组形状操作:例如numpy.reshape()函数可以改变数组的维度,numpy.transpose()函数可以交换数组的轴。
    • 数学运算:NumPy支持对数组执行各种数学运算,如加法、减法、乘法、除法、求和、均值等。
    • 数组统计:NumPy提供了多个统计函数,如numpy.mean()numpy.median()numpy.std()等,用于计算数组的平均值、中位数和标准差。
    • 数组排序和筛选:例如numpy.sort()函数可以对数组进行排序,numpy.where()函数可以根据条件筛选数组中的元素。
  4. 广播(Broadcasting):NumPy中的广播是一种强大的机制,它使得不同形状的数组之间的运算成为可能。广播可以让NumPy在执行一些特定的运算时自动调整数组的形状,使其能够匹配运算的要求。

总的来说,NumPy是Python中进行科学计算和数据处理的重要工具库,它提供了高效的数组操作和数学函数,使得处理大规模数据变得更加简单和高效。在数据分析、机器学习、图像处理等领域都有广泛的应用。

同样的,我来基础使用演示numpy库:

# 先导入 np
import numpy as np

'''创建数组'''
# 通过列表创建一维数组
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)  # 输出: [1 2 3 4 5]

# 通过多维列表创建二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# 输出:
# [[1 2 3]
#  [4 5 6]]

# 创建全零数组
zeros_arr = np.zeros((2, 3))  # 创建一个2行3列的全零数组
print(zeros_arr)
# 输出:
# [[0. 0. 0.]
#  [0. 0. 0.]]

# 创建全一数组
ones_arr = np.ones((3, 2))  # 创建一个3行2列的全一数组
print(ones_arr)
# 输出:
# [[1. 1.]
#  [1. 1.]
#  [1. 1.]]

# 创建指定范围的数组
range_arr = np.arange(1, 10, 2)  # 创建一个步长为2的1到9的数组
print(range_arr)  # 输出: [1 3 5 7 9]

'''接下来对数组操作'''
# 数组索引和切片
arr = np.array([1, 2, 3, 4, 5])
print(arr[0])  # 输出: 1
print(arr[1:4])  # 输出: [2 3 4]

# 数组形状操作
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape)  # 输出: (2, 3)
arr_reshaped = arr.reshape(3, 2)  # 改变数组形状为3行2列
print(arr_reshaped)
# 输出:
# [[1 2]
#  [3 4]
#  [5 6]]

# 数组数学运算
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
sum_result = a + b
print(sum_result)  # 输出: [5 7 9]
mul_result = a * b
print(mul_result)  # 输出: [4 10 18]

# 数组统计
arr = np.array([1, 2, 3, 4, 5])
mean_val = np.mean(arr)
print(mean_val)  # 输出: 3.0
max_val = np.max(arr)
print(max_val)  # 输出: 5

# 数组排序和筛选
arr = np.array([3, 1, 4, 2, 5])
sorted_arr = np.sort(arr)
print(sorted_arr)  # 输出: [1 2 3 4 5]
filtered_arr = arr[arr > 3]
print(filtered_arr)  # 输出: [4 5]

友情提示:动手自己跑代码才能真正的提升,快去动手试试吧


2.读取训练集和测试集

 使用 pd的read_csv() 函数从文件中读取训练集和测试集数据,文件名为 'train.csv'与'test.csv'

 3.将 'udmap' 列进行 One-Hot 编码 

注:以下源于赛事官方(我认为够详细了doge):

 而这,

对训练数据和测试数据中的udmap列进行处理,这里分别将训练数据和测试数据中的udmap列应用函数udmap_onethot,得到每个样本的udmap编码向量。然后构建新的DataFrame对象train_udmap_dftest_udmap_df,将编码向量作为新的列添加到train_datatest_data中。

apply() 方法将 udmap_onethot 函数应用于每个样本的 'udmap' 列
np.vstack() 用于将结果堆叠成一个数组
concat函数是pandas库中用于合并(连接)多个DataFrame对象的函数
'''pd.concat(objs, axis=0, join='outer')
objs是要合并的DataFrame对象列表
axis指定了连接的轴
join指定了连接的方式。
'''
# 按行连接(默认行连接):
import pandas as pd
# 创建两个DataFrame对象
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [7, 8, 9], 'B': [10, 11, 12]})
# 按行连接两个DataFrame对象
result = pd.concat([df1, df2])
print(result)
'''  
   A   B
0  1   4
1  2   5
2  3   6
0  7  10
1  8  11
2  9  12
'''

# 按列连接
import pandas as pd
# 创建两个DataFrame对象
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'C': [7, 8, 9], 'D': [10, 11, 12]})
# 按列连接两个DataFrame对象
result = pd.concat([df1, df2], axis=1)
print(result)
'''
   A  B  C   D
0  1  4  7  10
1  2  5  8  11
2  3  6  9  12
'''

4. 构建新的特征列 eid_freqeid_meanudmap_isunknown 和 common_ts_hour

【这段代码主要对训练数据和测试数据进行预处理和特征工程操作。这些预处理和特征工程的步骤旨在提取数据中的有用信息,并为分类器模型提供更丰富的特征,以提高模型的准确性和性能】

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())

这里通过map函数和value_counts方法,计算了eid列的频次,并将结果赋值给新的列eid_freq。这个特征可以提供有关每个 'eid' 的数据分布和频率信息。在许多机器学习任务中,频率信息经常被用作特征,以帮助模型识别重要的类别、标签或实体。通过添加 'eid_freq' 特征,模型可以更好地利用 'eid' 的出现频率信息,从而提高对不同 '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())
同时,通过groupbymean方法,计算了每个eid对应的target均值,并将结果赋值给新的列eid_mean。这两行代码主要用于创建新的特征 'eid_mean',其中存储了每个 'eid' 对应的目标变量 'target' 的均值。首先,train_data.groupby('eid') 将训练数据按照 'eid' 进行分组。然后,.mean() 函数计算每个分组中 'target' 的平均值。接下来,train_data['eid'].map(...) 将每个 'eid' 映射到对应的分组平均值,从而为每个样本创建了一个 'eid_mean' 特征值。同理,对于测试数据集,使用 train_data.groupby('eid')['target'].mean() 是因为测试数据集中的 'eid' 可能存在于训练数据集中,并且需要使用训练数据集中的目标变量的均值来计算测试数据集的 'eid_mean'。通过这样的特征工程,模型可以利用 'eid' 特征的统计信息来更好地理解和预测数据,提高模型的准确性和泛化能力。

另外,根据udmap列是否为unknown,构建了新的二进制特征列udmap_isunknown

最后,从时间戳中提取小时部分,得到新的特征列common_ts_hour
注: 看见“从时间戳中提取小时部分,得到新的特征列”是否能联想到上面’二.2机器学习解题基本流程‘里讲到的“特征工程能够充分捕捉数据的关键特征,那么机器学习算法也能够表现很好”。所以也可以从时间戳中提取季节,年份,月份,星期等来得到新特征来提分baseline。

 5.导入模型库并训练模型

这里使用sklearn库中的DecisionTreeClassifier类构建了一个决策树模型,并通过调用fit方法拟合了训练数据。

当我们使用sklearn库中的DecisionTreeClassifier类构建决策树模型时,fit方法是用于将模型与训练数据拟合的一个重要步骤。

首先,我们需要明确决策树模型的目标根据已知的特征和对应的目标值来学习特征间的关系,并利用这种关系对未知样本进行预测。因此,我们需要准备好训练数据集,其中包含已知的特征和对应的目标值。

然后,我们使用DecisionTreeClassifier类创建了一个决策树模型的实例,即创建了一个空的决策树。这个实例具有一些默认的参数设置,例如使用"gini"作为特征选择准则、选择最佳特征进行分割等。

接下来,我们调用fit方法并将训练数据集作为输入参数传递给它。该fit方法会将模型与训练数据进行拟合,也就是让模型根据训练数据学习特征之间的关系。

拟合过程中,决策树模型会根据训练数据中每个样本的特征值目标值的关系来确定分割条件,并在各个节点上构建决策树的分支。它会通过计算特征的重要性来选择最佳的分割点,以最大程度地提高预测的准确性。

通过不断地选择和分割特征,决策树模型的深度会逐渐增加,直到满足停止条件为止,例如达到最大深度或者节点中的样本数小于某个阈值。

拟合完成后,我们就可以使用已经拟合好的决策树模型来进行预测。利用训练过程中所学到的特征之间的关系,模型可以根据未知样本的特征值来预测它们的目标值。

总结起来,使用DecisionTreeClassifier类的fit方法可以将训练数据与决策树模型进行拟合,让模型学习特征间的关系,并用于预测未知样本的目标值。这样我们就可以利用决策树模型来进行分类任务或者回归任务。

再结合以下更好的理解:

'''
DecisionTreeClassifier类在sklearn库中的构造函数(init)可以接受多个参数来控制决策树模型的行为和性能。下面是一些常用的参数以及它们的作用:

criterion:用于衡量特征选择质量的准则。可以是"gini"表示基尼系数,或者"entropy"表示信息增益。默认值为"gini"。
splitter:特征选择策略。可以是"best"表示选择最佳特征进行分割,或者"random"表示随机选择特征进行分割。默认值为"best"。
max_depth:决策树的最大深度。默认值为None,表示没有限制。
min_samples_split:分割内部节点所需的最小样本数。可以是整数表示样本数,也可以是浮点数表示样本比例。默认值为2。
min_samples_leaf:叶子节点所需的最小样本数。可以是整数表示样本数,也可以是浮点数表示样本比例。默认值为1。
max_features:寻找最佳分割时要考虑的特征数量。可以是整数表示特征数量,也可以是浮点数表示特征比例。默认值为None,表示考虑所有特征。
random_state:随机种子。用于控制随机性,以便结果可重复。
class_weight:样本权重。可以是字典表示不同类别的权重,或者"balanced"表示根据训练数据自动调整权重以平衡类别不平衡问题。默认值为None,表示所有类别的权重相等。

除了构造函数中的参数,DecisionTreeClassifier类还提供了其他用于训练和预测的方法,例如:
fit(X, y):拟合模型与训练数据。
predict(X):预测给定输入数据的目标变量值。
predict_proba(X):预测给定输入数据属于每个类别的概率。
'''

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
# 生成简单的分类数据集
X, y = make_classification(n_samples=100, n_features=4, random_state=42)
# 创建决策树模型实例
model = DecisionTreeClassifier()
# 拟合模型与训练数据
model.fit(X, y)
# 可以进行预测了
new_data = [[0.2, 0.4, 0.6, 0.8]]
prediction = model.predict(new_data)
print("预测结果:", prediction)

'''
make_classification是scikit-learn库中的一个函数,用于生成一个人工分类数据集。
这个函数可以根据指定的参数生成一个具有特定特征和标签的分类数据集,用于模型的训练和测试。
具体来说,make_classification函数可以接受以下参数:

n_samples:生成的样本数量。
n_features:生成的特征数量。
n_informative:生成特征中与目标变量相关联的特征数量。
n_redundant:生成的冗余特征数量,这些特征与目标变量无关。
random_state:控制生成数据的随机种子。
通过调整这些参数,你可以生成适合不同任务和情景的数据集。

例如,在上面的例子中,我们使用make_classification函数生成了一个包含100个样本和4个特征的分类数据集。
该数据集是人工生成的,用于展示决策树模型的基本使用方法。
在实际应用中,你可以根据需求自定义参数,生成适合你任务的数据集,以便进行模型训练和评估。
'''

四.总结

 大一暑假第一次参与这种比赛,同助教与很多人共同进步成长,学习到了机器学习基础知识,参与AI夏令营第三期的用户新增预测挑战赛教程让我获得了宝贵的机器学习实践经验,并且提高了我的技能和知识水平。这将对我的未来学习和职业发展产生积极的影响。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值