Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL]Sprawdzanie plagiatów
Forum PHP.pl > Forum > Przedszkole
adrianozo
Witam wszystkich.
Nurtuje mnie pytanie jak sprawdzić przy pomocy php i mysql czy dana praca nie jest plagiatem.

Mianowicie. Do bazy danych kilka osób wysyła prace ja je pobieram i akceptuje albo odrzucam i to jest banalne. Ale chodzi mi o fakt, gdy dwie osoby podeślą bardzo podobną pracę. Oczywiście nie muszą być identyczne, ale dużo rzeczy może być identycznych. Zastanawiam się jak to zrobić. Jak porównać aktualnie otwartą pracę z innymi znajdującymi się już w bazie danych. Oczywiście można zapamiętać jak mniej więcej wyglądała jakaś praca i czy się powtarza, ale ja tutaj rozważam przypadek kiedy to prace akceptuje kilka osób i potrzebny jest taki skrypt.

PS. Skrypt nie może być bardzo rygorystyczny, ani za mało smile.gif

Pozdrawiam smile.gif
muk4
Może wstępnie policzyć ilość powtarzających się wyrazów, a jeśli jest podejrzanie duża to ręcznie się za to zabrać i porównać (chyba że to praca na 30 stron).
adrianozo
Z góry przyjmujemy, że praca ma dużo stron smile.gif
sadistic_son
Myślę, że można by to zrobić tak:
Wczytujesz całe 2 prace do tablic ($tab1 i $tab2). Każde słowo jako oddzielny element. Następnie porównujesz $tab1[0] po kolei z kolejnymi elementami tablicy drugiej, czyli pracy porównywanej. Po natrafieniu na identyczne słowo (np. $tab1[0] == $tab2[345]) porównujesz $tab1[1] z następnym wyrazem w drugiej tablicy czyli $tab2[346]. Jeśli $tab[1] == $tab[346] to sprawdzasz kolejne elementy np. 5 razy, bo ustalamy, że 5 słów pod rząd to już jest plagiat. Czyli $tab1[2] do $tab2[347], potem $tab1[3] do $tab[348] itd. Jeśli natomiast, żaden element z $tab2 nie jest identyczny, lub nie ma 5 kolejnych identycznych przechodzisz do następnego elementu czyli $tab1[1] i proces powtarzasz.
Na chłopski rozum powinno działać ale daję głowę, że będzie okrutnie zasobo-żerne, ale skuteczne.

Natomiast prościej np. szukając identycznych tylko takich samych zdań to:
Wczytujesz 2 prace do 2 stringów. Pierwszy traktujesz explode, dzieląc go wg kropek, lub znaków zapytania, a właściwie wg. obu. Potem szukasz powtórzeń w drugim stringu używając substr_compare lub substr_count . Proces powtarzasz dla każdego elementu tablicy, czyli każdego zdania pierwszej pracy.
  1. $str='Aaa aaa. Bb bb bb. Cc. D d d d. Eee. Ffffff';
  2.  
  3. $str=explode('.',$str);
  4.  
  5. $str2='Rrrrr rr rrr rrr rrrr. Bb bb bb. Ppp ppp. Aaaaaaaa a aaaa. Tttttt. Cc xxxxx. Cc. Cc ttttt. O o ooo.';
  6.  
  7. foreach($str as $s){
  8. $i=substr_count($str2,$s);
  9. if($i>0){echo 'Zdanie: '.$s.' znalezione '.$i.' razy!<br />';}
  10. }
muk4
Ewentualnie funkcja similar_text.
Nigdy jej nie używałem, więc nie wiem czy działa wedle oczekiwań.
adrianozo
Ale ja nie koniecznie będę porównywał dwie prace ale jedną będę przyrównywał na przykład do trzystu prac i co wtedy??
skarabe.pl
Ja bym nie analizował słowo po słowie, tylko zdanie po zdaniu. Pomysł sadistic_son nie wyłapie prostej zmiany szyku:
1. PHP jest jednym z najlepszych języków skryptowych,
2. Spośród języków skryptowych jednym z najlepszych jest PHP.

Dlatego ja bym podzielił całą pracę na poszczególne zdania, a potem, w pętli, porównał każde zdanie z pracy A z każdym zdaniem z pracy B nadając poszczególnym "parom zdań" odpowiednią procentową wartość podobieństwa (wyrażoną prostym stosunkiem liczby słów obecnych w obu zdaniach do liczby wszystkich słów w zdaniu). Zdania bardzo podobne, a położone niedaleko od siebie można łączyć we fragmenty - jeżeli znajdzie się pięć kolejnych zdań z wynikiem >60%, to mamy plagiat.

żeby wzmocnić ten algorytm to trzeba by było każde słowo sprowadzić do formy podstawowej (przymiotniki i rzeczowniki zamienić na rodzaj męski liczby pojedynczej, a czasowniki do bezokoliczników) oraz zbudować tablicę bezpośrednich synonimów dla poszczególnych słów. Dzięki tym dwóm zabiegom zdania:
"Alina ma kota" i "Ala posiada kotka" zostaną ustandaryzowane do postaci: "Alina mieć kot".

Cytat
Ale ja nie koniecznie będę porównywał dwie prace ale jedną będę przyrównywał na przykład do trzystu prac i co wtedy??

Niczego to nie zmienia - i tak musisz wyjść od zbudowania algorytmu porównującego 2 prace.
sadistic_son
Cytat(skarabe.pl @ 10.08.2010, 21:38:13 ) *
Pomysł sadistic_son nie wyłapie prostej zmiany szyku:
1. PHP jest jednym z najlepszych języków skryptowych,
2. Spośród języków skryptowych jednym z najlepszych jest PHP.
Takiej zamiany zdań to nie wyłapie nawet plagiat.pl Wiem bo sam ostatnio 'przerabiałem' pracę w ten sposób i plagiat się nie połapał smile.gif
skarabe.pl
Cytat(sadistic_son @ 10.08.2010, 21:55:12 ) *
Takiej zamiany zdań to nie wyłapie nawet plagiat.pl Wiem bo sam ostatnio 'przerabiałem' pracę w ten sposób i plagiat się nie połapał :)

A widzisz - a system zaproponowany przeze mnie poniżej by wyłapał ;) Widocznie jest lepszy od tego z plagiat.pl ;)
sadistic_son
Cytat(skarabe.pl @ 10.08.2010, 21:38:13 ) *
żeby wzmocnić ten algorytm to trzeba by było każde słowo sprowadzić do formy podstawowej........
Kolego.... blink.gif Nie przesadzasz? Sama baza danych ze słowami zajęłaby tonę miejsca! To już fantastyką zaleciało, albo co najmniej osiągnięciami wujka google.
skarabe.pl
Cytat(sadistic_son @ 10.08.2010, 22:00:52 ) *
Kolego.... blink.gif Nie przesadzasz? Sama baza danych ze słowami zajęłaby tonę miejsca! To już fantastyką zaleciało, albo co najmniej osiągnięciami wujka google.

400k słów pospolitych (w przybliżeniu) * 16 bajtów (po 8, średnio, na słowo i synonim) = 6,5 MB - czy to dużo? Do tego każda praca/wypracowanie itp. byłyby przechowywane w bazie w dwóch postaciach - oryginalnej i uproszczonej ("ala mieć kot") - żeby przyspieszyć porównywanie. Dla mnie to nie jest aż taka fantastyka. Poza tym - pisałem tylko o teoretycznych możliwościach - autor wątku już sam musi zdecydować, jak wysoka niezawodność algorytmu jest mu potrzebna.
everth
@skarabe.pl czy to co proponujesz nie jest czasem jakąś odmianą testu statystycznego nieparametrycznego (testu U mi się narzucił)? Stosowanie statystyki również mogłoby być tutaj dobrym rozwiązaniem (nie wiem czy do PHPa są jakieś natywne implementacje tych testów).

Innym rozwiązaniem które mi krąży po głowie - to użycie naiwnego klasyfikatora bayesowskiego. W wykrywaniu spamu daje radę. Znalazłem nawet fajny art opisujący implementacją w PHPie. Ma tylko tą jedną wadę że na początku trzeba go ręcznie uczyć które prace mają być uznane za spam - zawsze jednak można połączyć testowanie statystyczne z klasyfikatorem.

PS: Nie zmienia to faktu że twój algorytm wydaje się najprostszy w implementacji smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.