Import Packages

In [10]:
import pandas as pd
import string
from nltk.corpus import stopwords
from nltk.stem.snowball import SpanishStemmer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.ensemble import VotingClassifier
from sklearn.multiclass import OneVsRestClassifier
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score
from sklearn.metrics import log_loss
from nltk.corpus import stopwords
from scipy.sparse import hstack

Load Data

In [7]:
train_data = pd.read_excel('train_universidad.xlsx',sheetname=1)
test_data = pd.read_excel('test_universidad.xlsx')

Get Columns

In [8]:
train_data.columns
Out[8]:
Index(['COD_ENCUESTADO', 'Nombre Campus', 'NIVEL ACTUAL', 'Clave de carrera',
       'Ciclo', 'COMENTARIO', 'IND_GEA', 'IND_DELEGADO',
       'CANT_CURSOS_MATRICU_SIN_INGLES', 'UOD_depostista_ind_deportista',
       'NPS'],
      dtype='object')

First 5 rows

In [9]:
train_data.head()
Out[9]:
COD_ENCUESTADO Nombre Campus NIVEL ACTUAL Clave de carrera Ciclo COMENTARIO IND_GEA IND_DELEGADO CANT_CURSOS_MATRICU_SIN_INGLES UOD_depostista_ind_deportista NPS
0 13501 1 AC 3 2 Me gusta la u es paja bro y soy pito NaN Delegado 6.0 NaN 3
1 23622 3 AC 25 1 El metodo de blended no le hace bien a todos NaN Delegado 5.0 NaN 3
2 8354 4 AC 31 1 Los profesores, sus métodos de enseñanza bes ... NaN NaN 5.0 NaN 4
3 17745 4 AC 28 6 Porque posee gran mayoría de profesores espec... GEA NaN 6.0 NaN 3
4 10867 3 AC 34 1 La pencion NaN NaN 6.0 NaN 3

Append Data

In [11]:
all_data = train_data.append(test_data)

Adding 'Comentario' length

In [12]:
all_data['COMENTARIO_LEN'] =all_data['COMENTARIO'].str.len()

Columns Sets

In [13]:
data_cols= ['NIVEL ACTUAL',
       'Ciclo', 'COMENTARIO', 'COMENTARIO_LEN', 'IND_GEA', 'IND_DELEGADO',
       'CANT_CURSOS_MATRICU_SIN_INGLES', 'UOD_depostista_ind_deportista']

model_cols= ['NIVEL ACTUAL',
       'Ciclo', 'IND_GEA', 'IND_DELEGADO',
       'CANT_CURSOS_MATRICU_SIN_INGLES', 'UOD_depostista_ind_deportista']

model_log_cols= ['NIVEL ACTUAL',
       'Ciclo', 'COMENTARIO_LEN','IND_GEA', 'IND_DELEGADO',
       'CANT_CURSOS_MATRICU_SIN_INGLES', 'UOD_depostista_ind_deportista']

Cleaning Data

In [14]:
all_data['IND_GEA'] = all_data['IND_GEA'].map({'IND_GEA':1}).fillna(0)
all_data['IND_DELEGADO'] = all_data['IND_DELEGADO'].map({'Delegado':1}).fillna(0)
all_data['UOD_depostista_ind_deportista'] = all_data['UOD_depostista_ind_deportista'].map({'Deportista':1}).fillna(0)
all_data['CANT_CURSOS_MATRICU_SIN_INGLES'] = all_data['CANT_CURSOS_MATRICU_SIN_INGLES'].fillna(4)

Encoding 'Nivel Actual'

In [15]:
le = LabelEncoder()
In [16]:
all_data['NIVEL ACTUAL'] = le.fit_transform(all_data['NIVEL ACTUAL'])
In [17]:
all_data = all_data.reset_index(drop=True)

Removing stopwords, punctuation, stemming.

In [18]:
stop = stopwords.words('spanish')
stemmer = SpanishStemmer()
In [19]:
pretable = dict.fromkeys(string.punctuation)
table = str.maketrans(pretable)
In [20]:
all_data['COMENTARIO'] = all_data['COMENTARIO'].apply(lambda x: ' '.join([word.translate(table) for word in x.split() if word not in stop]))
In [21]:
all_data['COMENTARIO'] = all_data['COMENTARIO'].str.\
    replace('enseñansa','enseñanza').\
    replace('pencion','pension')
In [22]:
all_data['COMENTARIO'] = all_data['COMENTARIO'].apply(lambda x: ' '.join([stemmer.stem(word) for word in x.split() if word not in stop]))
In [23]:
all_data.head()
Out[23]:
CANT_CURSOS_MATRICU_SIN_INGLES COD_ENCUESTADO COMENTARIO Ciclo Clave de carrera IND_DELEGADO IND_GEA NIVEL ACTUAL NPS Nombre Campus UOD_depostista_ind_deportista COMENTARIO_LEN
0 6.0 13501 me gust u paj bro pit 2 3 1.0 0.0 0 3.0 1 0.0 37
1 5.0 23622 el metod blend hac bien 1 25 1.0 0.0 0 3.0 3 0.0 45
2 5.0 8354 los profesor metod enseñ bes buen el uso tecno... 1 31 0.0 0.0 0 4.0 4 0.0 168
3 6.0 17745 porqu pose gran mayor profesor especializ enseñ 6 28 0.0 0.0 0 3.0 4 0.0 73
4 6.0 10867 la pencion 1 34 0.0 0.0 0 3.0 3 0.0 11

Split Data

In [24]:
X = all_data.loc[:19999,data_cols]
y = all_data.loc[:19999,'NPS']
X_final = all_data.loc[20000:,data_cols]
In [25]:
x_train,x_test, y_train, y_test = train_test_split(X,y, test_size=0.1,random_state=1)

Vectorize 'Comentarios'

In [26]:
vec = TfidfVectorizer(ngram_range=(1,3), min_df=0.001, max_df=0.6,strip_accents='unicode')
In [27]:
vec
Out[27]:
TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=0.6, max_features=None, min_df=0.001,
        ngram_range=(1, 3), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents='unicode', sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)
In [28]:
vec.fit(x_train['COMENTARIO'])
Out[28]:
TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=0.6, max_features=None, min_df=0.001,
        ngram_range=(1, 3), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents='unicode', sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)
In [29]:
vec.get_feature_names()
Out[29]:
['10',
 '100',
 '11',
 'abastec',
 'abren',
 'abrir',
 'acab',
 'academ',
 'acced',
 'acces',
 'accesibil',
 'acept',
 'acerc',
 'acondicion',
 'acord',
 'acredit',
 'acredit wasc',
 'activ',
 'actual',
 'actualiz',
 'acuerd',
 'adecu',
 'adem',
 'ademas',
 'adicional',
 'administr',
 'administracion',
 'admision',
 'adquir',
 'afect',
 'agrad',
 'agrand',
 'agreg',
 'ahi',
 'ahor',
 'air',
 'air acondicion',
 'al',
 'algui',
 'algun',
 'algun curs',
 'algun profesor',
 'almorz',
 'almuerz',
 'alt',
 'alta',
 'alta calid',
 'altas',
 'alto',
 'alto nivel',
 'altos',
 'alumn',
 'alumn aprend',
 'alumn buen',
 'alumn campus',
 'alumn deb',
 'alumn epe',
 'alumn hac',
 'alumn mal',
 'alumn mas',
 'alumn matricul',
 'alumn mejor',
 'alumn pesim',
 'alumn profesor',
 'alumn pued',
 'alumn sed',
 'alumn sol',
 'alumn univers',
 'ambient',
 'ambient estudi',
 'ambit',
 'amig',
 'ampli',
 'ampliacion',
 'ano',
 'anos',
 'anterior',
 'antigu',
 'apart',
 'apertur',
 'aplic',
 'apoy',
 'apoy alumn',
 'app',
 'aprend',
 'aprendizaj',
 'aqu',
 'are',
 'are estudi',
 'are verd',
 'arquitectur',
 'arregl',
 'ascensor',
 'asesor',
 'asesori',
 'asi',
 'asi mism',
 'asient',
 'asim',
 'asist',
 'asistent',
 'aspect',
 'atencion',
 'atencion alumn',
 'atencion alumn pesim',
 'atencion client',
 'atencion telefon',
 'atend',
 'atiend',
 'atras',
 'audiovisual',
 'aul',
 'aul virtual',
 'aument',
 'aument pension',
 'aun',
 'aun falt',
 'aunqu',
 'avanz',
 'avec',
 'avis',
 'ayud',
 'ayud alumn',
 'baj',
 'baj pension',
 'baj preci',
 'ban',
 'bas',
 'basic',
 'bastant',
 'bec',
 'benefici',
 'bibliotec',
 'bien',
 'blackboard',
 'blend',
 'blend curs',
 'bolet',
 'bols',
 'bols trabaj',
 'bonit',
 'break',
 'brind',
 'brind alumn',
 'brind buen',
 'brind servici',
 'brind univers',
 'buen',
 'buen ambient',
 'buen atencion',
 'buen calid',
 'buen docent',
 'buen educ',
 'buen ensen',
 'buen infraestructur',
 'buen infraestructur buen',
 'buen metodolog',
 'buen nivel',
 'buen plan',
 'buen plan docent',
 'buen prof',
 'buen profesional',
 'buen profesor',
 'buen profesor buen',
 'buen servici',
 'buen sistem',
 'buen univers',
 'bus',
 'busc',
 'cad',
 'cad ano',
 'cad carrer',
 'cad cicl',
 'cad curs',
 'cad dia',
 'cad rat',
 'cad vez',
 'cafet',
 'cafeteri',
 'cafetin',
 'calcul',
 'calid',
 'calid docent',
 'calid educ',
 'calid ensen',
 'calid ensen buen',
 'calid ensen profesor',
 'calid profesor',
 'calid servici',
 'calif',
 'calific',
 'cambi',
 'cambi horari',
 'cambi mall',
 'cambi mall curricul',
 'cambi sed',
 'camin',
 'camp',
 'campus',
 'campus monterr',
 'campus san',
 'canal',
 'cantid',
 'cantid alumn',
 'caos',
 'capac',
 'capacit',
 'car',
 'carg',
 'carnet',
 'carpet',
 'carrer',
 'cas',
 'casi',
 'casiller',
 'caus',
 'centr',
 'centr atencion',
 'centr atencion alumn',
 'centr inform',
 'cerc',
 'cercan',
 'cerr',
 'charl',
 'chever',
 'chic',
 'cicl',
 'cienci',
 'cierr',
 'ciert',
 'civil',
 'clar',
 'clas',
 'clas blend',
 'clas deb',
 'clas dinam',
 'clas presencial',
 'clas profesor',
 'clas virtual',
 'client',
 'cobr',
 'col',
 'colaps',
 'colegi',
 'coloc',
 'com',
 'comedor',
 'comod',
 'companer',
 'compar',
 'competent',
 'competit',
 'complej',
 'complet',
 'complic',
 'compr',
 'comprend',
 'compromis',
 'comput',
 'comun',
 'comunic',
 'comunicacion',
 'con',
 'conect',
 'conexion',
 'conform',
 'conoc',
 'consegu',
 'consider',
 'constant',
 'consult',
 'cont',
 'contabil',
 'contact',
 'contact web',
 'conten',
 'conten curs',
 'contest',
 'continu',
 'contrasen',
 'contrat',
 'control',
 'convalid',
 'conveni',
 'conveni internacional',
 'conveni univers',
 'coordin',
 'corre',
 'correct',
 'cort',
 'cos',
 'cost',
 'cost pension',
 'costos',
 'cre',
 'cre deb',
 'creativ',
 'crec',
 'credit',
 'cruz',
 'cual',
 'cualqu',
 'cualqui',
 'cuand',
 'cuant',
 'cubicul',
 'cuelg',
 'cuent',
 'cuent buen',
 'cuest',
 'cultural',
 'cumpl',
 'curricul',
 'curs',
 'curs blend',
 'curs carrer',
 'curs deb',
 'curs deb ser',
 'curs ingles',
 'curs llev',
 'curs matemat',
 'curs numer',
 'curs profesor',
 'da',
 'dad',
 'dan',
 'dan facil',
 'dan solucion',
 'dar',
 'dar mas',
 'darl',
 'de',
 'deb',
 'deb ampli',
 'deb dar',
 'deb dej',
 'deb exist',
 'deb hab',
 'deb hab mas',
 'deb hac',
 'deb implement',
 'deb mejor',
 'deb mejor atencion',
 'deb pon',
 'deb ser',
 'deb ser mas',
 'deb ser presencial',
 'deb sub',
 'deb ten',
 'deb trabaj',
 'deberi',
 'deberi hab',
 'deberi hab mas',
 'deberi mejor',
 'deberi ser',
 'deberi ser mas',
 'deberi ten',
 'dec',
 'dedic',
 'deficient',
 'definit',
 'dej',
 'dej des',
 'del',
 'demand',
 'demas',
 'demasi',
 'demasi alumn',
 'demasi gent',
 'demasi lent',
 'demor',
 'den',
 'dentr',
 'dentr univers',
 'depend',
 'deport',
 'derech',
 'des',
 'desarroll',
 'desastr',
 'descans',
 'descuent',
 'desd',
 'desempen',
 'desorden',
 'desorganiz',
 'despues',
 'detall',
 'dia',
 'dia dia',
 'dias',
 'dic',
 'dict',
 'dict clas',
 'didact',
 'diferent',
 'dificil',
 'dificult',
 'dinam',
 'diner',
 'direct',
 'disen',
 'disminu',
 'dispon',
 'disponibil',
 'disponibil horari',
 'disposicion',
 'distint',
 'distribu',
 'divers',
 'docenci',
 'docent',
 'docent infraestructur',
 'doming',
 'dos',
 'dud',
 'econom',
 'educ',
 'educ brind',
 'educ buen',
 'educacion',
 'efect',
 'eficient',
 'egres',
 'ejempl',
 'ejercici',
 'el',
 'el ambient',
 'el aul',
 'el cambi',
 'el campus',
 'el horari',
 'el internet',
 'el metod',
 'el metod ensen',
 'el nivel',
 'el nivel ensen',
 'el nivel exigent',
 'el orden',
 'el prestigi',
 'el proces',
 'el servici',
 'el servici atencion',
 'el sistem',
 'el trat',
 'el uso',
 'el wifi',
 'eleccion',
 'eleg',
 'elev',
 'elimin',
 'ello',
 'embarg',
 'empez',
 'emple',
 'empres',
 'en',
 'en aspect',
 'en atencion',
 'en atencion alumn',
 'en curs',
 'en horari',
 'en matricul',
 'en proces',
 'en servici',
 'en sistem',
 'encant',
 'encarg',
 'enchuf',
 'encim',
 'encontr',
 'encuentr',
 'encuest',
 'enfoc',
 'ensen',
 'ensen bien',
 'ensen brind',
 'ensen buen',
 'ensen calid',
 'ensen curs',
 'ensen exigent',
 'ensen infraestructur',
 'ensen profesor',
 'ensen univers',
 'entend',
 'entiend',
 'entrad',
 'entrar',
 'entreg',
 'envi',
 'epe',
 'equip',
 'error',
 'es',
 'es buen',
 'es buen univers',
 'es univers',
 'escog',
 'escuch',
 'esfuerz',
 'eso',
 'espaci',
 'espaci alumn',
 'espaci deport',
 'espaci descans',
 'espaci estudi',
 'espaci pod',
 'esparc',
 'especial',
 'especializ',
 'especif',
 'esper',
 'esta',
 'establec',
 'estacion',
 'estadist',
 'estan',
 'estoy',
 'estructur',
 'estudi',
 'estudi buen',
 'estudi epe',
 'estudi univers',
 'estudiantil',
 'etc',
 'evalu',
 'event',
 'evit',
 'exam',
 'exam admision',
 'examen',
 'excelent',
 'excelent academ',
 'excelent profesor',
 'exces',
 'exig',
 'exigent',
 'exigent academ',
 'exigent buen',
 'exigent curs',
 'exigent profesor',
 'exist',
 'exit',
 'expect',
 'experient',
 'experient profesor',
 'experient univers',
 'explic',
 'explic bien',
 'extra',
 'extranjer',
 'facil',
 'facil brind',
 'facil dan',
 'facil estudi',
 'facil horari',
 'facil pag',
 'facilit',
 'facult',
 'fall',
 'falt',
 'falt espaci',
 'falt mas',
 'falt mejor',
 'famili',
 'favor',
 'fech',
 'filtr',
 'fin',
 'fin seman',
 'final',
 'fisic',
 'flexibil',
 'flexibil horari',
 'flexibl',
 'foment',
 'form',
 'form ensen',
 'formacion',
 'funcion',
 'futur',
 'gan',
 'gast',
 'gener',
 'general',
 'genial',
 'gent',
 'gent trabaj',
 'gestion',
 'gimnasi',
 'graci',
 'grad',
 'gran',
 'gran cantid',
 'grand',
 'gratis',
 'gratuit',
 'grup',
 'grupal',
 'guard',
 'gust',
 'gust univers',
 'gustari',
 'hab',
 'hab mas',
 'habil',
 'habilit',
 'habl',
 'hac',
 'hac clas',
 'hac trabaj',
 'haci',
 'haci alumn',
 'hag',
 'hast',
 'hay',
 'hay curs',
 'hay demasi',
 'hay much',
 'hay much gent',
 'hay profesor',
 'hech',
 'herramient',
 'higien',
 'hor',
 'hor almuerz',
 'hor clas',
 'hor punt',
 'horari',
 'horari bus',
 'horari clas',
 'horari curs',
 'horari deb',
 'horari flexibl',
 'horari sed',
 'horribl',
 'human',
 'ide',
 'igual',
 'imag',
 'implement',
 'implement mas',
 'import',
 'impos',
 'impresion',
 'inclu',
 'inclus',
 'incomod',
 'inconvenient',
 'increment',
 'indic',
 'ineficient',
 'inform',
 'informacion',
 'infraestructur',
 'infraestructur buen',
 'infraestructur calid',
 'infraestructur profesor',
 'infraestructur univers',
 'ing',
 'ingeni',
 'ingenieri',
 'ingles',
 'ingles deb',
 'ingres',
 'ingres univers',
 'inici',
 'inmediat',
 'innov',
 'innovacion',
 'instal',
 'institu',
 'insuficient',
 'integr',
 'interaccion',
 'intercambi',
 'interes',
 'intern',
 'internacional',
 'internet',
 'internet lent',
 'intranet',
 'investig',
 'ipad',
 'ipads',
 'ir',
 'isidr',
 'it',
 'junt',
 'just',
 'la',
 'la atencion',
 'la atencion alumn',
 'la bibliotec',
 'la buen',
 'la buen ensen',
 'la calid',
 'la calid docent',
 'la calid educ',
 'la calid ensen',
 'la calid profesor',
 'la comod',
 'la educ',
 'la ensen',
 'la ensen buen',
 'la ensen profesor',
 'la exigent',
 'la exigent profesor',
 'la experient',
 'la facil',
 'la flexibil',
 'la form',
 'la form ensen',
 'la infraestructur',
 'la innov',
 'la mall',
 'la matricul',
 'la mensual',
 'la metodolog',
 'la metodolog ensen',
 'la organiz',
 'la pension',
 'la pension sub',
 'la tecnolog',
 'la tecnologi',
 'la univers',
 'la univers buen',
 'labor',
 'laboral',
 'laboratori',
 'lad',
 'larg',
 'las',
 'las clas',
 'las facil',
 'las instal',
 'las oportun',
 'las pension',
 'le',
 'lectur',
 'leer',
 'lej',
 'lent',
 'libr',
 'libr bibliotec',
 'lim',
 'limit',
 'limpi',
 'limpiez',
 'limpiez ban',
 'lin',
 'line',
 'llam',
 'lleg',
 'lleg tard',
 'llen',
 'llev',
 'llev curs',
 'lo',
 'lo mas',
 'lo mas valor',
 'lo valor',
 'local',
 'logr',
 'los',
 'los buen',
 'los buen profesor',
 'los conveni',
 'los curs',
 'los curs blend',
 'los docent',
 'los horari',
 'los profesor',
 'los profesor buen',
 'los servici',
 'los taller',
 'lucr',
 'lueg',
 'lug',
 'lugar',
 'lugar estudi',
 'mac',
 'macs',
 'maestr',
 'mal',
 'mal atencion',
 'mal atencion alumn',
 'mal servici',
 'malisim',
 'mall',
 'mall curricul',
 'man',
 'manan',
 'mand',
 'manej',
 'maner',
 'manten',
 'maquet',
 'maquin',
 'mas',
 'mas alumn',
 'mas are',
 'mas cubicul',
 'mas curs',
 'mas espaci',
 'mas espaci estudi',
 'mas exigent',
 'mas facil',
 'mas grand',
 'mas hor',
 'mas horari',
 'mas libr',
 'mas lugar',
 'mas rap',
 'mas salon',
 'mas taller',
 'mas valor',
 'mat',
 'matemat',
 'materi',
 'material',
 'matricul',
 'matricul curs',
 'matricul line',
 'maxim',
 'mayor',
 'mayor cantid',
 'mayor espaci',
 'mayor profesor',
 'mayori',
 'me',
 'me encant',
 'me gust',
 'me parec',
 'me parec buen',
 'medi',
 'mediant',
 'medicin',
 'mejor',
 'mejor aspect',
 'mejor atencion',
 'mejor atencion alumn',
 'mejor aul',
 'mejor calid',
 'mejor horari',
 'mejor infraestructur',
 'mejor internet',
 'mejor matricul',
 'mejor organiz',
 'mejor proces',
 'mejor proces matricul',
 'mejor profesor',
 'mejor servici',
 'mejor servici atencion',
 'mejor sistem',
 'mejor tem',
 'mejor univers',
 'mejor wifi',
 'men',
 'menor',
 'mensual',
 'menu',
 'merc',
 'mes',
 'met',
 'metod',
 'metod ensen',
 'metodolog',
 'metodolog ensen',
 'metodologi',
 'metodologi ensen',
 'mi',
 'miguel',
 'minim',
 'minut',
 'mism',
 'mo',
 'mod',
 'modal',
 'modal blend',
 'modern',
 'modul',
 'molest',
 'moment',
 'moment matricul',
 'mont',
 'monterr',
 'motiv',
 'movil',
 'much',
 'much alumn',
 'much cos',
 'much facil',
 'much gent',
 'much oportun',
 'much person',
 'much vec',
 'music',
 'muy',
 'muy buen',
 'muy car',
 'nadi',
 'neces',
 'necesari',
 'necesit',
 'necesit mas',
 'negoci',
 'ningun',
 'nivel',
 'nivel academ',
 'nivel educ',
 'nivel ensen',
 'nivel exigent',
 'no',
 'no deb',
 'no gust',
 'no sub',
 'no suficient',
 'noch',
 'normal',
 'nos',
 'not',
 'nuev',
 'numer',
 'nunc',
 'nunc contest',
 'objet',
 'oblig',
 'obten',
 'ocasion',
 'ocup',
 'ofrec',
 'ofrec univers',
 'onlin',
 'opcion',
 'opinion',
 'oportun',
 'oportun laboral',
 'optim',
 'orden',
 'organiz',
 'organizacion',
 'orient',
 'otorg',
 'pabellon',
 'pacienci',
 'pag',
 'pag pension',
 'pagin',
 'pais',
 'par',
 'parec',
 'parec buen',
 'parec buen univers',
 'parec univers',
 'part',
 'particip',
 'pas',
 'ped',
 'pens',
 'pension',
 'pension alta',
 'pension cad',
 'pension cad ano',
 'pension cad cicl',
 'pension car',
 'pension deb',
 'pension sub',
 'pension sub cad',
 'peor',
 'pequen',
 'per',
 'perd',
 'perfect',
 'perjud',
 'perjudic',
 'permit',
 'person',
 'person trabaj',
 'personal',
 'personaliz',
 'peru',
 'pes',
 'pesim',
 'pesim atencion',
 'pid',
 'piens',
 'pierd',
 'pis',
 'piscin',
 'plan',
 'plan docent',
 'plat',
 'plataform',
 'plataform virtual',
 'pm',
 'poblacion',
 'poc',
 'poc espaci',
 'pod',
 ...]
In [30]:
x_train_tokens = vec.transform(x_train['COMENTARIO'])
In [31]:
x_test_tokens = vec.transform(x_test['COMENTARIO'])

Stacking together tokens and categorical features

In [32]:
full_x_train = hstack((x_train[model_cols].as_matrix(),x_train_tokens))
full_x_test = hstack((x_test[model_cols].as_matrix(),x_test_tokens))

Voting Classifier

In [33]:
clf_log2 = LogisticRegression(C= 1, class_weight= None, solver= 'newton-cg', random_state=1)
clf_xgb = XGBClassifier( objective='multi:softprob', scale_pos_weight=1, 
                        max_depth= 9,gamma=0.3, colsample_bytree= 0.9, subsample= 0.8,seed=27)
clf_nb2 = OneVsRestClassifier(MultinomialNB())
In [36]:
clf_voting = VotingClassifier(estimators=[('lr',clf_log2),('xgb', clf_xgb),('nb',clf_nb2)], voting='soft')
In [37]:
clf_voting.fit(full_x_train,y_train)
Out[37]:
VotingClassifier(estimators=[('lr', LogisticRegression(C=1, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=1, solver='newton-cg', tol=0.0001,
          verbose=0, warm_start=False)), ('xgb', XGBClassifi...assifier(estimator=MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True),
          n_jobs=1))],
         n_jobs=1, voting='soft', weights=None)
In [39]:
predict_clf_voting = clf_voting.predict(full_x_test)
In [42]:
print('accuracy: %s'  % accuracy_score(predict_clf_voting,y_test))
print('log_loss: %s'  % log_loss(y_test, clf_voting.predict_proba(full_x_test)))
accuracy: 0.7145
log_loss: 0.735936697571

Results for submission

In [43]:
x_final_tokens = vec.transform(X_final['COMENTARIO'])
In [44]:
final_x_test = hstack((X_final[model_cols].as_matrix(),x_final_tokens))
In [45]:
final_predict = clf_voting.predict_proba(final_x_test)
In [46]:
final_cod = all_data.loc[20000:,'COD_ENCUESTADO'].copy().reset_index(drop=True)
In [47]:
final_predict_df = pd.concat([final_cod,pd.DataFrame(final_predict,columns = ['NPS1','NPS2','NPS3','NPS4'])],axis=1)
In [49]:
final_predict_df.to_csv('submission.csv',index=False)