ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

代码分类功能优化(一)

2021-06-06 13:29:35  阅读:206  来源: 互联网

标签:target 代码 分类 dataset train keywords path 优化 pl


文章目录


前言

本文基于代码分类功能开发记录进行了一些优化
1、将分类类别增加至15个类别
2、加入每种语言的keywords表
3、在计算句向量时,加入keywords权重


一、优化思路

上一版模型测试结果:

1、在长文本测试集准确率达98%
2、在真实业务测试集准确率为49%

造成该结果可能的原因:

1、训练数据与真实业务数据相差较大:训练数据为一个完整的代码文件,而业务测试数据为代码段。
2、句向量计算不合理,不能体现每种语言的独特性:先前计算句向量时,用平均词向量代替句向量

二、所做的尝试

1.加入keywords权重计算句向量

在计算句向量时,还是只用平均词向量的计算方式,但加入了keywords的权重,分类模型为xgboost代码如下:

def wam(sentence, w2v_model):
    arr = []
    for s in str(sentence).split():
        if s not in w2v_model.wv.vocab.keys():
            arr.append(np.random.randn(1, 300))
        else:
            if s in keywords_result:
                arr.append(w2v_model.wv.get_vector(s) * 5)
            else:
                arr.append(w2v_model.wv.get_vector(s))
    return np.mean(np.array(arr), axis=0).reshape(1, -1)

两倍权重时:在业务数据上测试,准确率为63%
五倍权重时:在业务数据上测试,准确率为67%

2.更改词向量计算方式

词向量计算出来的向量,可以得到: 国王 + 女 = 女王
但代码之间,并不需要该关系(有点模糊,可以理解为代码与代码之间没有 for + if = XXX的关系),用词向量来将代码转为向量的方式并不合适,于是更改为tfidf的方式,分类模型为xgboost代码如下:

from sklearn.feature_extraction.text import TfidfVectorizer  

def prepare_dataset(dataset_path):
    """Load data files from directory, split into train and test.
    Return lists of target names, training samples, testing samples,
    training targets and testing targets. """
    # dataset_path = get_sgd_data_path()
    dataset = load_files(dataset_path, load_content=True,
                            encoding='UTF-8', decode_error='replace')
    X_train, X_test, y_train, y_test = train_test_split(
        dataset.data, dataset.target, test_size=0.20, random_state=3114795823)
    return dataset.target_names, X_train, X_test, y_train, y_test

dataset_path = '/Downloads/data'
target_names, X_train, X_test, y_train, y_test = prepare_dataset(dataset_path)
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(X_train)

在业务数据集上测试准确率为66%

3.加入keywords

还是使用tfidf+xgboost,但在每种语言训练文件夹下加入了对应的keywords.md文件。如图所示:
在这里插入图片描述
在这里插入图片描述
在业务数据集上测试准确率为67%

4.更改分类模型

向量化依旧使用tfidf,分类模型使用sgd,代码如下:

    def prepare_pipeline(self):
        """ Check to see if pipeline can be loaded from pickle. If not, train
        pipeline. Return pipeline and list of target names."""
        model_path = get_sgd_model_path()
        target_names_path = get_sgd_model_target_names_path()
        if os.path.isfile(model_path):
            keystone = joblib.load(model_path)
            target_names = joblib.load(target_names_path)
        else:
            target_names, X_train, X_test, y_train, y_test = self.prepare_dataset()
            keystone = Pipeline([
                ('vectorizer', CountVectorizer(
                    stop_words='english',
                    # analyzer='char_wb',
                    # max_features=256,
                )),
                ('tfidf', TfidfTransformer()),
                ('classifier', linear_model.SGDClassifier(
                    class_weight='balanced'
                ))  # 默认 SVM
            ])
            keystone.fit(X_train, y_train)
            joblib.dump(keystone, model_path, compress=1)
            joblib.dump(target_names, target_names_path, compress=1)
        return keystone, target_names

在业务数据集上测试准确率为84%


5.仅使用keywords,不使用模型

由于每种语言都有一些独特的关键词,于是尝试计算代码中每种语言keywords的个数,数量最大的特征keywords对应的语言即为预测的代码类型,代码如下:

pathlists = [c_keywords_path, cpp_keywords_path, go_keywords_path, java_keywords_path,\
            lua_keywords_path, js_keywords_path, html5_keywords_path, php_keywords_path,\
            python_keywords_path, rust_keywords_path, swift_keywords_path ]
plmapings = {'c': 0 , 'cpp': 1, 'golang': 2, 'java':3, 'lua': 4, 'javascript':5, 'html':6, 'php':7, 'python':8, 'rust':9, 'swift':10}

def get_pl_keywords(filepath):
    key_words = []
    with open(filepath, 'r', encoding='utf-8') as f:
        key = f.read()
        for i in key.split('\n'):
            key_words.append(i)
    return key_words

def count_keywords_num(text, keywords):
    count = 0
    data = text.split()
    for word in keywords:
        for i in data :
            if word in i:
                count += 1
    return count
def count_all_pl_keywords_num(keywords_pathlists, text):
    all_pl_keywords_num = []
    for keypath in keywords_pathlists:
        key_words = get_pl_keywords(keypath)
        count = count_keywords_num(text, key_words)
        all_pl_keywords_num.append(count)
    return all_pl_keywords_num

def get_pl_type(pathlists, testdata, plmaping):
    pl_keywords_num = count_all_pl_keywords_num(pathlists, testdata)
    pl_index = pl_keywords_num.index(max(pl_keywords_num, key = abs))
    result = list(plmaping.keys())[list(plmaping.values()).index(pl_index)]
    return result
#%%
pl_type = get_pl_type(pathlists, testdata_result, plmapings)

在业务测试集上准确率为67%

后续优化

后续会整理出每种语言的常用包及常用库,加入到keywords中,对准确率应该会有进一步的提升

总结

1、从上面所做的5种测试可以发现,tfidf+keywords+sgd的效果最好,但我一直很不理解,为什么tfidf+keywords+xgboost会不如tfidf+keywords+sgd,如果有理解的话,可以指点一下,万分感谢

2、仅仅使用keywords的效果比使用模型的效果更好,由此可见,对数据的理解也是NLP开发非常重要的一部分。

标签:target,代码,分类,dataset,train,keywords,path,优化,pl
来源: https://blog.csdn.net/qq_44193969/article/details/117623865

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有