Baixo Indice de acerto Consistentemente

Olá pessoal, alguem aqui submeteu resposta para esse desafio nos ultimos 30 dias? Só queria tirar esta dúvida, pois das respostas que submeti, não consegui nem 1% de acerto, e não sei se é simplesmente problemas com minha submissões ou o desafio possui algum problema no geral.

Abraço.

1 Curtida

Boa Tarde…nao fiz o teste ainda…estou iniciando hoje…quando fizer o teste te falo. Abraco

2 Curtidas

Olá Wesley vamos movimentar seu post, porque também parei na mesma situação, aqui conseguimos no máximo 26%.
Testamos até mesmo Keras, mas o treinamento parece que vicia num determinado momento.
Acredito que o problema esteja na estratégia da Regressão com múltiplas features (quais selecionar).
Se alguém tiver uma dica.

2 Curtidas

@tiagoz já usou o modelo.feature_importances_ dos algoritmos ensemble, como o Random Forest?

Ele te diz quais features foram as mais significativas para fazer a previsão.

Outra dica é separar as features quantitativas e dar um df.corr() para ver a correlação entre elas.

1 Curtida

Olá @wesleyjr0101 tudo bem?

alguem aqui submeteu resposta para esse desafio nos ultimos 30 dias

Submeti a 15 dias e consegui um acerto acima de 30% ainda é bem baixo, mas acredito que eu possa melhorar a minha submissão. Quais algoritmos e informações você está utilizando na sua submissão?

Você já tentou uma abordagem com cadeias de Markov?

Podem postar o código que não tem dado certo?

Talvez alguns possam ajudar e ver o que está dando errado. Eu consegui um índice de acertos legal, mas antes disso passei um tempo me perguntando o que estava dando de errado quando um erro trivial estava trocando colunas.

Outra alternativa pode ser pedir ajuda com o código no StackOverflow em Português. Eu também fico de olho nas perguntas por lá e ajudo quando posso (:

1 Curtida

Bom dia, tudo certo? Só não postei nenhum código antes porque não sabia se podia, mas vamos lá. Na abordagem deste código que vou postar, eu primeiramente filtrei as features do dataset de treinamento(train.csv) para que tivessem as mesmas do dataset de (teste.csv). Em seguida, na parte de "limpagem dos dados" eu dei merge verticalmente nos dois datasets, ai então eu removi as features que tinham mais de 50% dos falores faltando(NaN), e das features com NaNs que sobraram, as numéricas fiz imputation pela Média de cada feature, e das Categóricas imputei pela Mediana. Por fim, separei de volta em dataset de treinamento e teste.
Num ultimo passo de pre-processamento, eu utilizei a correlação de Pearson entre as features e o target para selecionar as features que pusuiam pelomenos 10% de correlação(Positivamente ou Negativamente), e depois dividi o dataframe de treinamento numa proporcao de 70:30 em (X_train,y_train):(X_test,y_test).
Por fim, utilizei a tecnica de regressao Lasso treinando sobre o dataset de treinamento (X_train,y_train), avaliei o modelo sobre o dataset (X_test,y_test), e enviei a resposta da predicao do modelo sobre o dataset novo, que chamei de X_pred.
Ainda vale notar que tentei varias outras formas de tratar os dados faltantes do problema(NaNs), como marcar todos os faltantes como zero(.fillna(0))! Por isso eu acredito que algum erro muito grosseiro estou cometento e não consigo enchergar, vou anexar abaixo o codigo compilando para vocês verem e alguem me da uma dica baita xD:enem_env

from __future__ import print_function
import numpy as np
import pandas as pd
from sklearn import preprocessing
#invite people for the Kaggle party
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
import warnings
#warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split,GridSearchCV,KFold
from sklearn.preprocessing import Imputer
import math
from sklearn.cross_validation import StratifiedKFold
from sklearn.utils import shuffle
from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV, ElasticNetCV, ElasticNet



df_train = pd.read_csv(r"C:\Users\Wesley\codenation\enem-2\train.csv", header=0)
df_pred = pd.read_csv(r"C:\Users\Wesley\codenation\enem-2\test.csv", header=0)
copy_df_train = df_train.copy()
copy_df_pred = df_pred.copy()


#### Root Mean Square Logarithmic Error ###
def logRMSE(y_test, y_pred) : 
    assert len(y_test) == len(y_pred)
    return np.sqrt(np.mean((np.log(1+y_pred) - np.log(1+y_test))**2))

############################################## DATASET INFORMATION ########################################################
# Take a look at the data
print('Training Dataset: \n',df_train.head(5))
print('Test Dataset: \n',df_pred.head(5))
print('Test Dataset Features: \n',df_pred.columns)

target = 'NU_NOTA_MT'
identifier = 'NU_INSCRICAO'
plot = 0
tam_test = 0.3
feature_transform = 0
Norm_Features = 1 #Normalizacao das Features de X_train antes do treinamento, e de X_test e X_pred com a normalizacao de X_train para predicoes
#X_train = dataset de treinamento
#X_teste = dataset de teste do treinamento
#X_pred = dataset de novas previsoes que serao a resposta a ser enviada para o desafio
############################################## DATASET INFORMATION ########################################################


############################################## PERGUNTAS IMPORTANTES ########################################################
print('\n Does the train dataset and prediction dataset have the same features?:',set(df_train.drop(target,1)) == set(df_pred))
############################################## PERGUNTAS IMPORTANTES ########################################################




############################################## EQUALIZAR FEATURES ###########################################################
targets = df_train[target]
df_train = df_train[df_pred.columns]
df_train[target] = targets
############################################## EQUALIZAR FEATURES ###########################################################

#sns.distplot(np.log(df_train['NU_NOTA_MT']))
#### nao treina com elementos nulos ###
df_train = df_train[~df_train['NU_NOTA_MT'].isnull()]
#df_train = df_train[df_train['NU_NOTA_MT']!=0]
#### nao treina com elementos nulos ###

### FEATURE TRANSFORM - LOG1 of SalePrice ###
if feature_transform:
    df_train[target] = np.log1p(df_train[target])


################################### DEALING WITH MISSING DATA  - IMPUTING AND DUMMIES #######################################
train_Id = df_train[identifier]
pred_Id = df_pred[identifier]
train_target = df_train[target]

### Merge Train and Prediction Dataset into df_merge. Drop 'Id' and 'SalePrice' columns before merge
df_merge = pd.concat([df_train.drop([target,identifier],1),df_pred.drop(identifier,1)],axis=0)


###Eliminar as colunas com mais de 50% de Missing Data###
total = df_merge.isnull().sum().sort_values(ascending=False)
percent = (df_merge.isnull().sum()/df_merge.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
df_merge = df_merge.drop((missing_data[missing_data['Percent'] > 0.5]).index,1) #Deleta as Colunas com mais de Metade dos dados Faltando
total = df_merge.isnull().sum().sort_values(ascending=False)
percent = (df_merge.isnull().sum()/df_merge.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
missing_data.head(50)
###Eliminar as colunas com mais de 50% de Missing Data###

#### Divisao entre Features Quantitativas e QUalitativas ####
qualitative_features = [f for f in df_merge.dropna().columns if df_merge.dropna().dtypes[f] == 'object'] #Lista de Features Qualitativas.
quantitative_features = [f for f in df_merge.dropna().columns if df_merge.dropna().dtypes[f] != 'object'] #Lista de Features Qualitativas.
#### Divisao entre Features Quantitativas e QUalitativas ####

############# NUMERIC FEATURES #############
print('\nIs there any NaN value of numeric features in the dataset before Imputing?:',df_merge[quantitative_features].isnull().sum().any())
df_merge[quantitative_features].isnull().sum().sort_values(ascending=False)
#df_merge.drop('IN_CEGUEIRA', axis=1, inplace=True)
#df_merge['TP_DEPENDENCIA_ADM_ESC'] = df_merge['TP_DEPENDENCIA_ADM_ESC'].fillna(0)
#df_merge['TP_ENSINO'] = df_merge['TP_ENSINO'].fillna(0)
#df_merge['TP_STATUS_REDACAO'] = df_merge['TP_STATUS_REDACAO'].fillna(4)
#df_merge['NU_NOTA_REDACAO'] = df_merge['NU_NOTA_REDACAO'].fillna(0)
#df_merge['NU_NOTA_COMP4'] = df_merge['NU_NOTA_COMP4'].fillna(0)
#df_merge['NU_NOTA_COMP3'] = df_merge['NU_NOTA_COMP3'].fillna(0)
#df_merge['NU_NOTA_COMP2'] = df_merge['NU_NOTA_COMP2'].fillna(0)
#df_merge['NU_NOTA_COMP1'] = df_merge['NU_NOTA_COMP1'].fillna(0)
#df_merge['NU_NOTA_COMP5'] = df_merge['NU_NOTA_COMP5'].fillna(0)
#df_merge['NU_NOTA_LC'] = df_merge['NU_NOTA_LC'].fillna(0)
#df_merge['NU_NOTA_CH'] = df_merge['NU_NOTA_CH'].fillna(0)
#df_merge['NU_NOTA_CN'] = df_merge['NU_NOTA_CN'].fillna(0)
for i in quantitative_features:
    df_merge[i] = df_merge[i].fillna(df_merge[i].mean())
    
## Normalization of Numeric Features ###
df_merge[quantitative_features] = (df_merge[quantitative_features]-df_merge[quantitative_features].min())/(
        df_merge[quantitative_features].max()-df_merge[quantitative_features].min())
## Normalization of Numeric Features ###
df_merge.drop('IN_CEGUEIRA', axis=1, inplace=True)
quantitative_features = [f for f in df_merge.dropna().columns if df_merge.dropna().dtypes[f] != 'object'] #Lista de Features Qualitativas.
print('\nIs there any NaN value of numeric features in the dataset after Imputing?:',df_merge[quantitative_features].isnull().sum().any())
############# NUMERIC FEATURES #############


############# NON-NUMERIC FEATURES #############
print('\nIs there any NaN value of numeric features in the dataset before Imputing?:',df_merge[qualitative_features].isnull().sum().any())
df_merge.isnull().sum().sort_values(ascending=False)
#df_merge['Q027'] = df_merge['Q027'].fillna('None')

qualitative_features = [f for f in df_merge.dropna().columns if df_merge.dropna().dtypes[f] == 'object'] #Lista de Features Qualitativas.
quantitative_features = [f for f in df_merge.dropna().columns if df_merge.dropna().dtypes[f] != 'object'] #Lista de Features Qualitativas.


print('\nIs there any NaN value  in the dataset after Imputing and get_dummies?:',df_merge.isnull().sum().any())
############# NON-NUMERIC FEATURES #############


### Labeling of Categorical Variables With Dummies
df_merge = pd.get_dummies(data=df_merge, columns=qualitative_features)


### Restore datraframes df_train and df_pred
df_train = df_merge[:len(df_train)]
df_train[target] = train_target
df_train[target].fillna(0,inplace=True)
df_pred = df_merge[len(df_train):]
################################### DEALING WITH MISSING DATA  - IMPUTING AND DUMMIES #######################################



################################################## CORRELACAO ENTRE FEATURES ###################################################          
### A variavel melhores_features vai receber as features que melhor se correlacionam com 'NU_NOTA_MT' ###
corrmat = df_train.corr()
melhores_features = corrmat[target].sort_values(ascending=False)
melhores_features = melhores_features[(melhores_features>0.1) | (melhores_features<-0.1)]
melhores_features = melhores_features.index
df_train = df_train[melhores_features]
df_pred = df_pred[melhores_features.drop(target)]
### A variavel melhores_features vai receber as features que melhor se correlacionam com 'NU_NOTA_MT' ###
################################################## CORRELACAO ENTRE FEATURES ###################################################



#################################### Division between X_train,X_test,y_train,y_test #########################################
df_train = shuffle(df_train) #shuffle data before division
train_target = df_train[target] # Just for code readibility
predictors = df_train.drop([target], axis=1)
X_train, X_test, y_train, y_test = train_test_split(predictors, 
                                                    train_target,
                                                    train_size=1-tam_test, 
                                                    test_size=tam_test, 
                                                    random_state=0)
X_pred = df_pred
#################################### Division between X_train,X_test,y_train,y_test #########################################




######################################################### LASSO ##########################################################
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import RobustScaler

lasso = make_pipeline(RobustScaler(),LassoCV(alphas = [0.0001, 0.0003, 0.0006, 0.001, 0.003, 0.006, 0.01, 0.03, 0.06, 0.1, 
                          0.3, 0.6, 1, 3, 6, 10, 30, 60, 100], 
                max_iter = 50000, cv = 10))

lasso.fit(X_train, y_train)

y_train_las = lasso.predict(X_train)
y_test_las = lasso.predict(X_test)
las_prediction = lasso.predict(X_pred)
###################################################### LASSO #############################################################


######################################### Results Compilation and Plots ################################################# 
df_resultado_treinamento = pd.DataFrame(
        {'x_train':list(X_train.values),
         'y_train':list(y_train),
         'y_train_lasso':y_train_las,
                })
    
df_resultado_val = pd.DataFrame(
        {'x_val':list(X_test.values),
         'y_val':list(y_test),  
         'y_test_lasso':y_test_las,
                })
    

plt.figure(1)
df_resultado_treinamento = df_resultado_treinamento.sort_values('y_train',ascending=1)
plt.plot(list(df_resultado_treinamento['y_train']),'r-.',label='y_train')
plt.plot(list(df_resultado_treinamento['y_train_lasso']),'g-.',label='LassoTrain')
plt.legend()


plt.figure(2)
df_resultado_val = df_resultado_val.sort_values('y_val',ascending=1)
plt.plot(list(df_resultado_val['y_val']),'r-.',label='y_test')
plt.plot(list(df_resultado_val['y_test_lasso']),'g-.',label='LassoTest')
plt.legend()
plt.show()


## Avaliacao do modelo
print("\nLasso logRMSE on Training set :", logRMSE(y_train,y_train_las))


print("\nLasso logRMSE on Test set :", logRMSE(y_test,y_test_las))
######################################### Results Compilation and Plots #################################################  


######################################### Escreve .csv com resultados ##################################################
df_saida = pd.DataFrame(
        {identifier:pred_Id,
        target: las_prediction
                })
df_saida.to_csv(r'C:\Users\Wesley\codenation\enem-2/answer.csv',index=False)
######################################### Escreve .csv com resultados ##################################################

Galera, o Octávio Santana mandou uma sugestão. Ele teve problemas com o cadastro no forum, então estou repassando a contribuição dele:

Eu acho que o pessoal não está pensando no problema em si, e apenas aplicando os modelos de ML, tem até gente usando Keras, não precisa disso para está problema. Te explico, no último comentário do rapaz wesleyjr0101, uma parte dela ele diz:

Em seguida, na parte de "limpagem dos dados" eu dei merge verticalmente nos dois datasets, ai então eu removi as features que tinham mais de 50% dos falores faltando(NaN), e das features com NaNs que sobraram, as numéricas fiz imputation pela Média de cada feature, e das Categóricas imputei pela Mediana.

Veja que a variavel que ele quer prever é a nota de matematica, mas neste caso tem muitas linhas nesta variavel que está como NaN, e o que isso significa? O cara não fez a prova, então o modelo tem que entender que ele não fez a prova. Quando ele substitui os valores faltando desta feature, ele está dizendo que o cara que não fez a prova, fez a prova e que sua nota é a média no geral, mas isso não é verdade. Minha sugestão, substitua os valores faltantes de forma que o modelo entenda que aquele predict refere-se ao cara que não fez a prova e submeta None.

Até mais,

Octávio Santana

1 Curtida

Muito obrigado pelo conselho, se eu obter alguma melhora neste sentido eu posto aqui. Essa parte de lidar com os dados faltantes que representam as pessoas que não foram me deixaram pensativo, se não me engano o tipo ‘None’ é interpretado como object em python, não? Se for interpretado como object não sei se seria uma boa ideia misturar int e object na mesma feature(https://github.com/pandas-dev/pandas/issues/10871). Cheguei a tentar substitutir os NaNs por int(0), mas nao sei se essa era uma boa interpretacao para as pessoas que nao foram fazer a prova, e o modelo nao melhorou a performance de qualquer forma.

Então, existe a possíbilidade de alguém ter zerado a prova, então você está misturando quem não foi e quem zerou a prova no modelo.

Vou te da uma dica:
A prova de matematica é feito junto com outra materia, certo? Então você já tem a resposta tando no dado de treino e de teste de quem não foi fazer a prova.

Espero que tenha ajudado,
Octávio Santana

1 Curtida

Bom dia pessoal.

Eu submeti em junho/julho, faz mais de 30 dias. Consegui um resultado bem legal, 90%. Ainda da pra melhorar… não tenho muita experiência na área.

Usei apenas a regressão linear do sklearn e tratei os NaNs como o pessoal tem falado. O pulo do gato ta nisso aí.

Olá Octavio, tudo bem?

Como você identificou quando o aluno não compareceu. Você alterou os dados para -1, ou criou um coluna identificando a presença?

Oi @tiagoz, estou bem e você?

Não sei se pelo tempo da pergunta você já deve ter tido alguma ideia sobre, mas de qualquer modo vou responder.

Num comentário anterior eu mencionei que

A prova de matematica é feito junto com outra materia, certo? Então você já tem a resposta tando no dado de treino e de teste de quem não foi fazer a prova.

É só identificar com a base de treino qual é a matéria que quando a a nota de matemática é nula a mesma também é, ou então, da uma procurada na internet.

Feito isso é apenas filtrar essas linhas nulas referente a esta matéria tanto na base de treino para treinar o seu modelo, enquanto na base de teste, essas linhas nulas já identifica qual é a nota daquela pessoa em matemática.

Espero ter ajudado,
Octávio Santana

Obrigado @Octavio_Santana.

Então, identificamos e utilizamos um valor negativo, conforme vocês talvez o baixo índice seria porque considerava faltantes como zerados.
Mesmo assim e ajustando umas features não chegamos ao percentual da maioria, acabaram as ideias :smile: slight_smile:

Oi @tiagoz,

O pessoal da codenation abriu uma opção de codereview, se quizer eu posso ver o que vocês estão fazendo a ajudar em algo se eu souber.

O que eu fiz foi justamente filtrar as linhas (tanto na base de treino e teste), pois eu já sei a resposta para as linhas faltantes referente a materia que é feito junto com matematica. Após o modelo treinado, eu fiz um iterador e se aquela outra matéria está com none, a nota de matematica é none, se não use o predict do modelo. E assim eu fui preenchendo o arquivo de submissão.

Octávio Santana

Opa, tudo certo? Não entendi como que funciona o esquema do CodeReview, na aba do CodeReview está sendo pedido pra compartilhar este link https://r.codenation.com.br/u/KmmBRuAmR,onde eu posto meu código?

De qualquer forma, eu fiz um resumo da minha solução num Jupyter Notebook pra ficar mais visual e fácil de entender, vou deixar aqui o link: https://github.com/wesleyjr01/CodeNation_Enem2016/blob/master/Enem2016.ipynb

Esta solução obteve somente 6% no LeaderBoard.
Obrigado!

Algo que deve ajudar bastante é saber a métrica utilizada para calculo do score. Alguém sabe a métrica utilizada?

Nunca consegui passar de 7,99%, tratando:

  • Se é Nan na NU_NOTA_LC é Nan em MT também. E estes dados não vão para o modelo de predição.
  • Se é 0 na NU_NOTA_LC é 0 em MT também. E estes dados não vão para o modelo de predição.
    Com os dados todos populados treino o modelo com as colunas de nota de LC, CN, CH e Redação, e depois submetendo os dados de teste para realizar a predição. ( já testei com uma combinação grande de outras colunas também, o que não alterou o resultado).
    Concateno os resultados com Nan, zero e os preditos, e envio a resposta.

O estranho é que ontem consegui 7,99, hj fiz uns testes e foi para 7,36, dai submeti o mesmo arquivo de ontem (que tinha nota 7,99), porém a nota continuou com 7,36… Agora não importa o que eu faça, sempre fica na mesma nota (7,36).
Parece que tem algum problema.

1 Curtida