Консультация № 187862
27.05.2014, 00:16
104.74 руб.
0 5 1
Здравствуйте! Прошу помощи в следующем вопросе:
Как будет выглядеть эта функция (в приложении), написанная на python, на языке PHP?

Приложение:
def getRecommendations(prefs,person,similarity=sim_pearson):
totals={}
simSums={}
for other in prefs:
# don't compare me to myself
if other==person: continue
sim=similarity(prefs,person,other)
# ignore scores of zero or lower
if sim<=0: continue
for item in prefs[other]:
# only score movies I haven't seen yet
if item not in prefs[person] or prefs[person][item]==0:
# Similarity * Score
totals.setdefault(item,0)
totals[item]+=prefs[other][item]*sim
# Sum of similarities
simSums.setdefault(item,0)
simSums[item]+=sim
# Create the normalized list
rankings=[(total/simSums[item],item) for item,total in totals.items( )]
# Return the sorted list
rankings.sort( )
rankings.reverse( )
return rankings

Обсуждение

давно
Старший Модератор
312929
1973
27.05.2014, 06:51
общий
это ответ
Здравствуйте, Sandor!

Примерно так:
[code lang=php]
function getRecommendations($prefs, $person, $similarity='sim_pearson')
{
$totals = array();
$simSums = array();
foreach ($prefs as $other_key=>$other_value)
{
# don't compare me to myself
if ($other_key==$person) continue;
$sim = $similarity($prefs, $person, $other_key);
# ignore scores of zero or lower
if ($sim<=0) continue;
foreach ($other_value as $item_key=>$item_value)
# only score movies I haven't seen yet
if (!array_key_exists($item_key, $prefs[$person]) || $prefs[$person][$item_key]==0)
{
# Similarity * Score
$totals[$item_key] = $item_value*$sim + (isset($totals[$item_key])?$totals[$item_key]:0);
# Sum of similarities
$simSums[$item_key] = $sim + (isset($simSums[$item_key])?$simSums[$item_key]:0);
}
}
# Create the normalized list
foreach ($totals as $item=>$total) $rankings[$item] = $total / $simSums[$item];
# Return the sorted list
arsort($rankings, SORT_NUMERIC);
return $rankings
}[/code]
Здесь функция сравнения передаётся через переменную $similarity, поэтому и вызывается через неё как $similarity($prefs, $person, $other_key). Функция array_key_exists($key, $array) проверяет наличие индекса $key в ассоциативном массиве $array - аналогично выражению key in array в Python для словаря array. Вместо двух Python'овских методов sort и reverse используется одна функция arsort сортировки элементов массива по убыванию с сохранением индексов (параметр SORT_NUMERIC означает сравнение элементов как чисел). К сожалению, в PHP нет аналога Python'овского метода setdefault для ассоциативных массивов, поэтому вместо него используется обычная для такого случая конструкция вида isset($array[$key])?$array[$key]:0, которая возвращает элемент массива $array с индексом $key, если элемент с таким индексом существует, и значение по умолчанию (например, 0), если он не существует.
5
Неизвестный
27.05.2014, 11:45
общий
27.05.2014, 11:53
Адресаты:
Здравствуйте! Возникли следующие ошибки:

строка 1: syntax error, unexpected ':', expecting '{' - заменил двоеточие на фигурную скобку.
строка 22: syntax error, unexpected 'as' (T_AS), expecting ';' - заменил for на foreach.
после вышеназванных исправлений ругается в строке 22: Division by zero, однако, выводит массив c названиями, но без значений.

Были ли допущены мной ошибки при исправлении?

Можно ли '}' в строке 19 изменить на endif; а в строке 20 на endforeach; добавив вместо строк 5 и 14 двоеточие к строкам 4 и 13?
Неизвестный
27.05.2014, 12:29
общий
27.05.2014, 12:30
Адресаты:
Локализовал ошибку - 16 и 18 строки, проблема в конструкции isset($array[$key])?$array[$key]:0.
Если вот так, то работает:
строка 16: $totals[$item_key] += $item_value*$sim;
строка 18: $simSums[$item_key] += $sim;

В чем ошибка конструкции с isset($array[$key])?$array[$key]:0 ?
давно
Старший Модератор
312929
1973
28.05.2014, 08:10
общий
28.05.2014, 08:23
Замены в строках 1 и 22 правильные, а в 16 и 18 строке нужно всю конструкцию с isset взять в круглые скобки. Соответствующие исправления в код я внёс.

Операторов endif и endforeach в PHP нет, просто если после if и foreach идёт больше одной команды, то они заключаются в фигурные скобки.
давно
Старший Модератор
312929
1973
28.05.2014, 08:19
общий
В принципе можно конструкцию с isset не использовать и просто писать $totals[$item_key] += $item_value*$sim; и $simSums[$item_key] += $sim;, но тогда всякий раз при первом обращении к элементу с новым индексом $item_key будет выскакивать предупреждение типа Undefined index. Если это мешает, отключите выдачу ошибок в PHP.
Форма ответа