触类旁通不是一件容易的事情,很多例子都是两个指标来确定分类,因为这样可以通过二维图有个清晰的认知。这里拿八字命理中最有争议的强弱论,试试用机器学习算法看看效果如何,因为我也可以才接触算法不久,故也对算法进行说明。
这里不搞什么加权,因为你怎么加权,总有争议。只按照八字中天干以及支藏天干,对日主的生助克泄耗做分析。而利用机器学习中的算法,就相对客观了多。这里1:生、2:助、3:克、4:泄、5:耗
数据生成参考八字生助克泄耗数据生成
1 决策树
1.1 随机森林
计算得到交叉熵均值和模型准确率评分,通过调参得到效果如下表所示,我随意调整了两个参数,模型得分居然相差了20个点,很神奇,这个是为什么呢?参数调整有没有啥经验策略呢?随机森林(Random Forest)
参数 | 交叉熵均值 | 模型得分 |
---|---|---|
RandomForestClassifier(max_depth=6,n_estimators=100,random_state=6) | 0.730452560922195 | 0.766831 |
RandomForestClassifier(max_features=0.2,n_estimators=100) | 0.9554445958928852 | 0.9572016460905349 |
RandomForestClassifier(max_features=0.2,n_estimators=200) | 0.9562679021291374 | 0.9588348765432099 |
将1.2中决策树模型改成随机森林,采用one-hot编码,n_estimators=100 | 0.9630319021784692 | 0.9647087191358025 |
将1.2中决策树模型改成随机森林,采用one-hot编码,n_estimators=200 | 0.9630319021784692 | 0.9647087191358025 |
将1.2中决策树模型改成随机森林,采用one-hot编码,n_estimators=300 | 0.9535918844663577 | 0.9565779320987654 |
n_estimators
从100到200,得分并没有太大变化。
以前我以为超参要一个个试出来,原来还可以通过网格搜索来进行,参考sklearn随机森林调参小结,注意并不是什么场景都适合scoring = 'roc_auc'
,参见机器学习:multiclass format is not supported,roc_auc是一个评价标准,auc是roc曲线下方的面积,面积越大则分类评估模型就越好
下方并不是最好的代码,应该参考Python机器学习笔记:Grid SearchCV(网格搜索)
网格搜索用于调参,那么集成学习voting Classifier在sklearn中的实现,怎可以调试哪个模型最优
param_estis = {'n_estimators': range(80, 250, 10)}
gs = ms.GridSearchCV(estimator=se.RandomForestClassifier(min_samples_split=100,
min_samples_leaf=20, max_depth=8, max_features='sqrt',
random_state=10)
, param_grid = param_estis, cv = 5)
gs.fit(x_train, y_train)
print('评估分为:{},参数:{},分值:{},结束时间为:{}'.format(gs.grid_scores_, gs.best_params_, gs.best_score_,
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
决策树算法可以使用不熟悉的数据集合,从中提取出一系列规则。随机森林过拟合问题
维度 | 说明 | 备注 |
---|---|---|
优点 | 对中间值的缺失不敏感,可以处理不相关特征数据 | |
缺点 | 会产生过度匹配问题 | |
数据类型 | 数值型和标称型 | 标称型数据是有限目标,生克关系、旺衰即是标称型数据,标称型特征编码 |
import pandas as pd
import sklearn.model_selection as ms
import sklearn.ensemble as se
import time
import warnings
warnings.filterwarnings('ignore')
def get_data():
'''
获取数据
:return:
'''
data = pd.read_csv('sample.csv')
return data.get_values()[:,2:],data['ws']
def train():
X,Y = get_data()
print('加载数据集完成')
x_train, x_test, y_train, y_test = ms.train_test_split(X, Y, test_size=0.2, random_state=1)
print('测试集划分完成')
#
print('开始建立随机森林模型:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) ))
model = se.RandomForestClassifier(max_depth=6,n_estimators=100,random_state=6)
cv = ms.cross_val_score(model,x_train,y_train,cv=4,scoring='f1_weighted')
print("交叉熵:{}".format(cv.mean()))
print('开始训练:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
model.fit(x_train,y_train)
s = model.score(x_test,y_test)
print('评估分为:{},结束时间为:{}'.format(s,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
1.2 决策树
参考Python学习教程:决策树算法(三)sklearn决策树实战,空值处理参考Pandas的数据清洗-填充NaN,直接使用示例会有下面的问题
y的数据类型他不认识ValueError: Unknown label type: 'unknown'
计算后得到的评分是0.9634934413580247
,貌似比随机森林效果还要好。机器学习:决策树(基尼系数,信息熵和基尼系统得到的评分效果差不多
系数 | 评分 |
---|---|
gini | 0.9634934413580247 |
entropy | 0.9638406635802469 |
import pandas as pd
from sklearn import tree
import sklearn.model_selection as ms
import sklearn.feature_extraction as fe
import sklearn.ensemble as se
import time
import warnings
warnings.filterwarnings('ignore')
from sklearn import tree
def train_small():
data = pd.read_csv('sample1.csv')
data.fillna('无', inplace=True)
print(data.sample(20))
# 特征向量化
vec = fe.DictVectorizer(sparse=False)
feature = data[['yg', 'mg', 'hg', 'yz_b', 'yz_z', 'yz_y', 'mz_b'
, 'mz_z', 'mz_y', 'dz_b', 'dz_z', 'dz_y', 'hz_b', 'hz_z', 'hz_y']]
print(data['ws'].unique())
X = vec.fit_transform(feature.to_dict(orient='record'))
# 通过astype进行类型转换
Y = data['ws'].astype('float')
print('加载数据集完成')
# criterion有两位:基尼系数gini和信息熵entropy
model = tree.DecisionTreeClassifier(criterion='gini')
x_train, x_test, y_train, y_test = ms.train_test_split(X, Y, test_size=0.15, random_state=1)
print('测试集划分完成')
print('开始训练:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
model.fit(x_train, y_train)
s = model.score(x_test, y_test)
print('评估分为:{},结束时间为:{}'.format(s, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
2 贝叶斯
朴素贝叶斯-分类及Sklearn库实现(1)机器学习实战,从下面看出贝叶斯算法并不高,对数据可能比较敏感,计算速度倒是相当快
算法模型 | 评分 |
---|---|
GaussianNB | 0.6287422839506173 |
MultinomialNB | 0.48348765432098767 |
BernoulliNB | 0.4255272633744856 |
2.1 高斯朴素贝叶斯
def train_gauss():
X, Y = get_data()
print('加载数据集完成')
x_train, x_test, y_train, y_test = ms.train_test_split(X, Y, test_size=0.15, random_state=1)
model = GaussianNB()
print('开始训练:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
model.fit(x_train, y_train)
s = model.score(x_test, y_test)
print('评估分为:{},结束时间为:{}'.format(s, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))