Es gibt viele Möglichkeiten zu berechnen, wie ähnlich Daten einer anderen sind. http://wikiwiki.jp/cattail/?%CE%E0%BB%F7%C5%D9%A4%C8%B5%F7%CE%A5
Unter diesen sind der euklidische Abstand, der Pearson-Produktfaktorkorrelationskoeffizient und der Jaccard-Koeffizient in Python implementiert. Kollektive Wissensprogrammierung Kapitel 2 Referenz. https://www.oreilly.co.jp/books/9784873113647/
Eine allgemeine Distanz ähnlich der der Mittel- und Oberstufe Mathematik. Wenn es sich um zwei oder drei Dimensionen handelt, kann es durch eine Figur dargestellt und ein Bild erstellt werden, es sind jedoch keine weiteren Dimensionen vorstellbar. Aber was ich mache, ist im Grunde das gleiche wie das dritte und niedrigere.
(a_1, a_2, a_3, ... a_i), (b_1, b_2, b_3, ... b_i)
Wenn es zwei Daten gibt, wie z. B., ist der euklidische Abstand d zwischen ab
d = \sqrt{(a_1 - b_1)^2 + (a_2 -b_2)^2 + (a_3 -b_3)^2 + ...+(a_i-b_i)^2}
Wenn dies so bleibt, wird die Entfernung zurückgegeben, aber ich möchte einen Wert, der als Ähnlichkeitsgrad leicht zu verstehen ist. Je ähnlicher die Werte von 0 bis 1 sind, desto näher ist er 1. Ein solcher Wert kann erhalten werden, indem 1 zu diesem d addiert und die inverse Zahl genommen wird, um einen Teilungsfehler bei 0 zu verhindern.
1/(1 + d)
Das Folgende ist die Implementierung in Python.
recommendation.py
import math
def sim_distance(prefs, person1, person2):
#Liste der Dinge, die sowohl person1 als auch person2 bewerten
si = {}
for item in prefs[person1]:
if item in prefs[person2]:
si[item] = 1
#Die Ähnlichkeit ist 0, wenn weder Person1 noch Person2 bewertet werden
if len(si) == 0 :
return 0
#Quadrat der Differenz für jeden Artikel
squares = [(prefs[person1][item] - prefs[person2][item]) ** 2 for item in si]
sum_of_sqrt = math.sqrt(sum(squares))
return 1/(1 + sum_of_sqrt)
Verwenden Sie die folgenden Daten, um die Ähnlichkeit zu ermitteln. Critcs speichert mehrere Filme und die 5-Punkte-Bewertung jeder Person für diese Filme.
critics = {
'Lisa Rose': {
'Lady in the Water': 2.5,
'Snakes on a Plane': 3.5,
'Just My Luck': 3.0,
'Superman Returns': 3.5,
'The Night Listener': 3.0,
'You, Me and Dupree': 2.5,
},
'Gene Seymour': {
'Lady in the Water': 3.0,
'Snakes on a Plane': 3.5,
'Just My Luck': 1.5,
'Superman Returns': 5.0,
'The Night Listener': 3.0,
'You, Me and Dupree': 3.5,
},
'Michael Phillips': {
'Lady in the Water': 2.5,
'Snakes on a Plane': 3.0,
'Superman Returns': 3.5,
'The Night Listener': 4.0,
},
'Claudia Puig': {
'Snakes on a Plane': 3.5,
'Just My Luck': 3.0,
'The Night Listener': 4.5,
'Superman Returns': 4.0,
'You, Me and Dupree': 2.5,
},
'Mick LaSalle': {
'Lady in the Water': 3.0,
'Snakes on a Plane': 4.0,
'Just My Luck': 2.0,
'Superman Returns': 3.0,
'The Night Listener': 3.0,
'You, Me and Dupree': 2.0,
},
'Jack Matthews': {
'Lady in the Water': 3.0,
'Snakes on a Plane': 4.0,
'The Night Listener': 3.0,
'Superman Returns': 5.0,
'You, Me and Dupree': 3.5,
},
'Toby': {
'Snakes on a Plane': 4.5,
'You, Me and Dupree': 1.0,
'Superman Returns': 4.0,
}
}
$ python
Python 3.5.1 (default, Nov 7 2016, 22:30:16)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import recommendation
>>> recommendation.sim_distance(critics, 'Lisa Rose', 'Gene Seymour')
0.29429805508554946
Wenn die Daten nicht normalisiert sind, führt das einfache Ermitteln des euklidischen Abstands nur zu subtilen Ergebnissen. Zum Beispiel bei der Bewertung eines Films, wenn Herr A und Herr B einen ähnlichen Geschmack haben. In diesem Fall möchte ich, dass Herr A und Herr B ein hohes Maß an Ähnlichkeit aufweisen. Angenommen, die beiden Personen bewerten die Filme X, Y und Z wie folgt.
Film X. | Film Y. | Film Z. | |
---|---|---|---|
Herr A. | 3 | 1.5 | 3.5 |
Herr B. | 4 | 2 | 5 |
Obwohl der Geschmack ähnlich zu sein scheint, hat Herr A eine eher trockene Bewertung und Herr B eine süße Bewertung. Wenn dies durch die obige sim_distance berechnet wird, beträgt die Ähnlichkeit 0,348. Wenn die Bewertungspunkte voreingenommen oder verstopft sind, kann der euklidische Abstand sie nicht abdecken, egal wie ähnlich der Geschmack ist.
In solchen Fällen wird der Pearson-Produktfaktorkorrelationskoeffizient verwendet. Quantifizieren Sie die Korrelation, nicht den einfachen Abstand zwischen den Daten.
\frac{ \sum_{i=1}^{n} (X_i - \bar{X})(Y_i - \bar{Y}) } { \sqrt{ \sum_{i=1}^{n} (X_i - \bar{X})^2} \sqrt{ \sum_{i=1}^{n} (Y_i - \bar{Y})^2} }
Die obere Leiste ist der Durchschnittswert. Ich bin mir nicht sicher, was ich mache, wenn ich nur die Formel betrachte, aber das Molekül ist codispers und der Nenner ist die Standardabweichung der einzelnen Daten. Kann es als Berechnung der Kosinusähnlichkeit betrachtet werden? (Ich verstehe nicht gut ...)
Referenz: http://mathtrain.jp/correlation http://aoki2.si.gunma-u.ac.jp/lecture/Soukan/pearson.html http://d.hatena.ne.jp/sleepy_yoshi/20110325/p1
Implementieren Sie dies in Python
def sim_pearson(prefs, person1, person2):
si = {}
for item in prefs[person1]:
if item in prefs[person2]:
si[item] = 1
n = len(si)
if n == 0: return 0
mean1 = sum([prefs[person1][item] for item in si]) / n
mean2 = sum([prefs[person2][item] for item in si]) / n
variance1 = math.sqrt(sum([((prefs[person1][item] - mean1) ** 2) for item in si]))
variance2 = math.sqrt(sum([((prefs[person2][item] - mean2) ** 2) for item in si]))
covariance = sum([(prefs[person1][item] - mean1)*(prefs[person2][item] - mean2) for item in si])
if variance1 * variance2 == 0: return 0
return covariance / (variance1 * variance2)
>>> data = {'Asan': {'X': 3.0,'Y': 1.5,'Z': 3.5,},'Bsan': {'X': 4.0,'Y': 2.0,'Z': 5.0,}}
>>> recommendation.sim_pearson(data, 'Asan', 'Bsan')
0.9958705948858225
Eine Zahl, die viel höher als die euklidische Entfernung war, kam heraus. Dann dachte ich, dass der Produktfaktorkorrelationskoeffizient von Pearson der stärkste war, aber er konnte nicht gut erfasst werden, es sei denn, es handelte sich um eine lineare Beziehung im Streudiagramm, die Vergleichsdaten mussten normal verteilt sein und die Ausreißer waren Es scheint, dass wenn es so ist, es davon mitgerissen wird, also müssen wir die Bedingungen bis zu einem gewissen Grad erfüllen.
In der kollektiven Intelligenzprogrammierung haben wir eine Funktion implementiert, um den Produktfaktorkorrelationskoeffizienten desselben Pearson wie folgt zu ermitteln.
def sim_pearson(prefs, p1, p2):
'''
Returns the Pearson correlation coefficient for p1 and p2.
'''
# Get the list of mutually rated items
si = {}
for item in prefs[p1]:
if item in prefs[p2]:
si[item] = 1
# If they are no ratings in common, return 0
if len(si) == 0:
return 0
# Sum calculations
n = len(si)
# Sums of all the preferences
sum1 = sum([prefs[p1][it] for it in si])
sum2 = sum([prefs[p2][it] for it in si])
# Sums of the squares
sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
# Sum of the products
pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
# Calculate r (Pearson score)
num = pSum - sum1 * sum2 / n
den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
if den == 0:
return 0
r = num / den
return r
https://github.com/arthur-e/Programming-Collective-Intelligence/blob/master/chapter2/recommendations.py
Als ich mir diesen Code in diesem Buch ansah, konnte ich nicht verstehen, wie man die obige Formel in eine solche Implementierung umwandelt, also implementierte ich die Formel wie zuvor. Als ich mit "scipy.stats.pearsonr" in scipy nachgesehen habe, haben der von mir implementierte Code und dieser Code den gleichen Wert zurückgegeben. Es spielt keine Rolle, welche Implementierung Sie verwenden, aber ich weiß nicht, wie ich den Ausdruck transformieren soll, um den Code zu erhalten, der in der Programmierung für kollektive Intelligenz unten angezeigt wird ... Wenn Sie wissen, lassen Sie es mich bitte wissen.
Berechnen Sie die Ähnlichkeit zwischen Mengen.
J( A, B ) = \frac { \mid A \cap B \mid } { \mid A \cup B \mid } = \frac { \mid A \cap B \mid } { |A| + |B| - \mid A \cap B \mid }
https://en.wikipedia.org/wiki/Jaccard_index#Tanimoto_similarity_and_distance
Es wird verwendet, wenn Sie die Ähnlichkeit zwischen Sätzen berechnen möchten. Extrahieren Sie die in Satz A verwendeten Wörter und die in Satz B verwendeten Wörter und ermitteln Sie den Wert aus der Summe der Wörter und des gemeinsamen Teils. In solchen Fällen ist die Ähnlichkeit umso höher, je mehr Wörter häufig verwendet werden.
def sim_jaccard(prefs, a, b):
si = {}
for item in prefs[a]:
if item in prefs[b]:
si[item] = 1
n = len(si)
if n == 0:
return 0
len_a = len(prefs[a])
len_b = len(prefs[b])
return n / (len_a + len_b - n)
>>> data = {'machine-learning': ['DNN', 'python', 'chainer', 'scikit-learn'], 'python-waf': ['python', 'django', 'flask', 'pyenv']}
>>> recommendation.sim_pearson(data, 'machine-learning', 'python-waf')
0.14285714285714285
Recommended Posts