[SOLVED] turning working KNN code into a static library

New to FreeBASIC? Post your questions here.
Post Reply
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: [help] converting code from python to FB

Post by dodicat »

Hello ron77
Here is a completely different regression line method, (For fun).
The only statistic is a mean, the rest is empirical.

Code: Select all



Function segmentdistance(lx1 As Double, _
    ly1 As Double, _
    lx2 As Double, _
    ly2 As Double, _
    px As Double,_
    py As Double, _
    Byref ox As Double=0,_
    Byref oy As Double=0) As Double
    Dim As Double M1,M2,C1,C2,B
    B=(Lx2-Lx1):If B=0 Then B=1e-20
    M2=(Ly2-Ly1)/B:If M2=0 Then M2=1e-20
    M1=-1/M2
    C1=py-M1*px
    C2=(Ly1*Lx2-Lx1*Ly2)/B
    Var L1=((px-lx1)*(px-lx1)+(py-ly1)*(py-ly1)),L2=((px-lx2)*(px-lx2)+(py-ly2)*(py-ly2))
    Var a=((lx1-lx2)*(lx1-lx2) + (ly1-ly2)*(ly1-ly2))
    Var a1=a+L1
    Var a2=a+L2
    Var f1=a1>L2,f2=a2>L1
    If f1 Xor f2 Then
        Var d1=((px-Lx1)*(px-Lx1)+(py-Ly1)*(py-Ly1))
        Var d2=((px-Lx2)*(px-Lx2)+(py-Ly2)*(py-Ly2))
        If d1<d2 Then Ox=Lx1:Oy=Ly1 : Return Sqr(d1) Else  Ox=Lx2:Oy=Ly2:Return Sqr(d2)
    End If
    Var M=M1-M2:If M=0 Then M=1e-20
    Ox=(C2-C1)/(M1-M2)
    Oy=(M1*C2-M2*C1)/M
    Return Sqr((px-Ox)*(px-Ox)+(py-Oy)*(py-Oy))
End Function

Sub rotate2d(pivotx As Double,pivoty As Double,px As Double,py As Double,a As Double,Byref rotx As Double,Byref roty As Double)',scale)
    rotx=(Cos(a*.0174533)*(px-pivotx)-Sin(a*.0174533)*(py-pivoty))+pivotx
    roty=(Sin(a*.0174533)*(px-pivotx)+Cos(a*.0174533)*(py-pivoty))+pivoty
End Sub

Sub GetRegressionLine(x() As Double,y() As Double,ans() As Double)
    Redim ans (1 To 6)
    Dim As Double mx,my
    Dim As Double lx=1e9,ly=1e9,ux=-1e9,uy=-1e9
    Dim As Double lastux,lastuy,lastlx,lastly
    Dim As Double ix,iy 'intertcept points
    Dim As Double tot,length,a
    Dim As Double min=1e6,lastmin
    For n As Long=Lbound(x) To Ubound(x)
        mx+=x(n)
        my+=y(n)
        If lx>x(n) Then lx=x(n)
        If ly>y(n) Then ly=y(n)
        If ux<x(n) Then ux=x(n)
        If uy<y(n) Then uy=y(n)
    Next n
    mx=mx/(Ubound(x)-Lbound(x)+1)'means
    my=my/(Ubound(x)-Lbound(x)+1)
    length=Sqr((ux-lx)^2+(uy-ly)^2)
    lx=mx-1.5*length/2
    ux=mx+1.5*length/2
    ly=my
    uy=my
    
    'test rotate direction
    Dim As Double tlx=lx,tly=ly,tux=ux,tuy=uy,t1,t2
    For k As Long=1 To 2
        rotate2d(mx,my,tlx,tly,.1,tlx,tly)
        rotate2d(mx,my,tux,tuy,.1,tux,tuy)
        For n As Long=Lbound(x) To Ubound(x)
            Var d=segmentdistance(tlx,tly,tux,tuy,x(n),y(n),ix,iy)
            If k=1 Then t1+=d
            If k=2 Then t2+=d
        Next n
    Next k
    a=.0001
    If t2>t1 Then a=-.0001

    Do
        tot=0
        'swing the lines round the mean and test the total distance of the points from the line.
        rotate2d(mx,my,lx,ly,a,lx,ly)
        rotate2d(mx,my,ux,uy,a,ux,uy)
        For n As Long=Lbound(x) To Ubound(x)
            Var d=segmentdistance(lx,ly,ux,uy,x(n),y(n),ix,iy)
            tot+=d
        Next n
        If min>tot Then min=tot
        If lastmin=min Then 'BINGO, you have passed the minimum distance 
            ans(1)=lastlx
            ans(2)=lastly
            ans(3)=lastux
            ans(4)=lastuy
            ans(5)=(lastuy-lastly)/(lastux-lastlx) 'gradient(M)
            ans(6)=-lastlx*ans(5)+lastly  'intercept(C)
            Exit Do
        End If
        lastmin=min
        lastux=ux
        lastuy=uy
        lastlx=lx
        lastly=ly
    Loop
End Sub

Screen 20
Dim As Integer xres,yres
Screeninfo xres,yres
Dim As Long mx,my,flag,btn

Window(0,0)-(xres,yres)
Redim As Double x(),y()
Dim As Long count
start:
Do
      'grid
      for x as long=0 to xres step 100
            line(x,0)-(x,yres),8
      next x
      for x as long=0 to yres step 100
            line(0,x)-(xres,x),8
            next x
    Getmouse mx,my,,btn
    Locate 4
    Print "Mouse click some points on the screen, press escape when points are complete"
    Locate 6
    Print String(30," ")
    Locate 6
    Print mx;"  ";yres-my
    If flag=0 And btn=1 Then 
        count+=1
        Circle(mx,yres-my),5:flag=1
        
        Redim Preserve x(1 To count)
        Redim Preserve y(1 To count)
        x(count)=mx
        y(count)=yres-my
    End If
    
    flag=btn
    Sleep 50
Loop Until Inkey=Chr(27)
'=========  get result() =====
Cls
Redim As Double result()
GetRegressionLine(x(),y(),result())



Circle(result(1),result(2)),4,5 'end points, not always on the screen.
Circle(result(3),result(4)),4,5
Line(result(1),result(2))-(result(3),result(4)) 'regression line

Dim As Double ix,iy 'intercepts
Dim As Double predictions(1 To Ubound(x))
Dim As  Double sum
For n As Long=Lbound(x) To Ubound(x)
    Var d=segmentdistance(result(1),result(2),result(3),result(4),x(n),y(n),ix,iy)
    Circle(x(n),y(n)),5
    'line(x(n),y(n))-(ix,iy),8
    Circle(x(n),result(5)*x(n)+result(6)),3,3,,,,f
    predictions(n)=result(5)*x(n)+result(6)
    Line(x(n),y(n))-(x(n),predictions(n)),8
    sum+=(y(n)-predictions(n))^2
Next n
Var sumerror=sum/(Ubound(x)-Lbound(x)+1)
Var rmse=Sqr(sumerror)
'grid
 for x as long=0 to xres step 100
            line(x,0)-(x,yres),8
      next x
      for x as long=0 to yres step 100
            line(0,x)-(xres,x),8
            next x
Locate 7
Print "Equation of regression line:"
Print "y = ";result(5);"*x";Iif(Sgn(result(6))=1," +","");result(6)

Locate 12
Color 3
Print "predictions"
For n As Long=1 To Ubound(predictions)
    Print Csng(predictions(n));"";
Next n
Print
Print "RMSE = ";rmse
Color 15
Print "  again  y/n ?"
count=0

If Input(1)="y" Then Cls: Goto start

  
Here is the python code running in fb (64 bit)
http://www.mediafire.com/file/d3tk9j0fm ... n.zip/file
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: [help] converting code from python to FB

Post by dodicat »

Standard way.

Code: Select all



Type ListPair
      As Double x,y
End Type

Function mean(p() As ListPair) As ListPair
      Dim As ListPair pt
      For n As Long=Lbound(p) To Ubound(p)
            pt.x+=p(n).x
            pt.y+=p(n).y
      Next n
      Var sz=(Ubound(p)-Lbound(p)+1)
      Return Type(pt.x/sz,pt.y/sz)
End Function

Function Gradient(p() As ListPair) As Double
      Dim As Double CoVariance,Variance
      Dim As ListPair m=mean(p())
      For n As Long=Lbound(p) To Ubound(p)
            CoVariance+=(p(n).x-m.x)*(p(n).y-m.y)
            Variance+=(p(n).x-m.x)^2           
      Next n
      Return CoVariance/Variance 
End Function

Function intercept(p() As ListPair,grad As Double) As Double
      Var m=mean(p())
      Return  m.y-grad*m.x
End Function

Function RMSerror(p() As ListPair,m As Double,c As Double,res() As Double) As Double
      Dim As Double acc
      Redim res(Lbound(p) To Ubound(p))
      For n As Long=Lbound(p) To Ubound(p)
            res(n)=m*p(n).x+c
            acc+=(p(n).y-res(n))^2
      Next n
      acc/=(Ubound(p)-Lbound(p)+1)
      Return Sqr(acc)
End Function


Function minmax(p() As ListPair,flag As String="x") As ListPair 'for plotting
      Dim As ListPair result
      Dim As Double d(Lbound(p) To Ubound(p))
      For n As Long=Lbound(d) To Ubound(d)
            If flag="x" Then  d(n)=p(n).x Else d(n)=p(n).y
      Next
      For n1 As Long=Lbound(d) To Ubound(d)-1
            For n2 As Long=n1+1 To Ubound(d)
                  If d(n1)>d(n2) Then Swap d(n1),d(n2)
            Next
      Next
      Return Type(d(Lbound(d)),d(Ubound(d)))
End Function

Sub plot(p() As ListPair,pred() As Double,xres As Integer,yres As Integer)
      #define map(a,b,x,c,d) ((d)-(c))*((x)-(a))/((b)-(a))+(c)
      #define xmap(z) map(minx,maxx,z,k,(xres-k))
      #define ymap(z) map(miny,maxy,z,k,(yres-k))
      Var minx=minmax(p(),"x").x,maxx=minmax(p(),"x").y
      Var miny=minmax(p(),"y").x,maxy=minmax(p(),"y").y
      Var k=100
      Line(k,k)-(xres-k,yres-k),8,b
      Dim As Double lxpos,lypos
      For n As Long=Lbound(p) To Ubound(p)
            Circle(xmap(p(n).x),ymap(p(n).y)),5,15,,,,f
            Circle(xmap(p(n).x),ymap(pred(n))),5,5,,,,f
            If n>Lbound(p) Then Line(xmap(p(n).x),ymap(pred(n)))-(lxpos,lypos),5
            Line(xmap(p(n).x),ymap(p(n).y))-(xmap(p(n).x),ymap(pred(n))) ,8
            lxpos=xmap(p(n).x)
            lypos=ymap(pred(n))
      Next n
End Sub

Sub GetRegressionLineAndShow(p() As ListPair,xres As Integer,yres As Integer)
      Var M= Gradient(p())  'get the gradient and intercept 
      Var C=intercept(p(),M)
      Redim As Double predictions()
      'get the regression line points (predictions) and root mean square error
      Dim As Double e=RMSerror(p(),M,C,predictions())
      Color 5
      'y=Mx+C
      Print "Regression line:   y = ";M;"*x";Iif(Sgn(C)=1," +","");C
      Print
      Print "Predictions"
      For n As Long=Lbound(predictions) To Ubound(predictions)
            Print predictions(n);" ";
      Next
      Print
      Color 8
      Print "RMSE: ";e
      plot(p(),predictions(),xres,yres)
End Sub


'python result
'predictions
'[1.1999999999999995, 1.9999999999999996, 3.5999999999999996, 2.8, 4.3999999999999995]
'RMSE: 0.693

Screen 20

Dim As Integer xres,yres
Screeninfo xres,yres
Window(0,0)-(xres,yres)

Dim As ListPair p(1 To 5)={(1, 1), (2, 3), (4, 3), (3, 2), (5, 5)} 'python list
GetRegressionLineAndShow(p(),xres,yres) '' from python list
Print "Press a key . . ."
Sleep
Cls
Dim As ListPair p2(1 To 11)={(6,82),(10,88),(2,56),(4,64),(6,77),(7,92),(0,23),(1,41),(8,80),(5,59),(3,47)}
GetRegressionLineAndShow(p2(),xres,yres)'another list
Print "Press a key . . ."
Sleep
Cls
dim as ListPair p3(...)={(1,sin(1)),(2,sin(2)),(3, sin(3)),(4,sin(4)),(5,sin(5)),(6,sin(6))}
GetRegressionLineAndShow(p3(),xres,yres)'another list
color 15
Print "DONE Press a key . . ."
Sleep

 
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [SOLVED] converting code from python to FB

Post by ron77 »

hello all :)

i'm happy to tell that me and my teacher had succeeded in combining dodicat code of linear regression with paul doe code of load_csv and here is the result before you - the next step planned is to make out of this working code a library with a "bi" file header and a ".a" lib file...

i thank everyone who suggested and advised and offered their help so far including : paul doe, dodicat, tourist trap, fxm, imortis, mrSwiss and the rest :)

:) ron77

the code:

Code: Select all

#include once "file.bi"

TYPE ListPair
      As Double x,y
End TYPE

'APPEND TO the listpair array the ListPair item
SUB pAPPEND(arr() AS ListPair , Item AS ListPair)
	REDIM PRESERVE arr(LBOUND(arr) TO UBOUND(arr) + 1) AS ListPair
	arr(UBOUND(arr)) = Item
END SUB

SUB loadDataset( byref path as const string , p() AS ListPair)
  'dim as ListPairTable t
   'Dim As ListPair p()
  
  
  if( fileExists( path ) ) then
    dim as long f = freeFile()
    
    open path for input as f
    
    do while( not eof( f ) )
      dim as ListPair d
      
      input #f, d.x
      input #f, d.y
      PAPPEND p(), d            
    LOOP
    CLOSE #f
  end if
  
end SUB


Function mean(p() As ListPair) As ListPair
      Dim As ListPair pt
      For n As Long=Lbound(p) To Ubound(p)
            pt.x+=p(n).x
            pt.y+=p(n).y
      Next n
      Var sz=(Ubound(p)-Lbound(p)+1)
      Return Type(pt.x/sz,pt.y/sz)
End Function

Function Gradient(p() As ListPair) As Double
      Dim As Double CoVariance,Variance
      Dim As ListPair m=mean(p())
      For n As Long=Lbound(p) To Ubound(p)
            CoVariance+=(p(n).x-m.x)*(p(n).y-m.y)
            Variance+=(p(n).x-m.x)^2           
      Next n
      Return CoVariance/Variance
End Function

Function intercept(p() As ListPair,grad As Double) As Double
      Var m=mean(p())
      Return  m.y-grad*m.x
End Function

Function RMSerror(p() As ListPair,m As Double,c As Double,res() As Double) As Double
      Dim As Double acc
      Redim res(Lbound(p) To Ubound(p))
      For n As Long=Lbound(p) To Ubound(p)
            res(n)=m*p(n).x+c
            acc+=(p(n).y-res(n))^2
      Next n
      acc/=(Ubound(p)-Lbound(p)+1)
      Return Sqr(acc)
End Function


Function minmax(p() As ListPair,flag As String="x") As ListPair 'for plotting
      Dim As ListPair result
      Dim As Double d(Lbound(p) To Ubound(p))
      For n As Long=Lbound(d) To Ubound(d)
            If flag="x" Then  d(n)=p(n).x Else d(n)=p(n).y
      Next
      For n1 As Long=Lbound(d) To Ubound(d)-1
            For n2 As Long=n1+1 To Ubound(d)
                  If d(n1)>d(n2) Then Swap d(n1),d(n2)
            Next
      Next
      Return Type(d(Lbound(d)),d(Ubound(d)))
End Function

Sub plot(p() As ListPair,pred() As Double,xres As Integer,yres As Integer)
      #define map(a,b,x,c,d) ((d)-(c))*((x)-(a))/((b)-(a))+(c)
      #define xmap(z) map(minx,maxx,z,k,(xres-k))
      #define ymap(z) map(miny,maxy,z,k,(yres-k))
      Var minx=minmax(p(),"x").x,maxx=minmax(p(),"x").y
      Var miny=minmax(p(),"y").x,maxy=minmax(p(),"y").y
      Var k=100
      Line(k,k)-(xres-k,yres-k),8,b
      Dim As Double lxpos,lypos
      For n As Long=Lbound(p) To Ubound(p)
            Circle(xmap(p(n).x),ymap(p(n).y)),5,15,,,,f
            Circle(xmap(p(n).x),ymap(pred(n))),5,5,,,,f
            If n>Lbound(p) Then Line(xmap(p(n).x),ymap(pred(n)))-(lxpos,lypos),5
            Line(xmap(p(n).x),ymap(p(n).y))-(xmap(p(n).x),ymap(pred(n))) ,8
            lxpos=xmap(p(n).x)
            lypos=ymap(pred(n))
      Next n
End Sub

Sub GetRegressionLineAndShow(p() As ListPair,xres As Integer,yres As Integer)
      Var M= Gradient(p())  'get the gradient and intercept
      Var C=intercept(p(),M)
      Redim As Double predictions()
      'get the regression line points (predictions) and root mean square error
      Dim As Double e=RMSerror(p(),M,C,predictions())
      COLOR 5
      'y=Mx+C
      Print "Regression line:   y = ";M;"*x";Iif(Sgn(C)=1," +","");C
      PRINT
      PRINT "Predictions"
      For n As Long=Lbound(predictions) To Ubound(predictions)
            Print predictions(n);" ";
      Next
      Print
      Color 8
      Print "RMSE: ";e
      SLEEP
      CLS
      PLOT(p(),predictions(),xres,yres)
End Sub


SCREEN 20
'SCREENRES 1000,950

Dim As Integer xres,yres
Screeninfo xres,yres
Window(0,0)-(xres,yres)

REDIM p(any) AS ListPair
loadDataset( "D:\repo\FB_libLINREG\datasets\dataset.csv", p() )
GetRegressionLineAndShow(p(),xres,yres)


Sleep


the dataset file "dataset.csv"

Code: Select all

108,392.5
19,46.2
13,15.7
124,422.2
40,119.4
57,170.9
23,56.9
14,77.5
45,214
10,65.3
5,20.9
48,248.1
11,23.5
23,39.6
7,48.8
2,6.6
24,134.9
6,50.9
3,4.4
23,113
6,14.8
9,48.7
9,52.1
3,13.2
29,103.9
7,77.5
4,11.8
20,98.1
7,27.9
4,38.1
0,0
25,69.2
6,14.6
5,40.3
22,161.5
11,57.2
61,217.6
12,58.1
4,12.6
16,59.6
13,89.9
60,202.4
41,181.3
37,152.8
55,162.8
41,73.4
11,21.3
27,92.6
8,76.1
3,39.9
17,142.1
13,93
13,31.9
15,32.1
8,55.6
29,133.3
30,194.5
24,137.9
9,87.4
31,209.8
14,95.5
53,244.6
26,187.5
p,s, - if you wish to continue following this project please visit this post viewtopic.php?f=8&t=28907

any help will be greatly appreciated

ron77
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: [SOLVED] converting code from python to FB

Post by Tourist Trap »

ron77 wrote: the dataset file "dataset.csv"

Code: Select all

108,392.5
19,46.2
13,15.7
124,422.2
40,119.4
57,170.9
...
p,s, - if you wish to continue following this project please visit this post viewtopic.php?f=8&t=28907

any help will be greatly appreciated

ron77
Hi ron,

Well done. I didn't know it was a school project. Nice to see FB being used for learning purpose at school, it's really worth it, If I can help I will. I just really lack time (here I'm on learning R for professionnal affairs at the moment).
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [SOLVED] converting code from python to FB

Post by ron77 »

tourist trap wrote:
Hi ron,

Well done. I didn't know it was a school project. Nice to see FB being used for learning purpose at school, it's really worth it, If I can help I will. I just really lack time (here I'm on learning R for professionnal affairs at the moment).
hello tourist trap... well actually i'm a little bit older for being a pupil of children school last time i checked i was 43 years old it's pretty old for being a school pupil - i'm taking private lesson from a private teacher in FB programming and paying him a lot of money since that's the only way i can learn... i wrote this in the project post and you would have known that if you would take the time to read seems like many here don't take time to read posts properly or even to help beginner's in FB learn stuff ("read the documentation" is the popular answer since no one has time to teach for free or explain stuff to a beginner like me that's why i pay with my own money to to this project FOR THIS COMMUNITY) and it's not a school project too it's suppose to be an OPEN SOURCE COMMUNITY PROJECT but seems like everyone is too busy to chip in IT'S FUNNY HOW YOU GUYS TELL ME TO READ THE DOCUMENTION OF FB YET AT THE SAME TIME DON'T BOTHER TO PROPERLY READ DITAILS IN POSTS oh well i guess your too busy for that...
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: [SOLVED] converting code from python to FB

Post by MrSwiss »

ron77 wrote:IT'S FUNNY HOW YOU GUYS TELL ME TO READ THE DOCUMENTION OF FB YET AT THE SAME TIME DON'T BOTHER TO PROPERLY READ DITAILS IN POSTS
I fully agree with the "don't bother with the details" part of your sentence.

I whould like to stress something thats a bit more to the point:
- posts are read, but the brain seems to be left "switched OFF"
this leads to:
- the comprehension of the meaning transmitted, seems lacking

re: Documentation
This is obviously, a different "kettle of fish" all together.
Many that have commented here, have also been involved (one way or another) in, generally speaking:
- clarifying matters (in the doc's)
- adding important notes/warnings/special cases
- rewriting sample code
- adding desriptions of new features
- ... (and so on and so forth)
IOW, the time the comunity as a whole, has "invested" in Documentation is substantial.
Nobody, therefore, wants this to be spent in vain.

As a result some research (in the doc's) is highly recommended as well as expected,
before asking questions that, a short "look-up" in the doc's could easily answer.
(You also whould dislike it, to repeatedly answering the very same questions again and again!)
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [SOLVED] converting code from python to FB

Post by ron77 »

hello MrSwiss

i agree with what you say and apologies for my cynical replay to tourist trap... i Stan corrected and apologies if anyone was offended or felt disrespected... it's just made me angry the misunderstanding ("school project")

ron77
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: [SOLVED] converting code from python to FB

Post by Tourist Trap »

ron77 wrote: i agree with what you say and apologies for my cynical replay to tourist trap... i Stan corrected and apologies if anyone was offended or felt disrespected... it's just made me angry the misunderstanding ("school project").
I also apology, since I didn't read the text surrounding the project I must confess. I try to keep an eye on what is going on around here, but I don't really play much with FB those days, because there are so many other languages that I must learn besides this one, which anyway is still my favourite.

For the part where you talk about people advising you to read the doc however, I claim very loudly not being of that kind. The doc is very nice but doesn't replace the interaction with the community.

And last but not least, I started also FB with little knowledge years ago, and thanks to the guys here, fxm being probably the most representative, it didn't require from me too much effort before I grasped many details that I needed to increase in skill. But still, I was helped by the fact that I used VB.net before, and basic tasks in VBA also. Which means, I think that multiplying the source of learnings also helped.

Then about the school, I'm almost 50 years old and was at school last year for graduating in webmapping and some data science that I need at work. That probably made me oversensitive on the possible fact you were also doing some school learning involving FB (it doesn't necessarily mean in my head you should be a youngster or anything).

Sorry again ron for my misreading :) Thanks for not taking that too badly. Next time I'll try to read what comes around the code snippets :)
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [SOLVED] converting code from python to FB

Post by ron77 »

thank you tourist trap for understanding and not being angry :-/ i would also like to take this opportunity and declare that project libLINREG library has been finish with the help of the community and it's members yes that's true the working code turned into a working library and have been pushed to the projects repository for everyone :)

freeBASIC now has a linear regression library version 1 i hope it will be further developed by the community the library is OPEN SOURCE MIT LISENCE...

here is the repository of the project: https://github.com/trapmania/libLINREG

<3
ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [HELP] converting code from python to FB

Post by ron77 »

hello again everyone :)

i would like to try and make another ML library for freeBASIC this time K'S NEAREST NEIGHBOUR (KNN)...

here is the machine learning algorithm guide in python : https://machinelearningmastery.com/tuto ... m-scratch/

there are two options 1 - to code a KNN from scratch in freebasic and turn it to a static library or...
2. try to find a library/code in C that implements KNN and make a header to freebasic... for example a C code like this : https://github.com/cdilga/knn-c...

i am trying both option with the help of my teacher...

any help will be greatly appreciated

ron77
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: [HELP] converting code from python to FB

Post by Tourist Trap »

ron77 wrote:hello again everyone :)

i would like to try and make another ML library for freeBASIC this time K'S NEAREST NEIGHBOUR (KNN)...
Hi ron,

how are u today. I will definitely take a deep look at the python code. I see that it's from scratch (not much dependencies involved) so it can teach a lot of fundamental stuff.

Similarly to the last regression problem, there is a choice to make relatively to the lists data structures. Do you plan to work at making a linked-list or things like that before you start? Or will you try to attack the problem with simple arrays everywhere (which would not keep the program as readable as it is in Python here)?
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: [HELP] converting KNN code from python to FB

Post by ron77 »

hi tourist trap :)

i'm better... me and my teacher when trying to code the KNN program asked ourselves the same question... python has a flexible and dynamic way with reading and storing the data in rows and columns and FB is not that flexible... the optimal way is to be able to write code in FB so it will read and store the data from csv file dynamically and flexible (like the python code) since we want the cde to be able to implement KNN prediction on all sort of data types (not to be limited to specific number of rows or columns) otherwise we will have to hard code the load csv and store it in a limited prefixed structure like arrays which will limit the ability to use the code on every type of data...

you mentioned "linked-lists" can you give an example of such data structure?

ron77
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: [HELP] converting KNN code from python to FB

Post by MrSwiss »

ron77 wrote:you mentioned "linked-lists" can you give an example of such data structure?
Hi ron77,
before deciding on a specific data-structure, check their advantages vs. disadvantages at:
Wikipedia (linked list), to allow for a informed decision.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: [HELP] converting KNN code from python to FB

Post by Tourist Trap »

ron77 wrote: you mentioned "linked-lists" can you give an example of such data structure?
Hi ron,

You'll find many examples written in FB in the forum. If you go to this post :
viewtopic.php?p=222924#p222924
and type F3 to search the page with "linked list", you then find 13 occurences. I give you this page because it's a little different than the classical search, it's a list of tons of tips and tricks posted around here gathered by author names.

Myself, I did this as an example : viewtopic.php?f=7&t=25318&p=227796&hilit=linked#p227796. The only advantage is that it shows you the links as bones in a body, so here again it's less common.

Otherwise, a linked-list is just a UDT, that stores not only the current object properties and functions, but also a pointer telling you what's the next as a list.
So for instance, I store a object describing a bone of the body, then I put a pointer and say, the next bone is there at this pointer address. So the hand bone, comes after the lower arm. It's linked this way, you will find the leg only far away if you go somehow upward in the list.

You can then handle easily list traversal, and management such as item removal, and so on. It's better than an array because it's a simple object structure, and yet embeds very well, and hides all the management that is a little of a pain to write the first time.

Let me know if you give it a try, and see where you get stuck.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: [HELP] converting KNN code from python to FB

Post by dodicat »

If it is just nearest neighbours to a chosen point in a 2D space array, then it is not difficult.

Code: Select all

type pt
    as single x,y
end type

sub GetClosest(a() as pt,ans() as pt,v as long,num as long)
     #define incircle(cx,cy,radius,x,y) (cx-x)*(cx-x) +(cy-y)*(cy-y)<= radius*radius
     dim as single r=.5,ctr
    do
        r+=.5
        ctr=0
    for n as long=lbound(a) to ubound(a)
        if incircle(a(v).x,a(v).y,r,a(n).x,a(n).y) then
            ctr+=1
            redim preserve ans(1 to ctr)
            ans(ctr)=a(n)
            end if
    next n
loop until ubound(ans)>=num
redim preserve ans(1 to num)
end sub

screen 20
dim as integer xres,yres
screeninfo xres,yres

dim as pt p(1 to 500)
redim as pt res()
'set up the array
for n as long=1 to ubound(p)
    p(n)=type(rnd*xres,rnd*yres)
next n

 #define range(f,l) Int(Rnd*(((l)+1)-(f))+(f))
 randomize 
do
    dim as long psn=range(lbound(p),ubound(p)),num=range(3,15)
    for n as long=1 to ubound(p)        'draw the points
        circle(p(n).x,p(n).y),2,7,,,,f
    next n
    
    GetClosest(p(),res(),psn,num)          'get closest num points centered on p(psn)
    
    for n as long=1 to ubound(res)
        circle(res(n).x,res(n).y),7,2   'draw these closest points
    next n
    circle(p(psn).x,p(psn).y),7,6
    draw string(50,50),"cluster of "&num & " centered on p("&psn &")"
    draw string (50,70),"Press a key, <esc> to end"
    sleep
    cls
    loop until inkey=chr(27) 
Post Reply