waliullah123 commited on
Commit
5907e4a
·
verified ·
1 Parent(s): c81673d

Upload models.py

Browse files
Files changed (1) hide show
  1. models.py +119 -0
models.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from sklearn.naive_bayes import MultinomialNB, ComplementNB
4
+ from sklearn.linear_model import LogisticRegression
5
+ from sklearn.svm import LinearSVC
6
+ from sklearn.calibration import CalibratedClassifierCV
7
+ from sklearn.ensemble import (
8
+ VotingClassifier, RandomForestClassifier, StackingClassifier,
9
+ GradientBoostingClassifier, HistGradientBoostingClassifier
10
+ )
11
+ from sklearn.feature_selection import SelectKBest, f_classif
12
+ from sklearn.pipeline import Pipeline
13
+ from sklearn.compose import ColumnTransformer
14
+ from sklearn.preprocessing import MinMaxScaler
15
+ from sklearn.feature_extraction.text import TfidfVectorizer
16
+ from dl_model import DeepNewsClassifier # §3.3.2 Deep Learning Module
17
+
18
+
19
+ class FakeNewsModels:
20
+ def __init__(self):
21
+ # All hand-crafted numeric columns (original + new deception features)
22
+ num_cols = [
23
+ # Original features
24
+ 'lexical_density', 'capital_ratio', 'noun_ratio', 'speaker_reliability',
25
+ 'sentiment_score', 'complexity_score', 'subjectivity_score',
26
+ 'verb_ratio', 'adj_ratio', 'adv_ratio', 'punctuation_aggression',
27
+ 'entity_density', 'formal_cadence', 'official_marker',
28
+ # Hedging & Certainty
29
+ 'hedge_ratio', 'certainty_ratio', 'hedge_certainty_diff',
30
+ # Emotional
31
+ 'emotional_intensity', 'sentiment_extremity',
32
+ 'negativity_score', 'positivity_score',
33
+ # Numerical
34
+ 'number_density', 'has_percentage', 'has_dollar_amount', 'number_count',
35
+ # Source / Attribution
36
+ 'attribution_ratio', 'has_source_citation',
37
+ # Readability
38
+ 'ari_score', 'gunning_fog', 'avg_sentence_length',
39
+ # Pronoun & Modality
40
+ 'first_person_ratio', 'modal_ratio', 'negation_ratio',
41
+ # Comparison
42
+ 'comparative_ratio', 'superlative_ratio',
43
+ # Voice
44
+ 'passive_ratio',
45
+ # Urgency / Style
46
+ 'caps_word_ratio', 'ellipsis_count',
47
+ 'exclamation_marks', 'question_marks', 'quotes_count',
48
+ 'total_words', 'avg_word_length',
49
+ # Social context history
50
+ 'false_history_ratio', 'true_history_ratio', 'history_volume',
51
+ 'is_republican', 'is_democrat',
52
+ ]
53
+
54
+ preprocessor = ColumnTransformer(
55
+ transformers=[
56
+ ('text', TfidfVectorizer(
57
+ ngram_range=(1, 3),
58
+ max_features=12000,
59
+ min_df=3,
60
+ max_df=0.75,
61
+ sublinear_tf=True,
62
+ stop_words='english'
63
+ ), 'statement'),
64
+ ('meta', MinMaxScaler(), num_cols),
65
+ ],
66
+ remainder='drop'
67
+ )
68
+
69
+ # Feature selection: keep top 5000 features
70
+ selector = SelectKBest(f_classif, k=5000)
71
+
72
+ # Individual classifiers — tuned for better performance and calibrated uncertainty
73
+ nb_clf = CalibratedClassifierCV(ComplementNB(alpha=0.1))
74
+ lr_clf = LogisticRegression(
75
+ C=0.8, max_iter=3000, solver='lbfgs',
76
+ class_weight='balanced', l1_ratio=0
77
+ )
78
+ svm_clf = CalibratedClassifierCV(
79
+ LinearSVC(C=0.5, max_iter=5000, class_weight='balanced', dual='auto')
80
+ )
81
+ rf_clf = CalibratedClassifierCV(
82
+ RandomForestClassifier(
83
+ n_estimators=600, max_depth=22, min_samples_leaf=3,
84
+ class_weight='balanced', random_state=42, n_jobs=-1
85
+ )
86
+ )
87
+
88
+ self.models = {
89
+ 'nb': Pipeline([('pre', preprocessor), ('sel', selector), ('clf', nb_clf)]),
90
+ 'lr': Pipeline([('pre', preprocessor), ('sel', selector), ('clf', lr_clf)]),
91
+ 'svm': Pipeline([('pre', preprocessor), ('sel', selector), ('clf', svm_clf)]),
92
+ 'rf': Pipeline([('pre', preprocessor), ('sel', selector), ('clf', rf_clf)]),
93
+ # §3.3.2 Deep Learning Module — BiLSTM-approximating dual encoder
94
+ 'dl': DeepNewsClassifier(),
95
+ }
96
+
97
+ # STACKING ENSEMBLE with LogisticRegression meta-learner (§3.3)
98
+ # Includes Deep Learning module as 5th base estimator
99
+ self.models['ensemble'] = StackingClassifier(
100
+ estimators=[
101
+ ('nb', self.models['nb']),
102
+ ('lr', self.models['lr']),
103
+ ('svm', self.models['svm']),
104
+ ('rf', self.models['rf']),
105
+ ('dl', self.models['dl']), # §3.3.2
106
+ ],
107
+ final_estimator=LogisticRegression(
108
+ C=0.5, class_weight='balanced', max_iter=1000
109
+ ),
110
+ stack_method='predict_proba',
111
+ cv=5,
112
+ n_jobs=-1
113
+ )
114
+
115
+ def get_model(self, name):
116
+ return self.models.get(name)
117
+
118
+ def get_all_models(self):
119
+ return self.models