Topic: Analisi dati, Regressione lineare, consigli  (Letto 242 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline pull_over93

  • python unicellularis
  • *
  • Post: 11
  • Punti reputazione: 0
    • Mostra profilo
Analisi dati, Regressione lineare, consigli
« il: Aprile 26, 2018, 19:23 »
Signori e signore buongiorno, prima volta nel forum!
Sto usando Python 3.6.4 (anaconda3), come IDE jupiter notebook/ spyder3 e il tutto su windows10.

Mi sto approcciando alla programmazione per la prima volta (ho fatto qualche codice con matlab e LUA, ma pietosi). Questo è uno dei miei primi codici e lo scopo è quello di :

1 . Velocizzare le mie analisi dati (obiettivo per cui mi sono avvicinato alla programmazione) ;

2. Caricare un foglio di excel, contenente i miei dati e fare calcoli basilari;

3. Fare un po' di statistica base;

4. Plottare qualche grafico.

Questo è il mio codice :

#importo i pacchetti necessari all'analisi dati.
import scipy as sp
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#carico i dati
dati = pd.read_excel('MeltFlowIndex.xlsx')

#creo un vettore massa
massa = dati['mass']

#creo vettore tempo
tempo = dati['time']

#calcolo il Melt Flow Index
mfi = (massa*600)/tempo

#calcolo le medie
avg_11 = np.mean(mfi[0:7],0)
avg_12 = np.mean(mfi[7:15],0)
avg_13 = np.mean(mfi[15:19],0)
avg_21 = np.mean(mfi[19:24],0)
avg_22 = np.mean(mfi[24:30],0)
avg_23 = np.mean(mfi[30:36],0)
avg_31 = np.mean(mfi[36:43],0)
avg_32 = np.mean(mfi[43:49],0)
avg_33 = np.mean(mfi[49:],0)

#calcolo la deviazione standard
sd_11 = np.std(mfi[0:7],0)
sd_12 = np.std(mfi[7:15],0)
sd_13 = np.std(mfi[15:19],0)
sd_21 = np.std(mfi[19:24],0)
sd_22 = np.std(mfi[24:30],0)
sd_23 = np.std(mfi[30:36],0)
sd_31 = np.std(mfi[36:43],0)
sd_32 = np.std(mfi[43:49],0)
sd_33 = np.std(mfi[49:],0)

#esporto i miei dati in una nuova tabella
MFI Prova = pd.DataFrame({
    "Load" : ["2.16","5.00","7.06"],
    "190 °C" : [avg_11, avg_12, avg_13],
    "190_std" : [sd_11,sd_12,sd_13],
    "210 °C" : [avg_21,avg_22,avg_23],
    "210_std" : [sd_21,sd_22,sd_23],
    "230 °C" : [avg_31,avg_32,avg_33],
    "230_std" : [sd_31,sd_32,sd_33]
})

with pd.ExcelWriter('MFI Prova.xlsx') as writer:
    MFI Prova.to_excel(writer, sheet_name="MFI_results")
   
# T in K, creazione di un vettore ra=1/RT, log(MFI) e log(1/RT)
T1 = 190+273.15
T2 = 210+273.15
T3 = 230+273.15
x = np.array([1/(8.314*T1),1/(8.314*T2),1/(8.314*T3)])
just_MFI = np.array([
     [avg_11, avg_12, avg_13],   
     [avg_21,avg_22,avg_23],   
     [avg_31,avg_32,avg_33] ]
)
Activation_energy = np.log(just_MFI)
y = Activation_energy[:,0]

#Fitting dati
p1 = sp.polyfit(x,y,1)
slope,intercept,r_value,p_value,std_err = stats.linregress(x,y)
print(pow(r_value,2))


#grafico 1 prova
plt.figure(1)
plt.plot(x,y,'r.')
plt.plot(x,sp.polyval(p1,x),'b--')
plt.show()

Problemi
Quando voglio calcolarmi l'R^2 del fitting, ovvero la sezione di codice:
slope,intercept,r_value,p_value,std_err = stats.linregress(x,y)
print(pow(r_value,2))

L'IConsole mi da il seguente errore:
ValueError: all the input array dimensions except for the concatenation axis must match exactly

il problema è che :
1. Sto eseguendo,a mio parere, tutte le istruzioni/comandi riportati in questo esempio:
http://apmonitor.com/che263/index.php/Main/PythonDataRegression
2. Le array, x,y, che sto utilizzando hanno effettivamente la stessa dimensione.
Cosa sbaglio? come posso risolvere?

Risolto questo problema, vorrei capire come migliorare il mio codice e sopratutto rendere più veloce ed efficiente la mia scrittura: è possibile che per un analisi così banale venga fuori una pagina di codice? mi sembra di sparare ad una zanzara con un bazooka. C'è, quindi, un modo per scrivere meno e fare le stesse cose?
Vi ringrazio.


« Ultima modifica: Aprile 26, 2018, 20:08 da pull_over93 »

Offline pull_over93

  • python unicellularis
  • *
  • Post: 11
  • Punti reputazione: 0
    • Mostra profilo
Re:Analisi dati, Regressione lineare, consigli
« Risposta #1 il: Aprile 27, 2018, 11:02 »
risolto

Offline bebo

  • python erectus
  • ***
  • Post: 220
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Analisi dati, Regressione lineare, consigli
« Risposta #2 il: Aprile 27, 2018, 20:12 »
Ciao, benvenuto/a!

Bene che hai risolto.. ti va di spendere due righe per spiegare anche ai futuri utenti del forum qual'era il problema?

Offline pull_over93

  • python unicellularis
  • *
  • Post: 11
  • Punti reputazione: 0
    • Mostra profilo
Re:Analisi dati, Regressione lineare, consigli
« Risposta #3 il: Aprile 28, 2018, 16:13 »
Riordinando un attimo il codice, importando correttamente il pacchetto scipy ho risolto:


#importo pacchetti
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy as sp
#carico i dati
df = pd.read_excel('MeltFlowIndex_1.xlsx')

# massa
m = np.array(df.mass)
# tempo
t = np.array(df.time)
# mfi
mfi = (m*600)/t
#calcolo le medie
avg_11 = np.mean(mfi[0:7],0)
avg_12 = np.mean(mfi[7:15],0)
avg_13 = np.mean(mfi[15:19],0)
avg_21 = np.mean(mfi[19:24],0)
avg_22 = np.mean(mfi[24:30],0)
avg_23 = np.mean(mfi[30:36],0)
avg_31 = np.mean(mfi[36:43],0)
avg_32 = np.mean(mfi[43:49],0)
avg_33 = np.mean(mfi[49:53],0)
avg_PP_Profax_STG12 = np.mean(mfi[53:58],0)
avg_PP_HPS61R = np.mean(mfi[58:],0)
#calcolo la deviazione standard
sd_11 = np.std(mfi[0:7],0)
sd_12 = np.std(mfi[7:15],0)
sd_13 = np.std(mfi[15:19],0)
sd_21 = np.std(mfi[19:24],0)
sd_22 = np.std(mfi[24:30],0)
sd_23 = np.std(mfi[30:36],0)
sd_31 = np.std(mfi[36:43],0)
sd_32 = np.std(mfi[43:49],0)
sd_33 = np.std(mfi[49:53],0)
sd_PP_Profax_STG12 = np.std(mfi[53:58],0)
sd_PP_HPS61R = np.std(mfi[58:],0)

#array mfi_ccx
mfi_cc1 = np.array([avg_11,avg_21,avg_31])
mfi_cc2 = np.array([avg_12,avg_22,avg_32])
mfi_cc3 = np.array([avg_13,avg_23,avg_33])
#ln(mfi_ccx)
y1 = np.log(mfi_cc1)
y2 = np.log(mfi_cc2)
y3 = np.log(mfi_cc3)

# T in [K], creazione di un vettore x=1/RT, log(MFI) e log(1/RT)
T1 = 190+273.15
T2 = 210+273.15
T3 = 230+273.15
x = np.array([1/(8.314*T1),1/(8.314*T2),1/(8.314*T3)])

#Fitting dati
k = 1 #numero di variabili nel modello, dato che è lineare K=1
from scipy import stats
p1 = sp.polyfit(x,y1,1)
slope,intercept,r_value,p_value,std_err  = stats.linregress(x,y1)
R2_1 = pow(r_value,2)
adj_R2_1 = 1-(1-R2_1)*(len(x)-1)/((len(x)-k-1))

p2 = sp.polyfit(x,y2,1)
slope,intercept,r_value,p_value,std_err  = stats.linregress(x,y2)
R2_2 = pow(r_value,2)
adj_R2_2 = 1-(1-R2_2)*(len(x)-1)/((len(x)-k-1))

p3 = sp.polyfit(x,y3,1)
slope,intercept,r_value,p_value,std_err  = stats.linregress(x,y3)
R2_3 = pow(r_value,2)
adj_R2_3 = 1-(1-R2_3)*(len(x)-1)/((len(x)-k-1))

results = {
    'Load' : [2.16,5.00,7.06],
    '190 °C' : [avg_11, avg_12, avg_13],
    '190_std' : [sd_11,sd_12,sd_13],
    '210 °C' : [avg_21,avg_22,avg_23],
    '210_std' : [sd_21,sd_22,sd_23],
    '230 °C' : [avg_31,avg_32,avg_33],
    '230_std' : [sd_31,sd_32,sd_33]
}
mfi_results = pd.DataFrame(results)

mfi_results.set_index('Load',inplace=True)

#esporto i risultati in un altro foglio excel
with pd.ExcelWriter('MFI_calculation.xlsx') as writer:
    mfi_results.to_excel(writer, sheet_name="MFI_results")


Se qualcuno potesse comunque consigliarmi come scrivere meno righe di codice per avere lo stesso risultato , mi farebbe un favore! grazie
« Ultima modifica: Aprile 28, 2018, 16:15 da pull_over93 »

Offline bebo

  • python erectus
  • ***
  • Post: 220
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Analisi dati, Regressione lineare, consigli
« Risposta #4 il: Aprile 29, 2018, 14:43 »
Intanto un consiglio: evita nomi di variabili "muti" .. m, t, x, k ..
Tra un mese, se dovrai rimetterci mano, dovrai rileggere tutto. L'ideale e' che le variabili parlino da sole. Ad es.
# massa
m = np.array(df.mass)

Che senso ha un commento di una parola per spiegare cosa significa m ? chiamalo direttamente massa, cosi' anche a riga 1000000 quando scriverai massa saprai cos'e'. Scrivendo m dovrai controllare se era una pandas series, una matrice numpy, etc ..

Altra cosa: evita commenti inutili, evita cioe' di commentare cose che si capiscono da sole dal testo.. # importo pacchetti, #Fitting dati, oppure
# mfi
mfi = (m*600)/t

.. che senso ha??

Poi.. non so come siano organizzati i tuoi dati in input, quindi non posso capire come mai stia facendo quelle selezioni per riga per calcolare medie e std. in ogni caso potresti compattare le due cose in una funzione, dato che estrapoli medie e std dagli stessi insiemi.. una cosa tipo:
def extract_mean_std(df, start_row, end_row):
    return df[start_row, end_row].mean(), df[start_row, end_row].std()


# T in [K], creazione di un vettore x=1/RT, log(MFI) e log(1/RT)
...
x = np.array([1/(8.314*T1),1/(8.314*T2),1/(8.314*T3)])

questo pezzo ora te sai benissimo come funziona. Se pero' pensi ad un tuo collega (o te stesso) tra un paio d'anni, quando dovra' metterci mano per ampliare o fixare un bug, cosa capira'?
Inoltre evita di ripetere costanti intuilmente. Stai moltiplicando le possibilita' di sbagliare una cifra e non accorgertene per ora quando non torneranno i conti alla fine.
Inoltre, hai detto di essere su python 3, quindi tutto bene. Se fossi su python2, io metterei 1. anziche' 1, per forzare il calcolo tra float (che appunto in py3 e' di default, in py2 no).

Metti gli import tutti in cima, e' piu' facile trovarli e modificarli.

Tutta la parte di codice:
p1 = sp.polyfit(x,y1,1)
slope,intercept,r_value,p_value,std_err  = stats.linregress(x,y1)
R2_1 = pow(r_value,2)
adj_R2_1 = 1-(1-R2_1)*(len(x)-1)/((len(x)-k-1))

vedi com'e' tutta uguale, ripetitiva? https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
Trasforma il tutto in una funzione contenente la logica delle azioni, e imposta i tuoi dati di input in una struttura dati su cui iterare.

Per finire dai un'occhiata alla PEP8, la "guida sullo stile" di python. Solitamente, se rispettata, aumenta la leggibilita' del codice. In particolare mi riferisco alle spaziature.

Offline pull_over93

  • python unicellularis
  • *
  • Post: 11
  • Punti reputazione: 0
    • Mostra profilo
Re:Analisi dati, Regressione lineare, consigli
« Risposta #5 il: Aprile 29, 2018, 20:34 »
Intanto grazie mille! mi hai dato un sacco di spunti  e consigli per migliorare! grazie mille! Mi son scaricato il pdf della PEP8.
Nelle prossimi giorni provo a caricare delle prove di funzione!

GRAZIE ancora!