Skip to content

Commit f0e7023

Browse files
authored
Release 0.6.4 (#76)
* update contact email * filter values for flesch and sentence length * Release 0.6.3 (#73) (#74) * update contact email * use alternative version of textstat for flesch scores * filter values for flesch and sentence length * add argument to return single prediction for multiclass probability estimate (#75) * Update version 0.6.4
1 parent 4cbef96 commit f0e7023

4 files changed

Lines changed: 41 additions & 12 deletions

File tree

quantgov/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
from . import corpus, nlp, ml, utils
55
from .utils import load_driver
66

7-
__version__ = '0.6.3'
7+
__version__ = '0.6.4'

quantgov/__main__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ def parse_args():
128128
estimate.add_argument(
129129
'--precision', default=4, type=int,
130130
help='number of decimal places to round the probabilities')
131+
estimate.add_argument(
132+
'--oneclass', action='store_true',
133+
help='only return predicted class for multiclass probabilty estimates')
131134
estimate.add_argument(
132135
'-o', '--outfile',
133136
type=lambda x: open(x, 'w', newline='', encoding='utf-8'),
@@ -223,7 +226,8 @@ def run_estimator(args):
223226
args.estimator,
224227
args.corpus,
225228
args.probability,
226-
args.precision)
229+
args.precision,
230+
args.oneclass)
227231
)
228232

229233

quantgov/ml/estimation.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Functionality for making predictions with an estimator
55
"""
66
import logging
7+
import numpy as np
78

89
log = logging.getLogger(__name__)
910

@@ -106,7 +107,7 @@ def estimate_probability_multilabel(estimator, streamer, precision):
106107
)
107108

108109

109-
def estimate_probability_multiclass(estimator, streamer, precision):
110+
def estimate_probability_multiclass(estimator, streamer, precision, oneclass):
110111
"""
111112
Generate probabilities for a one-label, multiclass estimator
112113
@@ -119,12 +120,24 @@ def estimate_probability_multiclass(estimator, streamer, precision):
119120
120121
"""
121122
texts = (doc.text for doc in streamer)
122-
probs = estimator.pipeline.predict_proba(texts).round(precision)
123-
yield from (
124-
(docidx, (class_, probability))
125-
for docidx, doc_probs in zip(streamer.index, probs)
126-
for class_, probability in zip(estimator.pipeline.classes_, doc_probs)
127-
)
123+
probs = estimator.pipeline.predict_proba(texts)
124+
# If oneclass flag is true, only returns the predicted class
125+
if oneclass:
126+
class_indices = list(i[-1] for i in np.argsort(probs, axis=1))
127+
yield from (
128+
(docidx, (estimator.pipeline.classes_[class_index],
129+
doc_probs[class_index].round(precision)))
130+
for docidx, doc_probs, class_index in zip(
131+
streamer.index, probs, class_indices)
132+
)
133+
# Else returns probabilty values for all classes
134+
else:
135+
yield from (
136+
(docidx, (class_, probability.round(precision)))
137+
for docidx, doc_probs in zip(streamer.index, probs)
138+
for class_, probability in zip(
139+
estimator.pipeline.classes_, doc_probs)
140+
)
128141

129142

130143
def estimate_probability_multilabel_multiclass(estimator, streamer, precision):
@@ -140,7 +153,7 @@ def estimate_probability_multilabel_multiclass(estimator, streamer, precision):
140153
141154
"""
142155
texts = (doc.text for doc in streamer)
143-
probs = estimator.pipeline.predict_proba(texts)
156+
probs = estimator.pipeline.predict_proba(texts).round(precision)
144157
yield from (
145158
(docidx, (label_name, class_, prob))
146159
for label_name, label_probs in zip(estimator.label_names, probs)
@@ -149,7 +162,8 @@ def estimate_probability_multilabel_multiclass(estimator, streamer, precision):
149162
)
150163

151164

152-
def estimate(estimator, corpus, probability, precision=4, *args, **kwargs):
165+
def estimate(estimator, corpus, probability, precision=4, oneclass=False,
166+
*args, **kwargs):
153167
"""
154168
Estimate label values for documents in corpus
155169
@@ -171,7 +185,7 @@ def estimate(estimator, corpus, probability, precision=4, *args, **kwargs):
171185
estimator, streamer, precision)
172186
elif estimator.multiclass: # Multiclass probability
173187
yield from estimate_probability_multiclass(
174-
estimator, streamer, precision)
188+
estimator, streamer, precision, oneclass)
175189
else: # Simple probability
176190
yield from estimate_probability(
177191
estimator, streamer, precision)

tests/test_ml.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,14 @@ def test_multiclass_probability_estimator():
6565
'moby,money,0.1536\n'
6666
'moby,science-and-technology,0.1671\n'
6767
'moby,world,0.141\n')
68+
69+
70+
def test_multiclass_probability_oneclass_estimator():
71+
output = check_output(
72+
['quantgov', 'ml', 'estimate',
73+
str(PSEUDO_ESTIMATOR_PATH.joinpath('data', 'multiclass.qge')),
74+
str(PSEUDO_CORPUS_PATH), '--probability', '--oneclass']
75+
)
76+
assert output == ('file,class,probability\n'
77+
'cfr,world,0.1997\n'
78+
'moby,health-and-public-welfare,0.205\n')

0 commit comments

Comments
 (0)