Heim  >  Artikel  >  Backend-Entwicklung  >  Implementierung des kollaborativen PHP+MySQL-Filteralgorithmus

Implementierung des kollaborativen PHP+MySQL-Filteralgorithmus

巴扎黑
巴扎黑Original
2017-08-15 09:29:122522Durchsuche

Um den kollaborativen Filterempfehlungsalgorithmus zu implementieren, müssen Sie zunächst die Kernidee und den Prozess des Algorithmus verstehen. Die Kernidee dieses Algorithmus lässt sich wie folgt zusammenfassen: Wenn a und b die gleiche Reihe von Elementen mögen (nennen wir b vorerst einen Nachbarn), dann mag a wahrscheinlich andere Elemente, die b mag. Der Implementierungsprozess des Algorithmus lässt sich einfach wie folgt zusammenfassen: 1. Bestimmen Sie, welche Nachbarn a hat. 2. Verwenden Sie die Nachbarn, um vorherzusagen, welche Art von Artikeln a gefallen könnten.

Die Kernformel des Algorithmus lautet wie folgt:

1. Kosinusähnlichkeit (Nachbarn finden):

Implementierung des kollaborativen PHP+MySQL-Filteralgorithmus

2 . Vorhersageformel (Vorhersagen, welche Art von Artikeln einem gefallen könnten):

Implementierung des kollaborativen PHP+MySQL-Filteralgorithmus

Allein aus diesen beiden Formeln können wir ersehen, dass allein die Berechnung nach diesen beiden Formeln Folgendes erfordert: Es gibt viele Schleifen und Urteilsvermögen, und es geht auch um Sortierprobleme, bei denen es um die Auswahl und Verwendung von Sortieralgorithmen geht. Hier wähle ich die Schnellsortierung, kopiere einen Abschnitt der Schnellsortierung aus dem Internet und verwende ihn direkt. Kurz gesagt, die Implementierung ist sehr mühsam, ganz zu schweigen von der Effizienz im Fall von Big Data.

Erstellen Sie zunächst eine Tabelle:

DROP TABLE IF EXISTS `tb_xttj`;
CREATE TABLE `tb_xttj` (
  `name` varchar(255) NOT NULL,
  `a` int(255) default NULL,
  `b` int(255) default NULL,
  `c` int(255) default NULL,
  `d` int(255) default NULL,
  `e` int(255) default NULL,
  `f` int(255) default NULL,
  `g` int(255) default NULL,
  `h` int(255) default NULL,
  PRIMARY KEY  (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `tb_xttj` VALUES ('John', '4', '4', '5', '4', '3', '2', '1', null);
INSERT INTO `tb_xttj` VALUES ('Mary', '3', '4', '4', '2', '5', '4', '3', null);
INSERT INTO `tb_xttj` VALUES ('Lucy', '2', '3', null, '3', null, '3', '4', '5');
INSERT INTO `tb_xttj` VALUES ('Tom', '3', '4', '5', null, '1', '3', '5', '4');
INSERT INTO `tb_xttj` VALUES ('Bill', '3', '2', '1', '5', '3', '2', '1', '1');
INSERT INTO `tb_xttj` VALUES ('Leo', '3', '4', '5', '2', '4', null, null, null);

Ich werde Leo nur in der letzten Zeile empfehlen, um zu sehen, welches von f, g und h ihm empfohlen werden kann.

Bei Verwendung von PHP+MySQL sieht das Flussdiagramm wie folgt aus:


Der Code zum Herstellen einer Verbindung mit der Datenbank und zum Speichern als Ein zweidimensionales Array sieht wie folgt aus:

header("Content-Type:text/html;charset=utf-8");

mysql_connect("localhost","root","admin");
mysql_select_db("geodatabase");
mysql_query("set names 'utf8'");	

$sql = "SELECT * FROM tb_xttj";
$result = mysql_query($sql);

$array = array();
while($row=mysql_fetch_array($result))
{
	$array[]=$row;//$array[][]是一个二维数组
}

Frage 1: Dieser Schritt kann als eine vollständige Tabellenabfrage betrachtet werden. Dies ist in Ordnung ein kleines Demonstrationssystem, aber für große Das Datensystem ist ineffizient. Was die Verbesserung betrifft, müssen wir noch mehr lernen.

Der Code zum Ermitteln des Cos-Werts von Löwe und anderen lautet wie folgt:

/*
 * 以下示例只求Leo的推荐,如此给变量命名我也是醉了;初次理解算法,先不考虑效率和逻辑的问题,主要把过程做出来
 */

$cos = array();
$cos[0] = 0;
$fm1 = 0;
//开始计算cos
//计算分母1,分母1是第一个公式里面 “*”号左边的内容,分母二是右边的内容
for($i=1;$i<9;$i++){
	if($array[5][$i] != null){//$array[5]代表Leo
		$fm1 += $array[5][$i] * $array[5][$i];
	}
}

$fm1 = sqrt($fm1);

for($i=0;$i<5;$i++){
	$fz = 0;
	$fm2 = 0;
	echo "Cos(".$array[5][0].",".$array[$i][0].")=";
	
	for($j=1;$j<9;$j++){
	    //计算分子
		if($array[5][$j] != null && $array[$i][$j] != null){
			$fz += $array[5][$j] * $array[$i][$j];
		}
		//计算分母2
		if($array[$i][$j] != null){
			$fm2 += $array[$i][$j] * $array[$i][$j];
		}			
	}
	$fm2 = sqrt($fm2);
	$cos[$i] = $fz/$fm1/$fm2;
	echo $cos[$i]."<br/>";
}
Das Ergebnis dieses Schritts ist Jiang Zi:

Sortieren Sie die erhaltenen Cos-Werte und verwenden Sie den Schnellsortiercode wie folgt (von Baidu kopiert):

//对计算结果进行排序,凑合用快排吧先
function quicksort($str){
	if(count($str)<=1) return $str;//如果个数不大于一,直接返回
	$key=$str[0];//取一个值,稍后用来比较;
	$left_arr=array();
	$right_arr=array();
	
	for($i=1;$i<count($str);$i++){//比$key大的放在右边,小的放在左边;
		if($str[$i]>=$key)
		$left_arr[]=$str[$i];
		else
		$right_arr[]=$str[$i];
	}
	$left_arr=quicksort($left_arr);//进行递归;
	$right_arr=quicksort($right_arr);
	return array_merge($left_arr,array($key),$right_arr);//将左中右的值合并成一个数组;
}

$neighbour = array();//$neighbour只是对cos值进行排序并存储
$neighbour = quicksort($cos);

The Das $neighbour-Array speichert hier nur die von groß nach klein sortierten Cos-Werte, die nicht mit Personen verknüpft sind. Dieses Problem muss noch gelöst werden.

Wählen Sie die 3 Personen mit den höchsten CoS-Werten als Leos Nachbarn aus:

//$neighbour_set 存储最近邻的人和cos值
$neighbour_set = array();
for($i=0;$i<3;$i++){
	for($j=0;$j<5;$j++){
		if($neighbour[$i] == $cos[$j]){
			$neighbour_set[$i][0] = $j;
			$neighbour_set[$i][1] = $cos[$j];
			$neighbour_set[$i][2] = $array[$j][6];//邻居对f的评分
			$neighbour_set[$i][3] = $array[$j][7];//邻居对g的评分
			$neighbour_set[$i][4] = $array[$j][8];//邻居对h的评分
		}
	}
}
print_r($neighbour_set);
echo "<p><br/>";

Das Ergebnis dieses Schrittes ist Jiang Zi:


Dies ist ein zweidimensionales Array. Die Indizes auf der ersten Ebene des Arrays sind 0, 1 und 2 und repräsentieren 3 Personen. Der Index 0 der zweiten Ebene stellt die Reihenfolge der Nachbarn in der Datentabelle dar, zum Beispiel ist Jhon die 0. Person in der Tabelle; der Index 1 repräsentiert den Cos-Wert von Leo und der Index 2, 3 und 4 repräsentieren das Nachbarpaar f bzw. g, h-Bewertung.

Vorhersage starten Der Berechnungscode für Predict lautet wie folgt:

Ich berechne Leos vorhergesagte Werte für f, g, h. Hier gibt es ein Problem, nämlich wie man damit umgehen soll, wenn einige Nachbarn leere Werte für f, g, h haben. Beispielsweise sind die Bewertungen von Jhon und Mary für h leer. Instinktiv denke ich darüber nach, if zur Beurteilung zu verwenden, und wenn es leer ist, überspringe ich diese Berechnungsreihe, aber ob dies sinnvoll ist, muss noch geprüft werden. Der folgende Code schreibt dieses Urteil nicht.

//计算Leo对f的评分
$p_arr = array();
$pfz_f = 0;
$pfm_f = 0;
for($i=0;$i<3;$i++){
	$pfz_f += $neighbour_set[$i][1] * $neighbour_set[$i][2];
	$pfm_f += $neighbour_set[$i][1];
}
$p_arr[0][0] = 6;
$p_arr[0][1] = $pfz_f/sqrt($pfm_f);
if($p_arr[0][1]>3){
	echo "推荐f";
}

//计算Leo对g的评分
$pfz_g = 0;
$pfm_g = 0;
for($i=0;$i<3;$i++){
	$pfz_g += $neighbour_set[$i][1] * $neighbour_set[$i][3];
	$pfm_g += $neighbour_set[$i][1];
	$p_arr[1][0] = 7;
	$p_arr[1][1] = $pfz_g/sqrt($pfm_g);
}
if($p_arr[0][1]>3){
	echo "推荐g";
}

//计算Leo对h的评分
$pfz_h = 0;
$pfm_h = 0;
for($i=0;$i<3;$i++){
	$pfz_h += $neighbour_set[$i][1] * $neighbour_set[$i][4];
	$pfm_h += $neighbour_set[$i][1];
	$p_arr[2][0] = 8;
	$p_arr[2][1] = $pfz_h/sqrt($pfm_h);
}
print_r($p_arr);
if($p_arr[0][1]>3){
	echo "推荐h";
}

$p_arr ist das empfohlene Array für Leo, sein Inhalt ähnelt dem folgenden:

Array ( [0] => Array ( [0] => ; 6 [ 1] => 4.2314002228795 ) [1] => Array ( [0] => 7 [1] => 2.6511380196197 ) [2] => Array ( [0] => 8 ] => ; 0,45287424581774 ) )

f ist die 6. Spalte, der Vorhersagewert ist 4,23, g ist die siebte Spalte, der Vorhersagewert ist 2,65...

Nach der Berechnung der Vorhersagewerte von f, g, h gibt es zwei Verarbeitungsmethoden: Eine besteht darin, Elemente mit Vorhersagewerten größer als 3 an Leo zu empfehlen, die andere darin, die Vorhersagewerte zu sortieren von groß nach klein, und die ersten beiden Artikel mit dem höchsten Wert werden Leo empfohlen. Dieser Code wurde nicht geschrieben.

Wie aus dem obigen Beispiel ersichtlich ist, ist die Implementierung des Empfehlungsalgorithmus sehr mühsam und erfordert Schleifen, Beurteilung, Zusammenführen von Arrays usw. Bei unsachgemäßer Handhabung wird es zu einer Belastung für das System. Bei der tatsächlichen Verarbeitung treten weiterhin folgende Probleme auf:

1. Im obigen Beispiel empfehlen wir nur Leo, und wir wissen bereits, dass Leo die Elemente f, g, h nicht ausgewertet hat. In einem tatsächlichen System muss für jeden Benutzer, der eine Empfehlung abgeben muss, herausgefunden werden, welche Artikel er nicht bewertet hat, was einen weiteren Teil des Overheads darstellt.

2. Die gesamte Tabellenabfrage sollte nicht durchgeführt werden. Im tatsächlichen System können einige Standardwerte festgelegt werden. Beispiel: Wir finden den Cos-Wert zwischen Löwe und anderen Personen in der Tabelle. Wenn der Wert größer als 0,80 ist, bedeutet dies, dass sie Nachbarn sein können. Auf diese Weise höre ich auf, den Cos-Wert zu berechnen, wenn ich 10 Nachbarn finde, um zu vermeiden, dass die gesamte Tabelle abgefragt wird. Diese Methode kann auch sinnvoll für empfohlene Artikel verwendet werden. Ich empfehle beispielsweise nur 10 Artikel und höre auf, den Vorhersagewert zu berechnen, nachdem ich sie empfohlen habe.

3. Wenn das System verwendet wird, ändern sich auch die Elemente. Heute ist es fgh, und morgen kann es sein, dass sich die Elemente ändern.

4. Inhaltsbasierte Empfehlungen können entsprechend eingeführt werden, um den Empfehlungsalgorithmus zu verbessern.

5. Probleme mit der empfohlenen Genauigkeit wirken sich auf die Genauigkeit aus.

Zusammenfassung: Ich denke, das Hauptproblem besteht darin, dass die Effizienz des Algorithmus nicht hoch ist. Untersuchen Sie weiter, ob es einen besseren Empfehlungsalgorithmus für die kollaborative Filterung gibt.

Das obige ist der detaillierte Inhalt vonImplementierung des kollaborativen PHP+MySQL-Filteralgorithmus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn