எளிய தமிழில் Pandas-9

Metrics

தரவுகளைப் பற்றிய புரிதலை இன்னும் நுணுக்கமாகத் துல்லியமாக அமைப்பதற்கு பல்வேறு அளவீடுகள் உதவுகின்றன. அவைகளின் பட்டியலை இப்பகுதியில் காணலாம். பொதுவாக இதுபோன்ற அளவீடுகளைக் கணக்கிடுவதற்கு இந்த உதாரணம் பொருத்தமாக இருக்காது. ஆனாலும் முதலில் இதை வைத்துப் புரிந்து கொண்டால், பின்னர் பெரிய அளவிலான தரவுகளை கையாளும் போது சுலபமாக இருக்கும் என்பதற்காக அதே உதாரணத்தை நான் பயன்படுத்தியுள்ளேன்.


import pandas as pd
import numpy as np
l2 = [[90,83,67,83,45],[68,89,75,56,73],[58,88,60,90,100]]
df = pd.DataFrame(l2,columns=['Tamil','English','Maths','Science','Social'],index=['Ramesh','Suresh','Kamesh'],dtype='int32')
print (df)
print (df.pct_change())
print (df['Tamil'].cov(df['English']))
print (df.cov())
print (df.corr())
print (df.rank())
print (df.rolling(window=3).mean())
print (df.rolling(window=3,min_periods=2).mean())
print (df.rolling(window=3,min_periods=2).aggregate([np.sum,np.mean]))
print (df.rolling(window=2).sum())
print (df.expanding(min_periods=2).sum())
print (df.ewm(com=0.5).mean())

முதலில் ஒரு டேட்டாஃப்பிரேமை உருவாக்கிக் கொள்வோம்.

l2 = [[90,83,67,83,45],[68,89,75,56,73],[58,88,60,90,100]]
df = pd.DataFrame(l2,columns=[‘Tamil’,’English’,’Maths’,’Science’,’Social’],index=[‘Ramesh’,’Suresh’,’Kamesh’],dtype=’int32′)

பின் அதனை பிரிண்ட் செய்து பார்ப்போம்.

print (df)

       Tamil English Maths Science Social
Ramesh 90    83      67    83      45
Suresh 68    89      75    56      73
Kamesh 58    88      60    90      100

Percentage Change

ஒவ்வொரு row-வில் உள்ள தரவுகளும் அதற்கு முந்தைய row-வில் உள்ள தரவுகளுடன் எவ்வளவு சதவீதம் மாறுபடுகின்றன என்பதைக் கண்டுபிடிக்க pct_change() எனும் ஃபங்ஷன் பயன்படுகிறது.
ஆகவேதான் முதல் row-க்கு முந்தி எந்த ஒரு row-வும் இல்லாத காரணத்தால் NaN என்பதை வெளிப்படுத்தியுள்ளது. அதற்கு அடுத்த row-வில் (68-90)/90 = -0.244444 என்பதை வெளிப்படுத்தியுள்ளது. இதே போல் ஒவ்வொரு மதிப்பையும் கணக்கிட்டு வெளிப்படுத்தியுள்ளது.

print (df.pct_change())

       Tamil     English   Maths     Science   Social
Ramesh NaN       NaN       NaN       NaN       NaN
Suresh -0.244444 0.072289  0.119403  -0.325301 0.622222
Kamesh -0.147059 -0.011236 -0.200000 0.607143  0.369863

Covariance

ஒவ்வொரு column-ல் உள்ள தரவுகளும் மற்ற column-ல் உள்ள தரவுகளுடன் எந்த அளவுக்குத் தொடர்புடையதாக இருக்கின்றன என்பதைக் கண்டுபிடிக்க Covariance,Correlation ஆகியவை பயன்படுகின்றன. இவற்றின் முக்கியத்துவத்தை மெஷின் லேர்னிங் என்ற புத்தகத்தில் ஏற்கனவே பார்த்தோம். இப்போது இவற்றுக்கான கணக்கீடுகளைப் பற்றி கொஞ்சம் கற்றுக் கொள்வோம்.
ஒவ்வொரு column-ல் இருக்கும் எண்களும் பல்வேறு range-ல் இருக்க வாய்ப்புகள் உள்ளன. ஆகவேதான் இவற்றுக்கிடையே இருக்கும் தொடர்பினைக் கண்டறிய ஒவ்வொரு column-ல் உள்ள மதிப்புகளுடனும் அந்த column-ன் சராசரி கழிக்கப்பட்டு ஒரு பொதுமதிப்பு உருவாக்கப்படுகிறது. இவ்வாறு இரண்டு column-க்கும் உருவாக்கப்பட்ட பொது மதிப்புகளை வைத்து அதன் தொடர்பு கண்டுபிடிக்கப்படுகிறது.
Covariance-க்கான வாய்ப்பாடு பின்வருமாறு.

summation of (x element – mean(x)).(y element – mean(y))
/ N -1

இங்கு தமிழ், ஆங்கிலம் ஆகிய இரு column-ல் சேமிக்கப்பட்டுள்ள தரவுகளின் covariance மதிப்பு பின்வருமாறு கணக்கிடப்படுகிறது.

(90+68+58)/3 = 72
(83+89+88)/3 = 86.67

= {[(90-72)*(83-86.67)]+
[(68-72)*(89-86.67)]+
[(58-72)*(88-86.67)]}/(3-1)
= {[18*(-3.67)]+
[(-4)*2.33]+
[(-14)*1.33]}/2
= [(-66.06)+(-9.32)+(-18.62)]/2
= -94/2 = -47

print (df[‘Tamil’].cov(df[‘English’]))
-47.0

அடுத்து ஒவ்வொரு column-க்கும் மற்ற column-களுக்கு இடையேயான covariance மதிப்பு கண்டுபிடிக்கப்பட்டுள்ளது.

print (df.cov())

        Tamil    English    Maths       Science     Social
Tamil   268.0    -47.000000 33.000000   5.000000    -441.000000
English -47.0    10.333333  4.666667    -26.833333  69.333333
Maths   33.0     4.666667   56.333333   -129.166667 -94.333333
Science 5.0 –    26.833333  -129.166667 322.333333  91.166667
Social  -441.0   69.333333  -94.333333  91.166667   756.333333

Correlation

Correlation-க்கான வாய்ப்பாடு பின்வருமாறு.

summation of (x element – mean(x)).(y element – mean(y))
/ square root of {summation of {square of [(x element – mean(x)]. square of [(y element – mean(y)]}}

Covariance மதிப்பு infinity வரை செல்லும். இதன் அளவிடப்பட்ட வடிவமாக (scaled form) correlation-ஐ சொல்லலாம். correlation மதிப்பு பொதுவாக -1 லிருந்து 1 வரை அமையும்.

மேலும் correlation மதிப்பு தரவுகளில் ஏற்படும் மாறுதல்களுக்கு ஏற்ப மாறி அமையாது. எடுத்துக்காட்டாக இரு column-லும் உள்ள அனைத்து மதிப்புகளையும் ஒரு குறிப்பிட்ட எண்ணால் பெருக்குகிறோம் என்று வைத்துக் கொள்வோம். இந்த மாறுதல்களால் covariance மதிப்பு மாறுபடும். ஆனால் இது போன்ற மாற்றங்கள் correlation மதிப்பில் எவ்வித மாற்றத்தையும் உண்டாக்காது.

இங்கு தமிழ், ஆங்கிலம் ஆகிய இரு column-ல் சேமிக்கப்பட்டுள்ள தரவுகளின் correlation மதிப்பு பின்வருமாறு கணக்கிடப்படுகிறது.

(90+68+58)/3 = 72
(83+89+88)/3 = 86.67

= {[18*(-3.67)]+[(-4)*2.33]+
[(-14)*1.33]} /
sqft{[(18*18)+(-4*-4)+(-14*-14]
*[(-3.67*-3.67)+(2.33*2.33)+(1.33*1.33)]}
= [(-66.06)+(-9.32)+(-18.62)]/
sqft{[324+16+196]
*[13.468+5.4289+1.7689]}
= -94/sqft(536*20.6658)
= -94/105.2467 = -0.8931

print (df.corr())

        Tamil     English   Maths     Science   Social
Tamil   1.000000  -0.893121 0.268574  0.017012  -0.979523
English -0.893121 1.000000  0.193421  -0.464945 0.784269
Maths   0.268574  0.193421  1.000000  -0.958551 -0.457010
Science 0.017012  -0.464945 -0.958551 1.000000  0.184640
Social  -0.979523 0.784269  -0.457010 0.184640  1.000000

Ranks

கொடுக்கப்பட்ட மதிப்புகளின் அடிப்படையில் தரவரிசைப் படுத்திக் காட்ட rank() பயன்படுகிறது.

print (df.rank())

       Tamil English Maths Science Social
Ramesh 3.0   1.0     2.0   2.0     1.0
Suresh 2.0   3.0     3.0   1.0     2.0
Kamesh 1.0   2.0     1.0   3.0     3.0

Rolling

Rolling Mean என்றால் நகரும் சராசரி என்று பொருள். பொதுவாக timeseries தரவுகளில் இதுபோன்ற விஷயங்கள் பயன்படும். கொடுக்கப்பட்ட window மதிப்பின் அடிப்படையில் தரவுகளைப் பிரித்து அதனைக் கொண்டு சராசரியைக் கணக்கிடும். இவ்வாறு கணக்கிடும்போது ஒவ்வொரு row-ம் விண்டோ அளவிற்கு ஏற்ப அதற்கு முந்தைய ரெகார்ட்ஸை எடுத்துக்கொண்டு கணக்கிடும். ஆகவே சராசரி கணக்கெடுப்புக்கு உதவும் rows-ஆனது சிறு சிறு பகுதிகளாக நகர்ந்து கொண்டே செல்லும். எனவேதான் இது Moving Average என்றும் அழைக்கப்படுகிறது. இங்கு விண்டோ அளவு மூன்று என கொடுக்கப்பட்டுள்ளதால் முதலிரண்டு row-க்கு null மதிப்பை வெளிப்படுத்திவிட்டு, மூன்றாவது ரோவில் இருந்து மும்மூன்று row-க்கும் சராசரியைக் கணக்கிட்டு வெளிப்படுத்தியுள்ளது.

(90+68+58)/3 = 72

நான்காவது row இருந்திருந்தால் 2,3,4 ஆகிய இடங்களில் இருக்கும் மதிப்பைக் கொண்டு சராசரியைக் கணக்கிடும்.

print (df.rolling(window=3).mean())

       Tamil English   Maths     Science   Social
Ramesh NaN   NaN       NaN       NaN       NaN
Suresh NaN   NaN       NaN       NaN       NaN
Kamesh 72.0  86.666667 67.333333 76.333333 72.666667

அதுவே min periods=2 எனக் கொடுத்தால் மூன்று row இல்லாதபோது குறைந்தபட்சம் இரண்டு row இருந்தால் கூட அதை எடுத்துக்கொண்டு சராசரியைக் கணக்கிடும். அதுவும் இல்லாத பட்சத்தில் தான் NaN-ஐ வெளிப்படுத்தும்.
இங்கு முதல் row-க்கு NaN என்பதையும், இரண்டாவது row-க்கு இரண்டின் சராசரியையும், மூன்றாவது row-லிருந்து கொடுக்கப்பட்ட விண்டோ மதிப்பின்படி சராசரியைக் கணக்கிட்டும் வெளிப்படுத்தியுள்ளது.

(90+68)/2 = 79
(90+68+58)/3 = 72

print (df.rolling(window=3,min_periods=2).mean())

       Tamil  English   Maths     Science   Social
Ramesh NaN    NaN       NaN       NaN       NaN
Suresh 79.0   86.000000 71.000000 69.500000 59.000000
Kamesh 72.0   86.666667 67.333333 76.333333 72.666667

ஒன்றுக்கும் மேற்பட்ட மெட்ரிக்சை கண்டுபிடித்து வெளிப்படுத்த விரும்பினால் aggregate () என்பதற்குள் பின்வருமாறு கொடுக்கலாம். இங்கு sum, mean ஆகிய இரண்டும் கண்டுபிடித்து வெளிப்படுத்தப்பட்டுள்ளது.

90+68 = 158
90+68+58 = 216

(90+68)/2 = 79
(90+68+58)/3 = 72

print (df.rolling(window=3,min_periods=2).aggregate([np.sum,np.mean]))

       Tamil      Englis… Science   Social
       sum   mean sum   … mean      sum   mean
Ramesh NaN   NaN  NaN   … NaN       NaN   NaN
Suresh 158.0 79.0 172.0 … 69.500000 118.0 59.000000
Kamesh 216.0 72.0 260.0 … 76.333333 218.0 72.666667
[3 rows x 10 columns]

Expanding

Rolling என்பது சிறு சிறு பகுதிகளாக தரவுகளைப் பிரித்துக்கொண்டு கணக்கீடுகளை நிகழ்த்தும். Expanding என்பது கணக்கிட்டு வந்த மதிப்புகளைக் கணக்கில் கொண்டு தனது கணக்கீடுகளைத் தொடர்ந்து கொண்டே செல்லும்.
கீழ்கண்ட Rolling எடுத்துக்காட்டில் மூன்றாவது row-க்கான கணக்கீடு அதன் மதிப்பையும் அதற்கு முந்தைய row மதிப்பான 68-ஐயும் இணைத்து 126 என்பதனை வெளிப்படுத்தியுள்ளது.

90+68+58

print (df.rolling(window=2).sum())

       Tamil English Maths Science Social
Ramesh NaN   NaN     NaN   NaN     NaN
Suresh 158.0 172.0   142.0 139.0   118.0
Kamesh 126.0 177.0   135.0 146.0   173.0

அதுவே expanding என்று வரும்போது மூன்றாவது row-க்கான கணக்கீடு அதன் மதிப்பையும் அதற்கு முந்தைய row கணக்கிட்டு வெளிப்படுத்திய மதிப்பான 158-ஐயும் இணைத்து 216 என வெளிப்படுத்தியுள்ளதைக் காணலாம்.

print (df.expanding(min_periods=2).sum())

       Tamil English Maths Science Social
Ramesh NaN   NaN     NaN   NaN     NaN
Suresh 158.0 172.0   142.0 139.0   118.0
Kamesh 216.0 260.0   202.0 229.0   218.0

Exponential weighted functions

இதுவரை நாம் பார்த்த rolling, expanding ஆகிய அனைத்தும் பல்வேறு யுக்திகளைக் கொண்டு mean, median ஆகியவற்றைக் கணக்கிடுகின்றன. ஆனால் இதுவோ ஒருசில parameters – ஐக் கணக்கில் கொண்டு அதே விசயத்தை செய்கின்றது.
com, span, halflife போன்ற சில parameters- ஐ வைத்து முதலில் ஆல்ஃபா மதிப்பைக் கண்டுபிடிக்கிறது.

alpha = 1/(1+com)

பின் அந்த ஆல்ஃபா மதிப்பை வைத்து கீழ்க்கண்ட சமன்பாட்டில் பொருத்தி வேண்டிய மதிப்புகள் கண்டுபிடிக்கப்படுகின்றன.

weighted_average[0] = arg[0]
weighted_average[i] = (1-alpha)*wt._avg[i-1]+alpha*arg[i]

இங்கு com = 0.5 என வைத்து ஆல்ஃபா மதிப்பு கண்டுபிடிக்கப்பட்டுள்ளது.
alpha = 1/(1+0.5) = 1/1.5 = 0.66

பின் முதல் row-க்கான mean அதே மதிப்பாக அமைந்துள்ளது.

அடுத்த row-க்கான mean சமன்பாட்டின் படி கீழ்கண்டவாறு கண்டுபிடிக்கப்பட்டுள்ளது.
(1-0.66)*90 + (0.66*68)
= 30.6 + 44.88 = 75.48
இங்கு 75.48 என கணக்கிடப்பட்டுள்ளது. ஆனால் நமது நிரல் 73.50 என்பதை வெளிப்படுத்தியுள்ளது.

மூன்றாவது row-க்கான mean கீழ்கண்டவாறு.
(1-0.66)*75 + (0.66*58)
= 25.5 + 38.28 = 63.78
இங்கு 63.78 என கணக்கிடப்பட்டுள்ளது. ஆனால் நமது நிரல் 62.76 என்பதை வெளிப்படுத்தியுள்ளது.
இந்தச் சிறு வித்தியாசம் எதனால் என்பது இன்னும் சரிவர புலப்படவில்லை. இதைப் படிக்கும் யாரேனும் இதற்கான விடையைக் கண்டுபிடித்தால் கூறவும்.

print (df.ewm(com=0.5).mean())

       Tamil     English   Maths Science   Social
Ramesh 90.000000 83.000000 67.0  83.000000 45.000000
Suresh 73.500000 87.500000 73.0  62.750000 66.000000
Kamesh 62.769231 87.846154 64.0  81.615385 89.538462

%d bloggers like this: