数据竞赛 - 达观杯(study)

request1:
(1.下载数据,读取数据,观察数据
2. 将训练集拆分为训练集和验证集。要求:数据3-7分,随机种子2019)

数据包含2个csv文件:
train_set.csv:此数据集用于训练模型,每一行对应一篇文章。文章分别在“字”和“词”的级别上做了脱敏处理。共有四列:
第一列是文章的索引(id),第二列是文章正文在“字”级别上的表示,即字符相隔正文(article);第三列是在“词”级别上的表示,即词语相隔正文(word_seg);第四列是这篇文章的标注(class)。
注:每一个数字对应一个“字”,或“词”,或“标点符号”。“字”的编号与“词”的编号是独立的!

test_set.csv:此数据用于测试。数据格式同train_set.csv,但不包含class。
注:test_set与train_test中文章id的编号是独立的。

读取数据
import pandas as pd
df_train = pd.read_csv(‘train_set.csv’)
df_test = pd.read_csv(‘test_set.csv’)
各列文件类型数量有无缺失。
df_train.info()
df_test.info()
各个类别数据是否分布不均:

df_train[‘class’].describe()
df_train[‘class’].value_counts()
文本分类共19类,各类别数据均在2000条以上。没有严重的类别不均。

数据说明中显示:
'article’是字级别上的,'word_seg’是词级别上的。
也就是说,比赛举办方已经把单词给我们切好了,不需要自己手动分词,已经把单词数字化(脱敏),因此数据划分中X以df_train[[‘word_seg’]进行即可。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df_train[[‘word_seg’]], df_train[[‘class’]], test_size=0.3, random_state=2019)
print(X_train.shape)
print(X_test.shape)

request2:
(对文本特征进行预处理,将文本转成向量表示:
1) 学习TF-IDF理论并实践;
2) 学习word2vec词向量原理并实践;
3)[可选]特征选择&特征构建)
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer=TfidfTransformer()
import gensim
import pickle
import time
import numpy as np


“”"=====================================================================================================================
1 数据预处理
“”"
print(“1 数据预处理”)

1 数据预处理
t_start = time.time()
df_train=pd.read_csv(’./data/new_data/train_set.csv’,nrows=10000) # 数据大,爆内存,读前10000行
df_test = pd.read_csv(’./data/new_data/test_set.csv’,nrows=10000)
df_train.drop([‘article’],axis=1, inplace=True)
df_test.drop([‘article’],axis=1, inplace=True)
f_all = pd.concat(objs=[df_train, df_test], axis=0)
y_train = (df_train[‘class’] - 1).values
#Tfidf
“”"=====================================================================================================================
2 特征工程
“”"
print(“2 特征工程”)
vectorizer = TfidfVectorizer(ngram_range=(1, 2), min_df=3, max_df=0.9, sublinear_tf=True)
vectorizer.fit(df_train[‘word_seg’])
x_train = vectorizer.transform(df_train[‘word_seg’])
x_test = vectorizer.transform(df_test[‘word_seg’])

“”"=====================================================================================================================
3 保存至本地
“”"
print(“3 保存至本地”)
data = (x_train, y_train, x_test)
fp = open(’/srv/r_server/ML/data_w_tfidf.pkl’, ‘wb’)
pickle.dump(data, fp)
fp.close()

t_end = time.time()
print(“已将原始数据数字化为tfidf特征,共耗时:{}min”.format((t_end-t_start)/60))
3 保存至本地
已将原始数据数字化为tfidf特征,共耗时:4.027563591798146min

word2vec

#=======================================================================================================================

1 准备训练数据

#=======================================================================================================================

print("准备数据… ")
sentences_train = list(df_train.loc[:, ‘word_seg’].apply(sentence2list))
sentences_test = list(df_test.loc[:, ‘word_seg’].apply(sentence2list))
sentences = sentences_train + sentences_test
print("准备数据完成! ")
准备数据…
准备数据完成!
word2vec 参考:https://github.com/Heitao5200/DGB/blob/master/feature/feature_code/train_word2vec.py

request3:
学习内容
使用下面模型对数据进行分类(包括:模型构建&调参&性能评估):
1)逻辑回归(LR)模型,学习理论并用Task2的特征实践;
2)支持向量机(SVM) 模型,学习理论并用Task2的特征实践;
3)尝试线上提交结果
4)[可选]尝试其他基本模型(不是集成模型哟)

特征选择
对特征进行嵌入式选择

  1. 读取特征
    import time
    import pickle
    from sklearn.feature_selection import SelectFromModel
    from sklearn.linear_model import LogisticRegression
    from sklearn.svm import LinearSVC
    features_path = ‘./data_w_tfidf.pkl’#tfidf特征的路径
    fp = open(features_path, ‘rb’)
    x_train, y_train, x_test = pickle.load(fp)
    fp.close()
    #######
    将前面进行TF-IDF的数据中训练集 拆成 train_data, valid_data, 调最优模型参数,再进行测试
    x_train1, x_valid, y_train1, y_valid = train_test_split(x_train, y_train, test_size=0.3, random_state=2019)
    LR模型
    逻辑回归处理的是分类问题,因变量取值是一个二元分布,学习得到的是给定自变量和超参数以后因变量的期望。基于期望来处理预测分类问题。
    具体参考细品 - 逻辑回归(LR)* - ML小菜鸟 - 博客园.
    选取部分数据跑LR/SVM模型,判断结果。
    from sklearn.linear_model import LogisticRegression
    from sklearn.svm import SVC
    from sklearn.metrics import confusion_matrix,f1_score
    svm=SVC(probability=True,class_weight=‘balanced’) # add probability=True ,then can print probability
    log=LogisticRegression(class_weight=‘balanced’)
    for model in ((svm,log)):
    model.fit(x_train,y_train)
    predicted_value=mod.predict(X_test)
    score=model.score(x_test,y_test)
    matrix=confusion_matrix(y_test,predicted_value)
    f1_score=f1_score(y_test,predicted_value,average=‘weighted’)
    print(model)
    print(‘f1_score:’,f1_score)
    print(‘Score:’,score)
    print(‘matrix:’,matrix)
    特征选择
    sklearn在Feature selection模块中内置了一个SelectFromModel,该模型可以通过Model本身给出的指标对特征进行选择,可参考https://blog.csdn.net/fontthrone/article/details/79064930
    eg:
    model = SelectFromModel(svm,prefit=True)
    X_new = model.transform(X)
    print(“X_new 共有 %s 个特征”%X_new.shape[1])
    特征选取并不一定升:所有特征有效的情况下,去除的特征只能带来模型性能的下降,即使不是全部有效很多时候,低重要程度的特征也并不一定代表着一定会导致模型性能的下降,因为某种度量方式并不代表着该特征的最终效果,很多时候我们的度量方式,往往只是一个参考而已.
    #####调参, 可用sklearn.pipeline
    from sklearn.pipeline import Pipeline
    from operator import itemgetter
    import collections
    from sklearn.metrics import classification_report
    def report(grid_scores, n_top=3):
    top_scores = sorted(grid_scores, key=itemgetter(1), reverse=True)[:n_top]
    for i, score in enumerate(top_scores):
    print(“Model with rank: {0}”.format(i + 1))
    print(“Mean validation score: {0:.3f} (std: {1:.3f})”.format(
    score.mean_validation_score,
    np.std(score.cv_validation_scores)))
    print(“Parameters: {0}”.format(score.parameters))
    print("")

跑随机森林模型
X_train, X_test, Y_train, Y_test = train_test_split(x_train, y_train, test_size=0.3, random_state=2019)
#初始化分类器
clf=RandomForestClassifier(n_estimators=500, criterion=‘entropy’, max_depth=5, min_samples_split=2,
min_samples_leaf=1, max_features=‘auto’, bootstrap=False, oob_score=False, n_jobs=1, random_state=0,
verbose=0)

###grid search找到最好的参数
param_grid = dict( )
##创建分类pipeline
pipeline=Pipeline([ (‘clf’,clf) ])
grid_search = GridSearchCV(pipeline, param_grid=param_grid, verbose=3,scoring=‘accuracy’,
cv=StratifiedShuffleSplit(n_splits=10,test_size=0.2, random_state=0)).fit(X_train, Y_train)

输出结果

print((“Best score: %0.3f” % grid_search.best_score_))
print((grid_search.best_estimator_))
#report(grid_search.best_score_)

print(’-----grid search end------------’)
print (‘on all train set’)
scores = cross_val_score(grid_search.best_estimator_, X_train, y_train,cv=3,scoring=‘accuracy’)
print(scores.mean(),scores)
print (‘on test set’)
scores = cross_val_score(grid_search.best_estimator_, X_test, Y_test,cv=3,scoring=‘accuracy’)
print(scores.mean(),scores)
print((classification_report(Y_train, grid_search.best_estimator_.predict(X_train) )))
print(‘test data’)
print((classification_report(Y_test, grid_search.best_estimator_.predict(X_test) )))
保存最优参数,再进行预测

request 4*****
1)构建LightGBM的模型(包括:模型构建&调参&性能评估),学习理论并用Task2的特征实践
2)线上提交结果;
3)[可选]尝试其他集成模型(XGBoost & GBDT & AdaBoost etc.)

Lightgbm参数设置
Lightgbm是基于决策树的分布式梯度提升框架,以选取最大信息增益作为特征选择的目标。
它最主要的参数有:
objective=‘binary’ #目标为二分类
num_leaves = 16 # 决策树叶子节点数
(Lightgbm用决策树叶子节点数来确定树的复杂度,而XGboost用max_depth确定树的复杂度)
num_threads=8 #最大线程数
learning_rate=0.05 #学习率
subsample=0.9 # 样本子集比例
n_estimators=1000 #最大迭代数
其中,num_leaves的设置与数据集特征总数有关,num_leaves尽量小于完全二叉树的叶子节点数,否则容易过拟合。
最大迭代数不必设置过大,可以在进行一次迭代后,根据最佳迭代数设置。(详细可参考https://blog.csdn.net/linxid/article/details/80785131)

#####跑LightGBM
import time
import pickle
import lightgbm as lgb
from sklearn.externals import joblib
from sklearn.model_selection import train_test_split, StratifiedKFold
from sklearn.metrics import
f1_score,recall_score,accuracy_score,confusion_matrix
t_start = time.time()
features_path = ‘./data_w_tfidf.pkl’#tfidf特征的路径
fp = open(features_path, ‘rb’)
x_train, y_train, x_test = pickle.load(fp)
fp.close()
X_train, X_valid, y_train, y_valid = train_test_split(x_train, y_train, test_size=0.3,shuffle=True, random_state=2019)
#自定义验证集的评价函数
def f1_score_vali(preds, data_vali):
labels = data_vali.get_label()
preds = np.argmax(preds.reshape(20, -1), axis=0)
score_vali = f1_score(y_true=labels, y_pred=preds, average=‘macro’)
return ‘f1_score’, score_vali, True
#读取数据,并转换到lgb的标准数据格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_valid, y_valid, reference=lgb_train)

#nfold = 5
#kf = StratifiedKFold(nfold)
#训练lgb分类器

params = {
‘boosting’: ‘gbdt’,
‘application’: ‘multiclass’,
‘num_class’: 19,
‘learning_rate’: 0.1,
‘num_leaves’: 31,
‘max_depth’: -1,
‘lambda_l1’: 0,
‘lambda_l2’: 0.5,
‘bagging_fraction’: 1.0,

}

lgb_model = lgb.train(params, lgb_train, num_boost_round = 200, valid_sets = lgb_eval, feval = f1_score_vali,
early_stopping_rounds = None, verbose_eval=True)
joblib.dump(lgb_model, “./lgb_w_tfidf.m”)

##对测试集进行预测;将预测结果转换为官方标准格式;并将结果保存至本地

y_test = np.argmax(lgb_model.predict(x_test), axis=1) + 1
df_result = pd.DataFrame(data={‘id’:range(102277), ‘class’: y_test.tolist()})
result_path = ‘…/results/’ + ‘lgb’ + ‘.csv’
df_result.to_csv(result_path, index=False)

t_end = time.time()
print(“训练结束,耗时:{}min”.format((t_end - t_start) / 60))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值