利用python实现对csv,arff,libsvm特征文件的导入,同时实现svm+f-score特征选择

使用方法

使用python语言实现对于支持向量机(SVM)特征选择的实现,特征选择算法为f-score,该程序的主要有点是可输入文件囊括了csv,libsvm,arff等在序列分类的机器学习领域常用到的格式,其中csv:最后一列为class,libsvm:第一列为class,arff:通常最后一列为类别,其中csv和libsvm中不存在开头,直接是使用的数据。
python train.py -i 1.csv,2.csv,3.libsvm,4.arff -c 5

  • 其中train.py为程序名称
  • -i :后面接文件名,可以为csv,libsvm,arff格式,多个文件也可以用,但建议不要,因为特征选择时间通常很长
  • -c:后面5代表五折交叉验证
    #!/usr/bin/env python
# encoding:utf-8
import os
import sys
import getopt
import threading
import pandas as pd
import math
import numpy as np
from time import clock
from sklearn.feature_selection import  f_classif
from sklearn.externals.joblib import Memory
from sklearn import  metrics
import easy_excel

import itertools
from sklearn.model_selection import KFold  
from sklearn import svm
from sklearn.model_selection import train_test_split
import math
from xgboost import XGBClassifier
from sklearn.neighbors import KNeighborsClassifier
import easy_excel
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import *
import sklearn.ensemble
from sklearn.externals import joblib
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
from sklearn.metrics import roc_curve, auc
import sys
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB  
import subprocess
from sklearn.utils import shuffle
import itertools
from sklearn.ensemble import GradientBoostingClassifier
import sys
from sklearn.decomposition import PCA
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC, LinearSVC
from sklearn.naive_bayes import BernoulliNB
from sklearn.datasets import load_svmlight_file
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import SGDClassifier, LogisticRegression
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, \
    BaggingClassifier, ExtraTreesClassifier, GradientBoostingClassifier

def performance(labelArr, predictArr):
    #labelArr[i] is actual value,predictArr[i] is predict value
    TP = 0.; TN = 0.; FP = 0.; FN = 0.
    for i in range(len(labelArr)):
        if labelArr[i] == 1 and predictArr[i] == 1:
            TP += 1.
        if labelArr[i] == 1 and predictArr[i] == 0:
            FN += 1.
        if labelArr[i] == 0 and predictArr[i] == 1:
            FP += 1.
        if labelArr[i] == 0 and predictArr[i] == 0:
            TN += 1.
    if (TP + FN)==0:
        SN=0
    else:
        SN = TP/(TP + FN) #Sensitivity = TP/P  and P = TP + FN
    if (FP+TN)==0:
        SP=0
    else:
        SP = TN/(FP + TN) #Specificity = TN/N  and N = TN + FP
    if (TP+FP)==0:
        precision=0
    else:
        precision=TP/(TP+FP)
    if (TP+FN)==0:
        recall=0
    else:
        recall=TP/(TP+FN)
    GM=math.sqrt(recall*SP)
    #MCC = (TP*TN-FP*FN)/math.sqrt((TP+FP)*(TP+FN)*(TN+FP)*(TN+FN))
    return precision,recall,SN,SP,GM,TP,TN,FP,FN


mem = Memory("./mycache")
@mem.cache
def get_data(file_name):
    data = load_svmlight_file(file_name)
    return data[0], data[1]


def csv_and_arff2svm(arff_files):
    svm_files = []
    for arff_file in arff_files:
        name = arff_file[0: arff_file.rindex('.')]
        tpe = arff_file[arff_file.rindex('.')+1:]
        svm_file = name+".libsvm"
        svm_files.append(svm_file)
        if tpe == "arff":
            if os.path.exists(svm_file):
                pass
            else:
                f = open(arff_file)
                w = open(svm_file, 'w')
                flag = False
                for line in f.readlines():
                    if flag:
                        if line.strip() == '':
                            continue
                        temp = line.strip('\n').strip('\r').split(',')
                        w.write(temp[len(temp)-1])
                        for i in range(len(temp)-1):
                            w.write(' '+str(i+1)+':'+str(temp[i]))
                        w.write('\n')
                    else:
                        line = line.upper()
                        if line.startswith('@DATA') or flag:
                            flag = True
                f.close()
                w.close()
        elif tpe == "csv":
            if os.path.exists(svm_file):
                pass
            else:
                f = open(arff_file)
                w = open(svm_file, 'w')
                for line in f.readlines():
                    if line.strip() == '':
                        continue
                    temp = line.strip('\n').strip('\r').split(',')
                    w.write(temp[len(temp)-1])
                    for i in range(len(temp)-1):
                        w.write(' '+str(i+1)+':'+str(temp[i]))
                    w.write('\n')
                f.close()
                w.close()
        elif tpe == "libsvm":
            continue
        else:
            print "File format error! Arff and libsvm are passed."
            sys.exit()
    return svm_files
opts, args = getopt.getopt(sys.argv[1:], "hi:c:t:o:s:m:", )
for op, value in opts:
    if op == "-i":
        input_files = str(value)
        input_files = input_files.replace(" ", "").split(',')
        for input_file in input_files:
            if input_file == "":
                print "Warning: please insure no blank in your input files !"
                sys.exit()
    elif op == "-c":
        cv = int(value)
if __name__ =="__main__":
    path=""
    outputname="svm_f-score"
    name=outputname
    print '*** Validating file format ...'
    input_files = csv_and_arff2svm(input_files)
    for input_file in input_files:
        # 导入原始数据
        X, Y = get_data(input_file)
        train_data = X.todense()
        train_data=np.array(train_data)
        F, pval = f_classif(train_data, Y)
        idx = np.argsort(F)
        selected_list_=idx[::-1]
        F_sort_value=[F[e] for e in selected_list_]
        with open("all_dimension_results.txt",'a') as f:
                f.write(str(F_sort_value)+"\n")
        print F_sort_value
        with open("all_dimension_results.txt",'a') as f:
                f.write(str(selected_list_)+"\n")
        print selected_list_
        bestACC=0
        bestC=0
        bestgamma=0
        best_dimension=0
        all_dimension_results=[]
        for select_num in xrange(1,len(train_data[0])+1):
            train_data2=train_data
            print np.array(train_data).shape
            print np.array(train_data2).shape
            selected_list_2=selected_list_[xrange(select_num)]
            X_train=pd.DataFrame(train_data2)
            X_train=X_train.iloc[:,selected_list_2]
            X = np.array(X_train)
            svc = svm.SVC()
            parameters = {'kernel': ['rbf'], 'C':map(lambda x:2**x,np.linspace(-2,5,7)), 'gamma':map(lambda x:2**x,np.linspace(-5,2,7))}
            clf = GridSearchCV(svc, parameters, cv=cv, n_jobs=2, scoring='accuracy')
            clf.fit(X, Y)
            C=clf.best_params_['C']
            joblib.dump(clf,path+outputname+str(select_num)+".model")
            gamma=clf.best_params_['gamma']
            y_predict=cross_val_predict(svm.SVC(kernel='rbf',C=C,gamma=gamma),X,Y,cv=cv,n_jobs=2)
            y_predict_prob=cross_val_predict(svm.SVC(kernel='rbf',C=C,gamma=gamma,probability=True),X,Y,cv=cv,n_jobs=2,method='predict_proba')
            predict_save=[Y.astype(int),y_predict.astype(int),y_predict_prob[:,1]]
            predict_save=np.array(predict_save).T
            pd.DataFrame(predict_save).to_csv(path+outputname+"_"+'_predict_crossvalidation.csv',header=None,index=False)
            ROC_AUC_area=metrics.roc_auc_score(Y,y_predict)
            ACC=metrics.accuracy_score(Y,y_predict)
            precision, recall, SN, SP, GM, TP, TN, FP, FN = performance(Y, y_predict)
            F1_Score=metrics.f1_score(Y, y_predict)
            F_measure=F1_Score
            MCC=metrics.matthews_corrcoef(Y, y_predict)
            pos=TP+FN
            neg=FP+TN
            savedata=[[['svm'+"C:"+str(C)+"gamma:"+str(gamma),ACC,precision, recall,SN, SP, GM,F_measure,F1_Score,MCC,ROC_AUC_area,TP,FN,FP,TN,pos,neg]]]
            if ACC>bestACC:
                bestACC=ACC
                bestgamma=gamma
                bestC=C
                best_dimension=X.shape[1]
            print savedata
            print X.shape[1]
            with open("all_dimension_results.txt",'a') as f:
                f.write(str(savedata)+"\n")
            all_dimension_results.append(savedata)
        print bestACC
        print bestC
        print bestgamma
        print best_dimension
        easy_excel.save("svm_crossvalidation",[str(X.shape[1])],savedata,path+'cross_validation_'+name+'.xls')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容