导入工具包

pandas是数据分析和处理常用的工具包,非常适合处理行列表格数据。numpy是数学运算工具包,支持高效的矩阵、向量运算。sklearn是机器学习常用工具包,包括了一些已经实现好的简单模型和一些常用数据处理方法、评价指标等函数。

  1. from collections import Counter
  2. import pandas as pd # 数据处理
  3. import numpy as np # 数学运算
  4. from sklearn.model_selection import train_test_split, cross_validate # 划分数据集函数
  5. from sklearn.metrics import accuracy_score # 准确率函数
  6. RANDOM_SEED = 2020 # 固定随机种子

读入数据

假设数据文件放在./data/目录下,标准的csv文件可以用pandas里的read_csv()函数直接读入。
可以舍去一些列,比如对局标号不是标签也不是特征,舍去。

  1. dataPath = './data/'
  2. dataName = 'high_diamond_ranked_10min.csv'
  3. csv_data = dataPath + dataName # 数据路径
  4. data_df = pd.read_csv(csv_data, sep=',') # 读入csv文件为pandas的DataFrame
  5. ColumnsNames = ['column1', 'column2', ]
  6. data_df = data_df.drop(columns=ColumnsNames, axis=1) # 删除不必要的字段

数据概览

对于一个机器学习问题,在拿到任务和数据后,首先需要观察数据的情况,比如我们可以通过.iloc[0]取出数据的第一行并输出。
可以发现有些特征列是重复冗余的。
通过DataFrame使用describe()函数,展示每一列数据的一些统计信息,对数据分布情况有大致了解。

  1. #print(data_df.iloc[0].T) # 输出第一行数据
  2. print(data_df.head(3).T)
  3. data_df.describe().T # 每列特征的简单统计信息

增删特征

传统的机器学习模型大部分都是基于特征的,因此特征工程是机器学习中非常重要的一步。有时构造一个好的特征比改进一个模型带来的提升更大。
这里删除掉上个frame观察到的冗余数据,并取某些数据做差值。

  1. drop_features = ['column1', 'column2', ] # 需要舍去的特征列
  2. df = data_df.drop(columns=drop_features, axis=1) # 舍去特征列
  3. #info_names = [c[3:] for c in df.columns if c.startswith('red')] # 取出要作差值的特征名字(除去red前缀)
  4. info_names = ['column1', 'column2', ]
  5. drop_features = []
  6. for info in info_names: # 对于每个特征名字
  7. # 构造一个新的特征,前缀为br
  8. #df['br' + info] = df['blue' + info] - df['red' + info]
  9. df['br' + info] =
  10. drop_features.append()
  11. drop_features.extend(['column1', 'column2', ])# 额外要drop的特征
  12. df.drop(columns=c, inplace=True, axis=1)

重新打印数据

  1. print(df.head(3).T) # 输出第一行数据
  2. df.describe().T # 每列特征的简单统计信息

特征离散化

决策树ID3算法一般是基于离散特征的,本例中存在很多连续的数值特征,例如队伍金币。直接应用该算法每个值当作一个该特征的一个取值可能造成严重的过拟合,因此需要对特征进行离散化,即将一定范围内的值映射成一个值,例如对用户年龄特征,将0-10映射到0,11-18映射到1,19-25映射到2,25-30映射到3,等等类似,然后在决策树构建时使用映射后的值计算信息增益。

  1. discrete_df = df.copy() # 先复制一份数据
  2. def get_discrete_conf(df):
  3. Sheet_discrete_list = []
  4. for c in df.columns: # 遍历每一列特征,跳过标签列(label)
  5. if c == 'blueWins':
  6. continue
  7. Sheet_discrete_list.append([c, get_discrete_conf_c(df, c)])
  8. Sheet_discrete_dict = dict(Sheet_discrete_list)
  9. print(Sheet_discrete_dict)
  10. return Sheet_discrete_dict
  11. def get_discrete_data(discrete_conf, df):
  12. for c in df.columns:
  13. if c not in discrete_conf:
  14. continue
  15. discrete_column = get_discrete_column(discrete_conf, c, list(df[c]))
  16. df[c] = discrete_column
  17. return df
  18. discrete_conf = get_discrete_conf(df)
  19. discrete_df = get_discrete_data(discrete_conf, df)
  20. print(discrete_df.head(3).T)
  21. discrete_df.to_csv('data.csv')

数据集准备

构建机器学习模型前要构建训练和测试的数据集。在本例中首先需要分开标签和特征,标签是不能作为模型的输入特征的,就好比作业和试卷答案不能在做题和考试前就告诉学生。测试一个模型在一个任务上的效果至少需要训练集和测试集,训练集用来训练模型的参数,好比学生做作业获得知识,测试集用来测试模型效果,好比期末考试考察学生学习情况。测试集的样本不应该出现在训练集中,否则会造成模型效果估计偏高,好比考试时出的题如果是作业题中出现过的,会造成考试分数不能准确衡量学生的学习情况,估计值偏高。划分训练集和测试集有多种方法,下面首先介绍的是随机取一部分如20%作测试集,剩下作训练集。sklearn提供了相关工具函数train_test_split。sklearn的输入输出一般为numpy的array矩阵,需要先将pandas的DataFrame取出为numpy的array矩阵。

  1. y_column = 'blueWins'
  2. all_y = discrete_df[y_column].values # 所有标签数据
  3. # 删除y列
  4. feature_names = list(discrete_df.columns.values)
  5. feature_names.remove(y_column)
  6. feature_names = np.array(feature_names)
  7. print("feature_len:",len(feature_names))
  8. print("feature_names:",feature_names)
  9. all_x = discrete_df[feature_names].values # 所有原始特征值,pandas的DataFrame.values取出为numpy的array矩阵
  10. # 划分训练集和测试集
  11. x_train, x_test, y_train, y_test = train_test_split(all_x, all_y, test_size=0.2, random_state=RANDOM_SEED)
  12. all_y.shape, all_x.shape, x_train.shape, x_test.shape, y_train.shape, y_test.shape # 输出数据行列信息

模型的实现(手撸代码|机器学习框架)

  1. from sklearn.model_selection import train_test_split
  2. from sklearn.tree import DecisionTreeClassifier
  3. clf = DecisionTreeClassifier(random_state=3) # 初始化
  4. clf = clf.fit(x_train,y_train) # 拟合
  5. score_ = clf.score(x_test, y_test) # 验证集查看得分,这个得分好像就是分类的准确率
  6. print(score_)

模型效果计算

第一次模型测试结果可能不够好,可以先检查调试代码是否有bug,再尝试调整参数或者优化计算方法。

  1. Err = p_test-y_test
  2. ErrNum = 0
  3. for i in range(len(Err)):
  4. if Err[i] != 0:
  5. ErrNum = ErrNum + 1
  6. ErrRate = float(ErrNum)/len(Err)
  7. print(ErrRate)
  8. print(1-ErrRate)