refs-mcc 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aBioInf100.py +58 -0
- classifiersMulti.py +227 -0
- features.py +354 -0
- reduceData.py +49 -0
- refs_mcc-1.0.0.dist-info/METADATA +73 -0
- refs_mcc-1.0.0.dist-info/RECORD +12 -0
- refs_mcc-1.0.0.dist-info/WHEEL +5 -0
- refs_mcc-1.0.0.dist-info/entry_points.txt +2 -0
- refs_mcc-1.0.0.dist-info/top_level.txt +7 -0
- refs_mcc.py +30 -0
- sumFig.py +103 -0
- summaryMulti.py +128 -0
aBioInf100.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from features import *
|
|
2
|
+
from reduceData import *
|
|
3
|
+
|
|
4
|
+
from joblib import Parallel, delayed
|
|
5
|
+
import multiprocessing
|
|
6
|
+
import time
|
|
7
|
+
import argparse
|
|
8
|
+
|
|
9
|
+
def mainRun(indexRun, numberOfFolds) :
|
|
10
|
+
run=indexRun
|
|
11
|
+
start_time = time.time()
|
|
12
|
+
globalAnt=0.0
|
|
13
|
+
globalIndex=0
|
|
14
|
+
globalAccuracy=0.0
|
|
15
|
+
|
|
16
|
+
X, y, biomarkerNames = loadDatasetOriginal(run)
|
|
17
|
+
|
|
18
|
+
if (int(len(X[0]))>1000):
|
|
19
|
+
numberOfTopFeatures = 1000
|
|
20
|
+
else :
|
|
21
|
+
numberOfTopFeatures = int(len(X[0])*0.80)
|
|
22
|
+
|
|
23
|
+
variableSize=numberOfTopFeatures;
|
|
24
|
+
while True:
|
|
25
|
+
globalAnt=globalAccuracy
|
|
26
|
+
globalAccuracy=featureSelection(globalIndex,variableSize, run,numberOfFolds)
|
|
27
|
+
print(globalAccuracy)
|
|
28
|
+
print(globalIndex)
|
|
29
|
+
print(variableSize)
|
|
30
|
+
size,sizereduced=reduceDataset(globalIndex, run)
|
|
31
|
+
|
|
32
|
+
if(variableSize==0):
|
|
33
|
+
break
|
|
34
|
+
variableSize=int(variableSize*0.80)
|
|
35
|
+
|
|
36
|
+
globalIndex=globalIndex + 1
|
|
37
|
+
|
|
38
|
+
elapsed_time = time.time() - start_time
|
|
39
|
+
print("time")
|
|
40
|
+
print(elapsed_time)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
def main(threads, totalRuns, numberOfFolds) :
|
|
44
|
+
Parallel(n_jobs=threads, verbose=5, backend="multiprocessing")(delayed(mainRun)(i, numberOfFolds) for i in range(0,totalRuns))
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__" :
|
|
48
|
+
parser = argparse.ArgumentParser(description="Run REFS-MCC - part 1")
|
|
49
|
+
parser.add_argument('--threads', type=int, default=10, help='Number of threads (default: 10)')
|
|
50
|
+
parser.add_argument('--totalRuns', type=int, default=10, help='Total number of runs (default: 10)')
|
|
51
|
+
parser.add_argument('--folds', type=int, default=10, help='Number of folds (default: 10)')
|
|
52
|
+
args = parser.parse_args()
|
|
53
|
+
|
|
54
|
+
threads=args.threads
|
|
55
|
+
totalRuns=args.totalRuns
|
|
56
|
+
numberOfFolds=args.folds
|
|
57
|
+
|
|
58
|
+
sys.exit( main(threads, totalRuns, numberOfFolds) )
|
classifiersMulti.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import datetime
|
|
3
|
+
import logging
|
|
4
|
+
import numpy as np
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import argparse
|
|
9
|
+
|
|
10
|
+
from sklearn.ensemble import AdaBoostClassifier
|
|
11
|
+
from sklearn.ensemble import BaggingClassifier
|
|
12
|
+
from sklearn.ensemble import ExtraTreesClassifier
|
|
13
|
+
from sklearn.ensemble import GradientBoostingClassifier
|
|
14
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
15
|
+
|
|
16
|
+
from sklearn.linear_model import ElasticNet
|
|
17
|
+
from sklearn.linear_model import ElasticNetCV
|
|
18
|
+
from sklearn.linear_model import Lasso
|
|
19
|
+
from sklearn.linear_model import LassoCV
|
|
20
|
+
from sklearn.linear_model import LogisticRegression
|
|
21
|
+
from sklearn.linear_model import LogisticRegressionCV
|
|
22
|
+
from sklearn.linear_model import PassiveAggressiveClassifier
|
|
23
|
+
from sklearn.linear_model import RidgeClassifier
|
|
24
|
+
from sklearn.linear_model import RidgeClassifierCV
|
|
25
|
+
from sklearn.linear_model import SGDClassifier
|
|
26
|
+
|
|
27
|
+
from sklearn.multiclass import OneVsOneClassifier
|
|
28
|
+
from sklearn.multiclass import OneVsRestClassifier
|
|
29
|
+
from sklearn.multiclass import OutputCodeClassifier
|
|
30
|
+
|
|
31
|
+
from sklearn.naive_bayes import BernoulliNB
|
|
32
|
+
from sklearn.naive_bayes import GaussianNB
|
|
33
|
+
from sklearn.naive_bayes import MultinomialNB
|
|
34
|
+
|
|
35
|
+
from sklearn.neighbors import KNeighborsClassifier
|
|
36
|
+
from sklearn.neighbors import NearestCentroid
|
|
37
|
+
from sklearn.neighbors import RadiusNeighborsClassifier
|
|
38
|
+
|
|
39
|
+
from sklearn.svm import SVC
|
|
40
|
+
|
|
41
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
42
|
+
from sklearn.tree import ExtraTreeClassifier
|
|
43
|
+
from sklearn.neural_network import MLPClassifier
|
|
44
|
+
|
|
45
|
+
# used for normalization
|
|
46
|
+
from sklearn.preprocessing import Normalizer
|
|
47
|
+
from sklearn.preprocessing import StandardScaler
|
|
48
|
+
from sklearn.preprocessing import MinMaxScaler
|
|
49
|
+
# used for cross-validation
|
|
50
|
+
from sklearn.model_selection import StratifiedKFold
|
|
51
|
+
from sklearn.metrics import roc_curve, auc
|
|
52
|
+
from numpy import interp
|
|
53
|
+
import matplotlib.pyplot as plt
|
|
54
|
+
from pandas import read_csv
|
|
55
|
+
|
|
56
|
+
from statsmodels.multivariate.manova import MANOVA
|
|
57
|
+
import statsmodels.api as sm
|
|
58
|
+
from scipy import stats
|
|
59
|
+
from sklearn.metrics import f1_score
|
|
60
|
+
def loadDataset() :
|
|
61
|
+
|
|
62
|
+
# data used for the predictions
|
|
63
|
+
dfData = read_csv("./best/data_0.csv", header=None, sep=',')
|
|
64
|
+
dfLabels = read_csv("./best/labels.csv", header=None)
|
|
65
|
+
|
|
66
|
+
return dfData.values, dfLabels.values.ravel() # to have it in the format that the classifiers like
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def runFeatureReduce(numberOfFolds) :
|
|
70
|
+
|
|
71
|
+
# list of classifiers, selected on the basis of our previous paper "
|
|
72
|
+
classifierList = [
|
|
73
|
+
|
|
74
|
+
[GradientBoostingClassifier(n_estimators=300), "GradientBoostingClassifier(n_estimators=300)"],
|
|
75
|
+
[RandomForestClassifier(n_estimators=300), "RandomForestClassifier(n_estimators=300)"],
|
|
76
|
+
[LogisticRegression(solver='lbfgs',), "LogisticRegression"],
|
|
77
|
+
[PassiveAggressiveClassifier(),"PassiveAggressiveClassifier"],
|
|
78
|
+
[SGDClassifier(), "SGDClassifier"],
|
|
79
|
+
[SVC(kernel='linear'), "SVC(linear)"],
|
|
80
|
+
[RidgeClassifier(), "RidgeClassifier"],
|
|
81
|
+
[BaggingClassifier(n_estimators=300), "BaggingClassifier(n_estimators=300)"],
|
|
82
|
+
# ensemble
|
|
83
|
+
#[AdaBoostClassifier(), "AdaBoostClassifier"],
|
|
84
|
+
#[AdaBoostClassifier(n_estimators=300), "AdaBoostClassifier(n_estimators=300)"],
|
|
85
|
+
#[AdaBoostClassifier(n_estimators=1500), "AdaBoostClassifier(n_estimators=1500)"],
|
|
86
|
+
#[BaggingClassifier(), "BaggingClassifier"],
|
|
87
|
+
|
|
88
|
+
#[ExtraTreesClassifier(), "ExtraTreesClassifier"],
|
|
89
|
+
#[ExtraTreesClassifier(n_estimators=300), "ExtraTreesClassifier(n_estimators=300)"],
|
|
90
|
+
# features_importances_
|
|
91
|
+
#[GradientBoostingClassifier(n_estimators=300), "GradientBoostingClassifier(n_estimators=300)"],
|
|
92
|
+
#[GradientBoostingClassifier(n_estimators=1000), "GradientBoostingClassifier(n_estimators=1000)"],
|
|
93
|
+
|
|
94
|
+
#[RandomForestClassifier(n_estimators=300), "RandomForestClassifier(n_estimators=300)"],
|
|
95
|
+
#[RandomForestClassifier(n_estimators=1000), "RandomForestClassifier(n_estimators=1000)"], # features_importances_
|
|
96
|
+
|
|
97
|
+
# linear
|
|
98
|
+
#[ElasticNet(), "ElasticNet"],
|
|
99
|
+
#[ElasticNetCV(), "ElasticNetCV"],
|
|
100
|
+
#[Lasso(), "Lasso"],
|
|
101
|
+
#[LassoCV(), "LassoCV"],
|
|
102
|
+
# coef_
|
|
103
|
+
#[LogisticRegressionCV(), "LogisticRegressionCV"],
|
|
104
|
+
# coef_
|
|
105
|
+
# coef_
|
|
106
|
+
#[RidgeClassifierCV(), "RidgeClassifierCV"],
|
|
107
|
+
# coef_
|
|
108
|
+
# coef_, but only if the kernel is linear...the default is 'rbf', which is NOT linear
|
|
109
|
+
|
|
110
|
+
# naive Bayes
|
|
111
|
+
#[BernoulliNB(), "BernoulliNB"],
|
|
112
|
+
#[GaussianNB(), "GaussianNB"],
|
|
113
|
+
#[MultinomialNB(), "MultinomialNB"],
|
|
114
|
+
|
|
115
|
+
# neighbors
|
|
116
|
+
#[KNeighborsClassifier(), "KNeighborsClassifier"], # no way to return feature importance
|
|
117
|
+
# TODO this one creates issues
|
|
118
|
+
#[NearestCentroid(), "NearestCentroid"], # it does not have some necessary methods, apparently
|
|
119
|
+
#[RadiusNeighborsClassifier(), "RadiusNeighborsClassifier"],
|
|
120
|
+
|
|
121
|
+
# tree
|
|
122
|
+
#[DecisionTreeClassifier(), "DecisionTreeClassifier"],
|
|
123
|
+
#[ExtraTreeClassifier(), "ExtraTreeClassifier"],
|
|
124
|
+
[AdaBoostClassifier(n_estimators=300), "AdaBoostClassifier(n_estimators=300)"],
|
|
125
|
+
[ExtraTreesClassifier(n_estimators=300), "ExtraTreesClassifier(n_estimators=300)"],
|
|
126
|
+
[KNeighborsClassifier(), "KNeighborsClassifier"],
|
|
127
|
+
#[LassoCV(), "LassoCV"],
|
|
128
|
+
[MLPClassifier(), "MLPClassifier"],
|
|
129
|
+
[LassoCV(), "LassoCV"]
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
# this is just a hack to check a few things
|
|
133
|
+
#classifierList = [
|
|
134
|
+
# [RandomForestClassifier(), "RandomForestClassifier"]
|
|
135
|
+
# ]
|
|
136
|
+
|
|
137
|
+
print("Loading dataset...")
|
|
138
|
+
X, y = loadDataset()
|
|
139
|
+
|
|
140
|
+
print(len(X))
|
|
141
|
+
print(len(X[0]))
|
|
142
|
+
print(len(y))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
labels=np.max(y)+1
|
|
146
|
+
# prepare folds
|
|
147
|
+
skf = StratifiedKFold(n_splits=numberOfFolds, shuffle=True)
|
|
148
|
+
indexes = [ (training, test) for training, test in skf.split(X, y) ]
|
|
149
|
+
|
|
150
|
+
# this will be used for the top features
|
|
151
|
+
topFeatures = dict()
|
|
152
|
+
|
|
153
|
+
# iterate over all classifiers
|
|
154
|
+
classifierIndex = 0
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
for originalClassifier, classifierName in classifierList :
|
|
160
|
+
|
|
161
|
+
print("\nClassifier " + classifierName)
|
|
162
|
+
classifierPerformance = []
|
|
163
|
+
F1score= []
|
|
164
|
+
|
|
165
|
+
cMatrix=np.zeros((labels, labels))
|
|
166
|
+
# iterate over all folds
|
|
167
|
+
|
|
168
|
+
indexFold = 0
|
|
169
|
+
|
|
170
|
+
yTest=[]
|
|
171
|
+
yNew=[]
|
|
172
|
+
|
|
173
|
+
for train_index, test_index in indexes :
|
|
174
|
+
|
|
175
|
+
X_train, X_test = X[train_index], X[test_index]
|
|
176
|
+
y_train, y_test = y[train_index], y[test_index]
|
|
177
|
+
|
|
178
|
+
# let's normalize, anyway
|
|
179
|
+
# MinMaxScaler StandardScaler Normalizer
|
|
180
|
+
scaler = StandardScaler()
|
|
181
|
+
X_train = scaler.fit_transform(X_train)
|
|
182
|
+
X_test = scaler.transform(X_test)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
classifier = copy.deepcopy(originalClassifier)
|
|
187
|
+
classifier.fit(X_train, y_train)
|
|
188
|
+
scoreTraining = classifier.score(X_train, y_train)
|
|
189
|
+
scoreTest = classifier.score(X_test, y_test)
|
|
190
|
+
|
|
191
|
+
y_new = classifier.predict(X_test)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
yNew.append(y_new)
|
|
196
|
+
yTest.append(y_test)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
for i in range(0,len(y_new)):
|
|
200
|
+
cMatrix[y_test[i]][round(y_new[i])]+=1
|
|
201
|
+
y_new[i]=round(y_new[i])
|
|
202
|
+
|
|
203
|
+
print("\ttraining: %.4f, test: %.4f" % (scoreTraining, scoreTest))
|
|
204
|
+
classifierPerformance.append( scoreTest )
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
F1scoreTest = f1_score(y_test, y_new, average='weighted')
|
|
208
|
+
F1score.append(F1scoreTest)
|
|
209
|
+
|
|
210
|
+
pd.DataFrame(cMatrix).to_csv("./best/cMatrix"+str(classifierIndex)+".csv", header=None, index =None)
|
|
211
|
+
classifierIndex+=1
|
|
212
|
+
line ="%s \t %.4f \t %.4f \t %.4f \t %.4f\n" % (classifierName, np.mean(classifierPerformance), np.std(classifierPerformance), np.mean(F1score), np.std(F1score))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
print(line)
|
|
216
|
+
fo = open("./best/results.txt", 'a')
|
|
217
|
+
fo.write( line )
|
|
218
|
+
fo.close()
|
|
219
|
+
|
|
220
|
+
return
|
|
221
|
+
|
|
222
|
+
if __name__ == "__main__" :
|
|
223
|
+
parser = argparse.ArgumentParser(description="Run multiple classifiers based on the best run")
|
|
224
|
+
parser.add_argument('--folds', type=int, default=10, help='Number of folds (default: 10)')
|
|
225
|
+
args = parser.parse_args()
|
|
226
|
+
|
|
227
|
+
sys.exit( runFeatureReduce(args.folds) )
|
features.py
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import datetime
|
|
3
|
+
import logging
|
|
4
|
+
import numpy as np
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from sklearn.ensemble import AdaBoostClassifier
|
|
9
|
+
from sklearn.ensemble import BaggingClassifier
|
|
10
|
+
from sklearn.ensemble import ExtraTreesClassifier
|
|
11
|
+
from sklearn.ensemble import GradientBoostingClassifier
|
|
12
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
13
|
+
|
|
14
|
+
from sklearn.linear_model import ElasticNet
|
|
15
|
+
from sklearn.linear_model import ElasticNetCV
|
|
16
|
+
from sklearn.linear_model import Lasso
|
|
17
|
+
from sklearn.linear_model import LassoCV
|
|
18
|
+
from sklearn.linear_model import LogisticRegression
|
|
19
|
+
from sklearn.linear_model import LogisticRegressionCV
|
|
20
|
+
from sklearn.linear_model import PassiveAggressiveClassifier
|
|
21
|
+
from sklearn.linear_model import RidgeClassifier
|
|
22
|
+
from sklearn.linear_model import RidgeClassifierCV
|
|
23
|
+
from sklearn.linear_model import SGDClassifier
|
|
24
|
+
|
|
25
|
+
from sklearn.multiclass import OneVsOneClassifier
|
|
26
|
+
from sklearn.multiclass import OneVsRestClassifier
|
|
27
|
+
from sklearn.multiclass import OutputCodeClassifier
|
|
28
|
+
|
|
29
|
+
from sklearn.naive_bayes import BernoulliNB
|
|
30
|
+
from sklearn.naive_bayes import GaussianNB
|
|
31
|
+
from sklearn.naive_bayes import MultinomialNB
|
|
32
|
+
|
|
33
|
+
from sklearn.neighbors import KNeighborsClassifier
|
|
34
|
+
from sklearn.neighbors import NearestCentroid
|
|
35
|
+
from sklearn.neighbors import RadiusNeighborsClassifier
|
|
36
|
+
|
|
37
|
+
from sklearn.svm import SVC
|
|
38
|
+
|
|
39
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
40
|
+
from sklearn.tree import ExtraTreeClassifier
|
|
41
|
+
|
|
42
|
+
# used for normalization
|
|
43
|
+
from sklearn.preprocessing import StandardScaler
|
|
44
|
+
|
|
45
|
+
# used for cross-validation
|
|
46
|
+
from sklearn.model_selection import StratifiedKFold
|
|
47
|
+
from sklearn.metrics import matthews_corrcoef
|
|
48
|
+
|
|
49
|
+
from pandas import read_csv
|
|
50
|
+
import pandas as pd
|
|
51
|
+
|
|
52
|
+
def loadDatasetOriginal(run) :
|
|
53
|
+
|
|
54
|
+
# data used for the predictions
|
|
55
|
+
dfData = read_csv("../data/data_0.csv", header=None, sep=',')
|
|
56
|
+
dfLabels = read_csv("../data/labels.csv", header=None)
|
|
57
|
+
biomarkers = read_csv("../data/features_0.csv", header=None)
|
|
58
|
+
|
|
59
|
+
# create folder
|
|
60
|
+
folderName ="./run"+str(run)+"/"
|
|
61
|
+
if not os.path.exists(folderName) : os.makedirs(folderName)
|
|
62
|
+
|
|
63
|
+
pd.DataFrame(dfData.values).to_csv("./run"+str(run)+"/data_0.csv", header=None, index =None)
|
|
64
|
+
pd.DataFrame(biomarkers.values.ravel()).to_csv("./run"+str(run)+"/features_0.csv", header=None, index =None)
|
|
65
|
+
pd.DataFrame(dfLabels.values.ravel()).to_csv("./run"+str(run)+"/labels.csv", header=None, index =None)
|
|
66
|
+
return dfData.values, dfLabels.values.ravel(), biomarkers.values.ravel() # to have it in the format that the classifiers like
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def loadDataset(globalIndex, run) :
|
|
70
|
+
|
|
71
|
+
# data used for the predictions
|
|
72
|
+
dfData = read_csv("./run"+str(run)+"/data_"+str(globalIndex)+".csv", header=None, sep=',')
|
|
73
|
+
dfLabels = read_csv("./run"+str(run)+"/labels.csv", header=None)
|
|
74
|
+
biomarkers = read_csv("./run"+str(run)+"/features_"+str(globalIndex)+".csv", header=None)
|
|
75
|
+
|
|
76
|
+
return dfData.values, dfLabels.values.ravel(), biomarkers.values.ravel() # to have it in the format that the classifiers like
|
|
77
|
+
|
|
78
|
+
# this function returns a list of features, in relative order of importance
|
|
79
|
+
def relativeFeatureImportance(classifier) :
|
|
80
|
+
|
|
81
|
+
# this is the output; it will be a sorted list of tuples (importance, index)
|
|
82
|
+
# the index is going to be used to find the "true name" of the feature
|
|
83
|
+
orderedFeatures = []
|
|
84
|
+
|
|
85
|
+
# the simplest case: the classifier already has a method that returns relative importance of features
|
|
86
|
+
if hasattr(classifier, "feature_importances_") :
|
|
87
|
+
|
|
88
|
+
orderedFeatures = zip(classifier.feature_importances_ , range(0, len(classifier.feature_importances_)))
|
|
89
|
+
orderedFeatures = sorted(orderedFeatures, key = lambda x : x[0], reverse=True)
|
|
90
|
+
|
|
91
|
+
# some classifiers are ensembles, and if each element in the ensemble is able to return a list of feature importances
|
|
92
|
+
# (that are going to be all scored following the same logic, so they could be easily aggregated, in theory)
|
|
93
|
+
elif hasattr(classifier, "estimators_") and hasattr(classifier.estimators_[0], "feature_importances_") :
|
|
94
|
+
|
|
95
|
+
# add up the scores given by each estimator to all features
|
|
96
|
+
global_score = np.zeros(classifier.estimators_[0].feature_importances_.shape[0])
|
|
97
|
+
|
|
98
|
+
for estimator in classifier.estimators_ :
|
|
99
|
+
for i in range(0, estimator.feature_importances_.shape[0]) :
|
|
100
|
+
global_score[i] += estimator.feature_importances_[i]
|
|
101
|
+
|
|
102
|
+
# "normalize", dividing by the number of estimators
|
|
103
|
+
for i in range(0, global_score.shape[0]) : global_score[i] /= len(classifier.estimators_)
|
|
104
|
+
|
|
105
|
+
# proceed as above to obtain the ranked list of features
|
|
106
|
+
orderedFeatures = zip(global_score, range(0, len(global_score)))
|
|
107
|
+
orderedFeatures = sorted(orderedFeatures, key = lambda x : x[0], reverse=True)
|
|
108
|
+
|
|
109
|
+
# the classifier does not have "feature_importances_" but can return a list
|
|
110
|
+
# of all features used by a lot of estimators (typical of ensembles)
|
|
111
|
+
elif hasattr(classifier, "estimators_features_") :
|
|
112
|
+
|
|
113
|
+
numberOfFeaturesUsed = 0
|
|
114
|
+
featureFrequency = dict()
|
|
115
|
+
for listOfFeatures in classifier.estimators_features_ :
|
|
116
|
+
for feature in listOfFeatures :
|
|
117
|
+
if feature in featureFrequency :
|
|
118
|
+
featureFrequency[feature] += 1
|
|
119
|
+
else :
|
|
120
|
+
featureFrequency[feature] = 1
|
|
121
|
+
numberOfFeaturesUsed += len(listOfFeatures)
|
|
122
|
+
|
|
123
|
+
for feature in featureFrequency :
|
|
124
|
+
featureFrequency[feature] /= numberOfFeaturesUsed
|
|
125
|
+
|
|
126
|
+
# prepare a list of tuples (name, value), to be sorted
|
|
127
|
+
orderedFeatures = [ (featureFrequency[feature], feature) for feature in featureFrequency ]
|
|
128
|
+
orderedFeatures = sorted(orderedFeatures, key=lambda x : x[0], reverse=True)
|
|
129
|
+
|
|
130
|
+
# the classifier does not even have the "estimators_features_", but it's
|
|
131
|
+
# some sort of linear/hyperplane classifier, so it does have a list of
|
|
132
|
+
# coefficients; for the coefficients, the absolute value might be relevant
|
|
133
|
+
elif hasattr(classifier, "coef_") :
|
|
134
|
+
|
|
135
|
+
# now, "coef_" is usually multi-dimensional, so we iterate on
|
|
136
|
+
# all dimensions, and take a look at the features whose coefficients
|
|
137
|
+
# more often appear close to the top; but it could be mono-dimensional,
|
|
138
|
+
# so we need two special cases
|
|
139
|
+
dimensions = len(classifier.coef_.shape)
|
|
140
|
+
#print("dimensions=", len(dimensions))
|
|
141
|
+
featureFrequency = None # to be initialized later
|
|
142
|
+
|
|
143
|
+
# check on the dimensions
|
|
144
|
+
if dimensions == 1 :
|
|
145
|
+
featureFrequency = np.zeros(len(classifier.coef_))
|
|
146
|
+
|
|
147
|
+
relativeFeatures = zip(classifier.coef_, range(0, len(classifier.coef_)))
|
|
148
|
+
relativeFeatures = sorted(relativeFeatures, key=lambda x : abs(x[0]), reverse=True)
|
|
149
|
+
|
|
150
|
+
for index, values in enumerate(relativeFeatures) :
|
|
151
|
+
value, feature = values
|
|
152
|
+
featureFrequency[feature] += 1/(1+index)
|
|
153
|
+
|
|
154
|
+
elif dimensions > 1 :
|
|
155
|
+
featureFrequency = np.zeros(len(classifier.coef_[0]))
|
|
156
|
+
|
|
157
|
+
# so, for each dimension (corresponding to a class, I guess)
|
|
158
|
+
for i in range(0, len(classifier.coef_)) :
|
|
159
|
+
# we give a bonus to the feature proportional to
|
|
160
|
+
# its relative order, good ol' 1/(1+index)
|
|
161
|
+
relativeFeatures = zip(classifier.coef_[i], range(0, len(classifier.coef_[i])))
|
|
162
|
+
relativeFeatures = sorted(relativeFeatures, key=lambda x : abs(x[0]), reverse=True)
|
|
163
|
+
|
|
164
|
+
for index, values in enumerate(relativeFeatures) :
|
|
165
|
+
value, feature = values
|
|
166
|
+
featureFrequency[feature] += 1/(1+index)
|
|
167
|
+
|
|
168
|
+
# finally, let's sort
|
|
169
|
+
orderedFeatures = [ (featureFrequency[feature], feature) for feature in range(0, len(featureFrequency)) ]
|
|
170
|
+
orderedFeatures = sorted(orderedFeatures, key=lambda x : x[0], reverse=True)
|
|
171
|
+
|
|
172
|
+
else :
|
|
173
|
+
print("The classifier does not have any way to return a list with the relative importance of the features")
|
|
174
|
+
|
|
175
|
+
return np.array(orderedFeatures)
|
|
176
|
+
|
|
177
|
+
def featureSelection(globalIndex, variableSize,run, numberOfFolds) :
|
|
178
|
+
|
|
179
|
+
classifierList = [
|
|
180
|
+
# ensemble
|
|
181
|
+
#[AdaBoostClassifier(), "AdaBoostClassifier"],
|
|
182
|
+
#[AdaBoostClassifier(n_estimators=300), "AdaBoostClassifier(n_estimators=300)"],
|
|
183
|
+
#[AdaBoostClassifier(n_estimators=1500), "AdaBoostClassifier(n_estimators=1500)"],
|
|
184
|
+
#[BaggingClassifier(), "BaggingClassifier"],
|
|
185
|
+
|
|
186
|
+
[GradientBoostingClassifier(n_estimators=300), "GradientBoostingClassifier(n_estimators=300)"],
|
|
187
|
+
[RandomForestClassifier(n_estimators=300), "RandomForestClassifier(n_estimators=300)"],
|
|
188
|
+
[LogisticRegression(), "LogisticRegression"],
|
|
189
|
+
[PassiveAggressiveClassifier(),"PassiveAggressiveClassifier"],
|
|
190
|
+
[SGDClassifier(), "SGDClassifier"],
|
|
191
|
+
[SVC(kernel='linear'), "SVC(linear)"],
|
|
192
|
+
[RidgeClassifier(), "RidgeClassifier"],
|
|
193
|
+
[BaggingClassifier(n_estimators=300), "BaggingClassifier(n_estimators=300)"],
|
|
194
|
+
#[ExtraTreesClassifier(), "ExtraTreesClassifier"],
|
|
195
|
+
#[ExtraTreesClassifier(n_estimators=300), "ExtraTreesClassifier(n_estimators=300)"],
|
|
196
|
+
#[GradientBoostingClassifier(), "GradientBoostingClassifier"], # features_importances_
|
|
197
|
+
#[GradientBoostingClassifier(n_estimators=300), "GradientBoostingClassifier(n_estimators=300)"],
|
|
198
|
+
#[GradientBoostingClassifier(n_estimators=1000), "GradientBoostingClassifier(n_estimators=1000)"],
|
|
199
|
+
#[RandomForestClassifier(), "RandomForestClassifier"],
|
|
200
|
+
#[RandomForestClassifier(n_estimators=300), "RandomForestClassifier(n_estimators=300)"],
|
|
201
|
+
#[RandomForestClassifier(n_estimators=1000), "RandomForestClassifier(n_estimators=1000)"], # features_importances_
|
|
202
|
+
|
|
203
|
+
# linear
|
|
204
|
+
#[ElasticNet(), "ElasticNet"],
|
|
205
|
+
#[ElasticNetCV(), "ElasticNetCV"],
|
|
206
|
+
#[Lasso(), "Lasso"],
|
|
207
|
+
#[LassoCV(), "LassoCV"],
|
|
208
|
+
#[LogisticRegression(), "LogisticRegression"], # coef_
|
|
209
|
+
#[LogisticRegressionCV(), "LogisticRegressionCV"],
|
|
210
|
+
#[PassiveAggressiveClassifier(), "PassiveAggressiveClassifier"], # coef_
|
|
211
|
+
#[RidgeClassifier(), "RidgeClassifier"], # coef_
|
|
212
|
+
#[RidgeClassifierCV(), "RidgeClassifierCV"],
|
|
213
|
+
#[SGDClassifier(), "SGDClassifier"], # coef_
|
|
214
|
+
#[SVC(kernel='linear'), "SVC(linear)"], # coef_, but only if the kernel is linear...the default is 'rbf', which is NOT linear
|
|
215
|
+
|
|
216
|
+
# naive Bayes
|
|
217
|
+
#[BernoulliNB(), "BernoulliNB"],
|
|
218
|
+
#[GaussianNB(), "GaussianNB"],
|
|
219
|
+
#[MultinomialNB(), "MultinomialNB"],
|
|
220
|
+
|
|
221
|
+
# neighbors
|
|
222
|
+
#[KNeighborsClassifier(), "KNeighborsClassifier"], # no way to return feature importance
|
|
223
|
+
# TODO this one creates issues
|
|
224
|
+
#[NearestCentroid(), "NearestCentroid"], # it does not have some necessary methods, apparently
|
|
225
|
+
#[RadiusNeighborsClassifier(), "RadiusNeighborsClassifier"],
|
|
226
|
+
|
|
227
|
+
# tree
|
|
228
|
+
#[DecisionTreeClassifier(), "DecisionTreeClassifier"],
|
|
229
|
+
#[ExtraTreeClassifier(), "ExtraTreeClassifier"],
|
|
230
|
+
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
# this is just a hack to check a few things
|
|
234
|
+
#classifierList = [
|
|
235
|
+
# [RandomForestClassifier(), "RandomForestClassifier"]
|
|
236
|
+
# ]
|
|
237
|
+
|
|
238
|
+
print("Loading dataset...")
|
|
239
|
+
if (globalIndex==0):
|
|
240
|
+
X, y, biomarkerNames = loadDatasetOriginal(run)
|
|
241
|
+
else:
|
|
242
|
+
X, y, biomarkerNames = loadDataset(globalIndex, run)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
numberOfTopFeatures=int(variableSize)
|
|
247
|
+
# create folder
|
|
248
|
+
folderName ="./run"+str(run)+"/"
|
|
249
|
+
if not os.path.exists(folderName) : os.makedirs(folderName)
|
|
250
|
+
|
|
251
|
+
# prepare folds
|
|
252
|
+
skf = StratifiedKFold(n_splits=numberOfFolds, shuffle=True)
|
|
253
|
+
indexes = [ (training, test) for training, test in skf.split(X, y) ]
|
|
254
|
+
|
|
255
|
+
# this will be used for the top features
|
|
256
|
+
topFeatures = dict()
|
|
257
|
+
|
|
258
|
+
# iterate over all classifiers
|
|
259
|
+
classifierIndex = 0
|
|
260
|
+
|
|
261
|
+
globalAccuracy=0;
|
|
262
|
+
|
|
263
|
+
for originalClassifier, classifierName in classifierList :
|
|
264
|
+
|
|
265
|
+
print("\nClassifier " + classifierName)
|
|
266
|
+
classifierPerformance = []
|
|
267
|
+
classifierTopFeatures = dict()
|
|
268
|
+
|
|
269
|
+
# iterate over all folds
|
|
270
|
+
for train_index, test_index in indexes :
|
|
271
|
+
|
|
272
|
+
X_train, X_test = X[train_index], X[test_index]
|
|
273
|
+
y_train, y_test = y[train_index], y[test_index]
|
|
274
|
+
|
|
275
|
+
# let's normalize, anyway
|
|
276
|
+
scaler = StandardScaler()
|
|
277
|
+
X_train = scaler.fit_transform(X_train)
|
|
278
|
+
X_test = scaler.transform(X_test)
|
|
279
|
+
|
|
280
|
+
classifier = copy.deepcopy(originalClassifier)
|
|
281
|
+
classifier.fit(X_train, y_train)
|
|
282
|
+
#scoreTraining = classifier.score(X_train, y_train)
|
|
283
|
+
#scoreTest = classifier.score(X_test, y_test)
|
|
284
|
+
|
|
285
|
+
y_new_test = classifier.predict(X_test)
|
|
286
|
+
for i in range(0, len(y_new_test)):
|
|
287
|
+
y_new_test[i]=round(y_new_test[i])
|
|
288
|
+
y_new_train = classifier.predict(X_train)
|
|
289
|
+
for i in range(0, len(y_new_train)):
|
|
290
|
+
y_new_train[i]=round(y_new_train[i])
|
|
291
|
+
|
|
292
|
+
scoreTest = matthews_corrcoef(y_test, y_new_test)
|
|
293
|
+
scoreTraining = matthews_corrcoef(y_train, y_new_train)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
print("\ttraining: %.4f, test: %.4f" % (scoreTraining, scoreTest))
|
|
298
|
+
classifierPerformance.append( scoreTest )
|
|
299
|
+
|
|
300
|
+
# now, let's get a list of the most important features, then mark the ones in the top X
|
|
301
|
+
orderedFeatures = relativeFeatureImportance(classifier)
|
|
302
|
+
for i in range(0, numberOfTopFeatures) :
|
|
303
|
+
|
|
304
|
+
feature = int(orderedFeatures[i][1])
|
|
305
|
+
|
|
306
|
+
if feature in topFeatures :
|
|
307
|
+
topFeatures[ feature ] += 1
|
|
308
|
+
else :
|
|
309
|
+
topFeatures[ feature ] = 1
|
|
310
|
+
|
|
311
|
+
if feature in classifierTopFeatures :
|
|
312
|
+
classifierTopFeatures[ feature ] += 1
|
|
313
|
+
else :
|
|
314
|
+
classifierTopFeatures[ feature ] = 1
|
|
315
|
+
|
|
316
|
+
line ="%s\t%.4f\t%.4f\n" % (classifierName, np.mean(classifierPerformance), np.std(classifierPerformance))
|
|
317
|
+
|
|
318
|
+
globalAccuracy=globalAccuracy+np.mean(classifierPerformance)
|
|
319
|
+
|
|
320
|
+
print(line)
|
|
321
|
+
fileName=folderName+"results.txt"
|
|
322
|
+
fo = open(fileName, 'a')
|
|
323
|
+
fo.write( line )
|
|
324
|
+
fo.close()
|
|
325
|
+
# save most important features for the classifier
|
|
326
|
+
with open( os.path.join(folderName, classifierName + ".csv"), "w" ) as fp :
|
|
327
|
+
|
|
328
|
+
fp.write("feature,frequencyInTop" + str(numberOfTopFeatures) + "\n")
|
|
329
|
+
|
|
330
|
+
# transform dictionary into list
|
|
331
|
+
listOfClassifierTopFeatures = [ (key, classifierTopFeatures[key]) for key in classifierTopFeatures ]
|
|
332
|
+
listOfClassifierTopFeatures = sorted( listOfClassifierTopFeatures, key = lambda x : x[1], reverse=True )
|
|
333
|
+
|
|
334
|
+
for feature, frequency in listOfClassifierTopFeatures :
|
|
335
|
+
fp.write( str(biomarkerNames[feature]) + "," + str(float(frequency/numberOfFolds)) + "\n")
|
|
336
|
+
|
|
337
|
+
# save most important features overall
|
|
338
|
+
with open( os.path.join(folderName, "global_"+str(int(globalIndex))+".csv"), "w" ) as fp :
|
|
339
|
+
|
|
340
|
+
fp.write("feature,frequencyInTop" + str(numberOfTopFeatures) + "\n")
|
|
341
|
+
|
|
342
|
+
# transform dictionary into list
|
|
343
|
+
listOfTopFeatures = [ (key, topFeatures[key]) for key in topFeatures ]
|
|
344
|
+
listOfTopFeatures = sorted( listOfTopFeatures, key = lambda x : x[1], reverse=True )
|
|
345
|
+
|
|
346
|
+
tempIndex=0
|
|
347
|
+
for feature, frequency in listOfTopFeatures :
|
|
348
|
+
if tempIndex<numberOfTopFeatures:
|
|
349
|
+
fp.write( str(biomarkerNames[feature]) + "," + str(float(frequency/numberOfFolds)) + "\n")
|
|
350
|
+
tempIndex=tempIndex+1
|
|
351
|
+
|
|
352
|
+
globalAccuracy=globalAccuracy/8
|
|
353
|
+
return globalAccuracy
|
|
354
|
+
|
reduceData.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from pandas import read_csv
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
def reduceDataset(globalIndex, run) :
|
|
7
|
+
|
|
8
|
+
# data used for the predictions
|
|
9
|
+
if(globalIndex==0):
|
|
10
|
+
dfData = read_csv("../data/data_"+str(globalIndex)+".csv", header=None, sep=',')
|
|
11
|
+
ids=read_csv("../data/features_"+str(globalIndex)+".csv", header=None, sep=',')
|
|
12
|
+
else:
|
|
13
|
+
dfData = read_csv("./run"+str(run)+"/data_"+str(globalIndex)+".csv", header=None, sep=',')
|
|
14
|
+
ids=read_csv("./run"+str(run)+"/features_"+str(globalIndex)+".csv", header=None, sep=',')
|
|
15
|
+
|
|
16
|
+
idsRed=read_csv("./run"+str(run)+"/global_"+str(globalIndex)+".csv", sep=',')
|
|
17
|
+
|
|
18
|
+
data=dfData.values
|
|
19
|
+
idsRed=idsRed.values
|
|
20
|
+
|
|
21
|
+
ids=ids.values
|
|
22
|
+
|
|
23
|
+
print("data Y %d" %(len(data)))
|
|
24
|
+
print("data X %d" %(len(data[0])))
|
|
25
|
+
print(len(ids))
|
|
26
|
+
print(len(idsRed))
|
|
27
|
+
|
|
28
|
+
tempIds=[]
|
|
29
|
+
for i in range(0,len(idsRed)):
|
|
30
|
+
if (idsRed[i,1]>=1):
|
|
31
|
+
tempIds.append(idsRed[i,0])
|
|
32
|
+
print(len(tempIds))
|
|
33
|
+
count=0
|
|
34
|
+
|
|
35
|
+
dataRed=np.zeros((len(data),len(tempIds)))
|
|
36
|
+
|
|
37
|
+
for i in range(0,len(tempIds)):
|
|
38
|
+
for j in range (0,len(ids)):
|
|
39
|
+
if (ids[j]== tempIds[i]):
|
|
40
|
+
count=count+1
|
|
41
|
+
for k in range(0,len(data)):
|
|
42
|
+
dataRed[k,i]=data[k,j]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
pd.DataFrame(tempIds).to_csv("./run"+str(run)+"/features_"+str(globalIndex+1)+".csv", header=None, index =None)
|
|
46
|
+
pd.DataFrame(dataRed).to_csv("./run"+str(run)+"/data_"+str(globalIndex+1)+".csv", header=None, index =None)
|
|
47
|
+
print(count)
|
|
48
|
+
|
|
49
|
+
return len(ids),len(tempIds)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: refs-mcc
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Recursive Ensemble Feature Selection using Matthews Correlation Coefficient
|
|
5
|
+
Author: Alejandro Lopez-Rincon, Alberto Tonda, Brigitta Varga
|
|
6
|
+
Author-email: Alejandro Lopez-Rincon <alejandrolopezrn@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: source, https://github.com/steppenwolf0/REFS-MCC/
|
|
9
|
+
Project-URL: tracker, https://github.com/steppenwolf0/REFS-MCC/issues
|
|
10
|
+
Keywords: feature-selection,matthews-correlation-coefficient,bioinformatics,machine-learning,ensemble-learning
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: joblib>=1.5.3
|
|
26
|
+
Requires-Dist: matplotlib>=3.10.8
|
|
27
|
+
Requires-Dist: numpy>=2.4.1
|
|
28
|
+
Requires-Dist: pandas>=2.3.3
|
|
29
|
+
Requires-Dist: scikit-learn>=1.8.0
|
|
30
|
+
Requires-Dist: scipy>=1.17.0
|
|
31
|
+
Requires-Dist: statsmodels>=0.14.6
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
|
|
35
|
+
# REFS-MCC
|
|
36
|
+
Recursive Ensemble Feauture Selection using Matthews Correlation Coefficient
|
|
37
|
+
|
|
38
|
+
--------------------------------------------------------------------
|
|
39
|
+
Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install refs-mcc
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
After installation it can be used as the following (using the default parameters):
|
|
46
|
+
```python
|
|
47
|
+
from refs_mcc import REFS_MCC
|
|
48
|
+
REFS_MCC().run()
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or from CLI. For more information, run:
|
|
52
|
+
```bash
|
|
53
|
+
refs-mcc --help
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
--------------------------------------------------------------------
|
|
57
|
+
Input
|
|
58
|
+
|
|
59
|
+
Next to the folder where the code is executed from, a `data` folder needs to be present with the following files:
|
|
60
|
+
- `data_0.csv`
|
|
61
|
+
- `features_0.csv`
|
|
62
|
+
- `ids.csv`
|
|
63
|
+
- `labels.csv`
|
|
64
|
+
|
|
65
|
+
--------------------------------------------------------------------
|
|
66
|
+
Output
|
|
67
|
+
|
|
68
|
+
The following folders and files will be created:
|
|
69
|
+
- run folders (`run0`, `run1`, ..., `run{n-1}`, where n is the selected number of total runs, 10 by default)
|
|
70
|
+
- `best` folder
|
|
71
|
+
- `sumFig.pdf` & `sumFig.png`
|
|
72
|
+
|
|
73
|
+
--------------------------------------------------------------------
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
aBioInf100.py,sha256=saaD9_GwyWCd--Wc6EFaif6lcn_tMwdUbZyUyyxwmhA,1679
|
|
2
|
+
classifiersMulti.py,sha256=uLSySF0v_cdcYQj6LWDHjwTYowxjju2c3sW35PW9YuU,7737
|
|
3
|
+
features.py,sha256=UHl6NCinqlqjU286nxfTfEG9UMrCQwrcN8hkMRXcHUY,14511
|
|
4
|
+
reduceData.py,sha256=sCzoheZn8clva2RQKWwH3B-4y3wilIi5DQPXyenSIcM,1444
|
|
5
|
+
refs_mcc.py,sha256=IHzbaeSfgAIA3FtfGrtqAOXBIP5r8EdPfYwELtdn4L0,1118
|
|
6
|
+
sumFig.py,sha256=sjljlTIeOhO7pzOxuFZHTqZzw9ikVYxIQWq47xrDnLY,2819
|
|
7
|
+
summaryMulti.py,sha256=Wo44vWXY3z8OOeqFpW_tJKNHytr0lVewyFc855CVJak,3697
|
|
8
|
+
refs_mcc-1.0.0.dist-info/METADATA,sha256=ZmZYO3QcYhNobci9wr2U-gRunWITqTnCCa4KTl0-hss,2615
|
|
9
|
+
refs_mcc-1.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
10
|
+
refs_mcc-1.0.0.dist-info/entry_points.txt,sha256=Wdp8mPnH0-qa4cbpPd_xKeOJpAwZ19IsN7758QhyLlU,43
|
|
11
|
+
refs_mcc-1.0.0.dist-info/top_level.txt,sha256=cihDROHg3c_S0-46mDNd9c59gG2s9tzrDySfZYnhpc8,77
|
|
12
|
+
refs_mcc-1.0.0.dist-info/RECORD,,
|
refs_mcc.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from aBioInf100 import main as part1
|
|
5
|
+
from summaryMulti import fakeBootStrapper as part2
|
|
6
|
+
from sumFig import create_summary_figure as part3
|
|
7
|
+
|
|
8
|
+
class REFS_MCC:
|
|
9
|
+
def __init__(self, threads: int = 10, totalRuns: int = 10, numberOfFolds: int = 10):
|
|
10
|
+
self.threads = threads
|
|
11
|
+
self.totalRuns = totalRuns
|
|
12
|
+
self.numberOfFolds = numberOfFolds
|
|
13
|
+
|
|
14
|
+
def run(self):
|
|
15
|
+
part1(self.threads, self.totalRuns, self.numberOfFolds)
|
|
16
|
+
part2(self.totalRuns, self.numberOfFolds)
|
|
17
|
+
part3(self.totalRuns)
|
|
18
|
+
|
|
19
|
+
def main():
|
|
20
|
+
parser = argparse.ArgumentParser(description="REFS-MCC")
|
|
21
|
+
parser.add_argument('--threads', type=int, default=10, help='Number of threads (default: 10)')
|
|
22
|
+
parser.add_argument('--totalRuns', type=int, default=10, help='Total number of runs (default: 10)')
|
|
23
|
+
parser.add_argument('--folds', type=int, default=10, help='Number of folds (default: 10)')
|
|
24
|
+
args = parser.parse_args()
|
|
25
|
+
|
|
26
|
+
refs_mcc = REFS_MCC(args.threads, args.totalRuns, args.folds)
|
|
27
|
+
return refs_mcc.run()
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
sys.exit(main())
|
sumFig.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Thu Jan 7 12:15:27 2021
|
|
4
|
+
|
|
5
|
+
@author: alber
|
|
6
|
+
"""
|
|
7
|
+
# convert float to percentage string
|
|
8
|
+
def convert_to_percentage(f) :
|
|
9
|
+
if f != "" :
|
|
10
|
+
print("Converting \"%.4f\"..." % f)
|
|
11
|
+
percentage = f
|
|
12
|
+
return "%.1f" % percentage
|
|
13
|
+
else :
|
|
14
|
+
return ""
|
|
15
|
+
|
|
16
|
+
# script to create a figure
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
import pandas as pd
|
|
21
|
+
import matplotlib as mpl
|
|
22
|
+
import matplotlib.cm
|
|
23
|
+
import argparse
|
|
24
|
+
|
|
25
|
+
def create_summary_figure(totalRuns):
|
|
26
|
+
|
|
27
|
+
file2 = open('./best/sumA.csv', 'w')
|
|
28
|
+
|
|
29
|
+
#file2.write("features, run0, run1, run2, run3, run4, run5, run6, run7, run8, run9\n")
|
|
30
|
+
|
|
31
|
+
k = totalRuns
|
|
32
|
+
|
|
33
|
+
header = "features, " + ", ".join(f"run{i}" for i in range(k)) + "\n"
|
|
34
|
+
file2.write(header)
|
|
35
|
+
|
|
36
|
+
filepath = './best/sum.csv'
|
|
37
|
+
with open(filepath) as file1:
|
|
38
|
+
line = file1.readline()
|
|
39
|
+
cnt = 1
|
|
40
|
+
while line:
|
|
41
|
+
#print("Line {}: {}".format(cnt, line.strip()))
|
|
42
|
+
file2.write(line)
|
|
43
|
+
line = file1.readline()
|
|
44
|
+
cnt += 1
|
|
45
|
+
file1.close()
|
|
46
|
+
file2.close()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
df = pd.read_csv("./best/sumA.csv")
|
|
51
|
+
|
|
52
|
+
x = df['features'].values
|
|
53
|
+
|
|
54
|
+
features=pd.read_csv("./best/features_0.csv", header=None)
|
|
55
|
+
print("len features:"+str(len(features.values)))
|
|
56
|
+
|
|
57
|
+
maxValue=len(features.values)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
runs = [r for r in list(df) if r != 'features']
|
|
61
|
+
|
|
62
|
+
#We declare 15 because numbers 0-5 are almost white.
|
|
63
|
+
n_lines=15
|
|
64
|
+
c = np.arange(1, n_lines + 1)
|
|
65
|
+
|
|
66
|
+
norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max())
|
|
67
|
+
cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.Blues)
|
|
68
|
+
cmap.set_array([])
|
|
69
|
+
|
|
70
|
+
import matplotlib.pyplot as plt
|
|
71
|
+
fig = plt.figure(figsize=(8,6))
|
|
72
|
+
ax = fig.add_subplot(111)
|
|
73
|
+
ax.set_xscale('log')
|
|
74
|
+
|
|
75
|
+
#starts in 5 because numbers 0-5 are almost white.
|
|
76
|
+
i=5
|
|
77
|
+
for r in runs :
|
|
78
|
+
y = df[r].values
|
|
79
|
+
ax.plot(x, y, label=r, c=cmap.to_rgba(i))
|
|
80
|
+
i=i+1
|
|
81
|
+
|
|
82
|
+
plt.xticks(x, [str(a) for a in list(x)], rotation=90, fontsize=6)
|
|
83
|
+
y_locs = ax.get_yticks()
|
|
84
|
+
print(y_locs)
|
|
85
|
+
plt.yticks(y_locs, [convert_to_percentage(p) for p in y_locs])
|
|
86
|
+
|
|
87
|
+
ax.axvline(linewidth=2, color='r', x=maxValue)
|
|
88
|
+
ax.grid(linestyle='--')
|
|
89
|
+
ax.legend(loc='best')
|
|
90
|
+
ax.set_xlabel("Number of features (log scale)")
|
|
91
|
+
ax.set_ylabel("Ensemble MCC")
|
|
92
|
+
ax.set_title("MCC vs number of features in REFS runs")
|
|
93
|
+
plt.savefig("sumFig.pdf")
|
|
94
|
+
plt.savefig("sumFig.png", dpi=300)
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__" :
|
|
97
|
+
parser = argparse.ArgumentParser(description="Create summary figure")
|
|
98
|
+
parser.add_argument('--totalRuns', type=int, default=10, help='Total number of runs (default: 10)')
|
|
99
|
+
args = parser.parse_args()
|
|
100
|
+
|
|
101
|
+
totalRuns = args.totalRuns
|
|
102
|
+
|
|
103
|
+
sys.exit( create_summary_figure(totalRuns) )
|
summaryMulti.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
from classifiersMulti import *
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from pandas import read_csv
|
|
11
|
+
|
|
12
|
+
directory="data"
|
|
13
|
+
|
|
14
|
+
def fakeBootStrapper(runs, numberOfFolds):
|
|
15
|
+
# create folder
|
|
16
|
+
folderName ="./best/"
|
|
17
|
+
if not os.path.exists(folderName) : os.makedirs(folderName)
|
|
18
|
+
|
|
19
|
+
orig_stdout = sys.stdout
|
|
20
|
+
f = open('./best/out.txt', 'w')
|
|
21
|
+
sys.stdout = f
|
|
22
|
+
|
|
23
|
+
directory="run"+str(0)
|
|
24
|
+
f=open("./"+directory+"/results.txt", "r")
|
|
25
|
+
fl =f.readlines()
|
|
26
|
+
blocks=int(len(fl)/8)
|
|
27
|
+
print(blocks)
|
|
28
|
+
results=np.zeros((blocks,runs+1))
|
|
29
|
+
for j in range(0,runs):
|
|
30
|
+
directory="run"+str(j)
|
|
31
|
+
f=open("./"+directory+"/results.txt", "r")
|
|
32
|
+
fl =f.readlines()
|
|
33
|
+
blocks=int(len(fl)/8)
|
|
34
|
+
count=0
|
|
35
|
+
value=0
|
|
36
|
+
variables=np.zeros(blocks)
|
|
37
|
+
accuracy=np.zeros(blocks)
|
|
38
|
+
indexResults=0
|
|
39
|
+
for x in fl:
|
|
40
|
+
a=x.split("\t")
|
|
41
|
+
value=value+float(a[1])/8.0
|
|
42
|
+
count=count+1
|
|
43
|
+
if (count==8):
|
|
44
|
+
accuracy[indexResults]=value
|
|
45
|
+
value=0
|
|
46
|
+
count=0
|
|
47
|
+
indexResults=indexResults+1
|
|
48
|
+
indexResults=0
|
|
49
|
+
|
|
50
|
+
for i in range (0,blocks):
|
|
51
|
+
dfFeats = (read_csv("./"+directory+"/features_"+str(i)+".csv", header=None)).values.ravel()
|
|
52
|
+
variables[i]=len(dfFeats)
|
|
53
|
+
results[i,j+1]=accuracy[i]
|
|
54
|
+
results[i,0]=variables[i]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
pd.DataFrame(results).to_csv("./best/sum.csv", header=None, index =None)
|
|
59
|
+
|
|
60
|
+
bestVal=np.zeros(runs)
|
|
61
|
+
bestSize=np.zeros(runs)
|
|
62
|
+
bestPos=np.zeros(runs)
|
|
63
|
+
for j in range(0,runs):
|
|
64
|
+
bestVal[j]=np.max(results[:,j+1])
|
|
65
|
+
|
|
66
|
+
for j in range(0,runs):
|
|
67
|
+
for i in range (0,blocks):
|
|
68
|
+
if ( bestVal[j]==results[i,j+1]):
|
|
69
|
+
bestSize[j]=int(results[i,0])
|
|
70
|
+
bestPos[j]=i
|
|
71
|
+
print(bestVal)
|
|
72
|
+
print(bestSize)
|
|
73
|
+
print(bestPos)
|
|
74
|
+
|
|
75
|
+
bestFeatures=[]
|
|
76
|
+
signatures=[]
|
|
77
|
+
for j in range(0,runs):
|
|
78
|
+
dfFeats = (read_csv("./run"+str(j)+"/features_"+str(int(bestPos[j]))+".csv", header=None))
|
|
79
|
+
bestFeatures.extend(dfFeats.values.ravel())
|
|
80
|
+
signatures.append(dfFeats.values.ravel())
|
|
81
|
+
#print(bestFeatures)
|
|
82
|
+
signatures.append(bestVal)
|
|
83
|
+
signatures.append(bestSize)
|
|
84
|
+
pd.DataFrame(signatures).to_csv("./best/signatures.csv", header=None, index =None)
|
|
85
|
+
|
|
86
|
+
unique, counts = np.unique(bestFeatures, return_counts=True)
|
|
87
|
+
|
|
88
|
+
resultsFeatures=np.zeros((len(unique),2), 'U16')
|
|
89
|
+
for j in range(0,len(unique)):
|
|
90
|
+
resultsFeatures[j,0]=unique[j]
|
|
91
|
+
resultsFeatures[j,1]=counts[j]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
pd.DataFrame(resultsFeatures).to_csv("./best/resultsFeatures.csv", header=None, index =None)
|
|
95
|
+
|
|
96
|
+
print(np.max(bestVal))
|
|
97
|
+
print(np.argmax(bestVal))
|
|
98
|
+
print(int(bestPos[np.argmax(bestVal)]))
|
|
99
|
+
|
|
100
|
+
runBest=int(np.argmax(bestVal))
|
|
101
|
+
indexBest=int(bestPos[np.argmax(bestVal)])
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# data used for the predictions
|
|
106
|
+
dfData = read_csv("./run"+str(runBest)+"/data_"+str(indexBest)+".csv", header=None, sep=',')
|
|
107
|
+
dfLabels = read_csv("./run"+str(runBest)+"/labels.csv", header=None)
|
|
108
|
+
biomarkers = read_csv("./run"+str(runBest)+"/features_"+str(indexBest)+".csv", header=None)
|
|
109
|
+
|
|
110
|
+
pd.DataFrame(dfData.values).to_csv("./best/data_0.csv", header=None, index =None)
|
|
111
|
+
pd.DataFrame(biomarkers.values.ravel()).to_csv("./best/features_0.csv", header=None, index =None)
|
|
112
|
+
pd.DataFrame(dfLabels.values.ravel()).to_csv("./best/labels.csv", header=None, index =None)
|
|
113
|
+
|
|
114
|
+
runFeatureReduce(numberOfFolds)
|
|
115
|
+
sys.stdout = orig_stdout
|
|
116
|
+
f.close()
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
if __name__ == "__main__" :
|
|
120
|
+
parser = argparse.ArgumentParser(description="Run REFS-MCC - part 2")
|
|
121
|
+
parser.add_argument('--totalRuns', type=int, default=10, help='Total number of runs (default: 10)')
|
|
122
|
+
parser.add_argument('--folds', type=int, default=10, help='Number of folds (default: 10)')
|
|
123
|
+
args = parser.parse_args()
|
|
124
|
+
|
|
125
|
+
runs=args.totalRuns
|
|
126
|
+
numberOfFolds=args.folds
|
|
127
|
+
|
|
128
|
+
sys.exit( fakeBootStrapper(runs, numberOfFolds) )
|