Return None in function: TypeError: object of type 'NoneType' has no len()
Return None in function: TypeError: object of type 'NoneType' has no len()
我正在尝试打印我的主题和 LDA
中每个主题的文本。但是在打印主题后 None 打乱了我的脚本。我可以打印我的主题,但不能打印文本。
import pandas
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
n_top_words = 5
n_components = 5
def print_top_words(model, feature_names, n_top_words):
for topic_idx, topic in enumerate(model.components_):
message = "Topic #%d: " % topic_idx
message += " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
return message
text = pandas.read_csv('text.csv', encoding = 'utf-8')
text_list = text.values.tolist()
tf_vectorizer = CountVectorizer()
tf = tf_vectorizer.fit_transform(text_list)
lda = LatentDirichletAllocation(n_components=n_components, learning_method='batch', max_iter=25, random_state=0)
doc_distr = lda.fit_transform(tf)
tf_feature_names = tf_vectorizer.get_feature_names()
print (print_top_words(lda, tf_feature_names, n_top_words))
doc_distr = lda.fit_transform(tf)
topics = print_top_words(lda, tf_feature_names, n_top_words)
for i in range(len(topics)):
print ("Topic {}:".format(i))
docs = np.argsort(doc_distr[:, i])[::-1]
for j in docs[:10]:
print (" ".join(text_list[j].split(",")[:2]))
我的输出:
Topic 0: no order mail received back
Topic 1: cancel order wishes possible wish
Topic 2: keep current informed delivery order
Topic 3: faulty wooden box present side
Topic 4: delivered received be produced urgent
Topic 5: good waiting day response share
后面出现这个错误:
File "lda.py", line 41, in <module>
for i in range(len(topics)):
TypeError: object of type 'NoneType' has no len()
您没有提供完整的代码,但最可能的原因是变量 topics
是 None。唯一可能发生的情况是,如果 print_top_words
函数中的 model.components_
是一个空集合,那么循环永远不会运行,并且函数(隐式地)returns None。检查集合的价值。更好的是,在这种情况下选择要 returned 的值。
另一个不相关的点:你在每次迭代中初始化你的 message
变量,并且你在每次迭代中 return 它。检查你的意思。
如果不了解 LatentDirichletAllocation
的内部工作原理,这个问题很难回答。但是,它的 components_ 与它有关,因为它的重复迭代会产生不同的结果。
您很可能可以通过更改以下内容来避免此错误:
print (print_top_words(lda, tf_feature_names, n_top_words))
doc_distr = lda.fit_transform(tf)
topics = print_top_words(lda, tf_feature_names, n_top_words)
至:
temp = print_top_words(lda, tf_feature_names, n_top_words)
print (temp)
doc_distr = lda.fit_transform(tf)
topics = print_top_words(temp)
第二次调用该函数,model.components_ returns什么都没有,所以循环被跳过,函数returns none.
但是,我不确定这是否是代码的实际意图。看起来您可能希望 print_top_words 成为一个生成器?您正在返回 for 循环内部,这使得它永远不会到达第二次迭代。这可能不是循环的目的。
您的 print_top_words()
功能(至少)有四个问题。
第一个 - 导致您当前的问题 - 是如果 model.components_
为空,for 循环的主体将不会执行,然后您的函数将(隐含地) return None
.
第二个有点微妙:如果 model.components_
不为空,函数将 return 仅第一条消息,然后 return 它并退出 - 这非常return
语句的定义:return 一个值(如果未指定值,则为 None
)并退出该函数。
第三个问题是(当model.components_
不为空时),函数return是一个字符串,调用代码显然需要一个列表。这是一个微妙的错误,因为字符串有长度,所以 range(len(topics))
上的 for 循环似乎 可以工作,但 len(topics)
肯定不是您期望的值。
最后,该函数的命名非常糟糕,因为它没有 "print" 任何东西 - 与前三个问题相比,这看起来微不足道,并且它不会阻止代码确实工作(假设前三个问题已修复),但是代码推理本身就已经足够困难了,因此正确命名 很重要,因为它大大减少了认知负担并使维护/调试更容易。
长话短说:想想你真正想要这个功能做什么,并适当地修复它。我不会在此处 post "corrected" 版本,因为我不确定您要做什么,但以上说明应该有所帮助。
注意:另外,您使用完全相同的参数调用 doc_distr = lda.fit_transform(tf)
和 print_top_words(lda, tf_feature_names, n_top_words)
两次,这要么完全没用,要么纯粹浪费处理器周期(在最好的情况下)或如果您从第二次调用中得到不同的结果,就会有另一个错误的味道。
我正在尝试打印我的主题和 LDA
中每个主题的文本。但是在打印主题后 None 打乱了我的脚本。我可以打印我的主题,但不能打印文本。
import pandas
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
n_top_words = 5
n_components = 5
def print_top_words(model, feature_names, n_top_words):
for topic_idx, topic in enumerate(model.components_):
message = "Topic #%d: " % topic_idx
message += " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
return message
text = pandas.read_csv('text.csv', encoding = 'utf-8')
text_list = text.values.tolist()
tf_vectorizer = CountVectorizer()
tf = tf_vectorizer.fit_transform(text_list)
lda = LatentDirichletAllocation(n_components=n_components, learning_method='batch', max_iter=25, random_state=0)
doc_distr = lda.fit_transform(tf)
tf_feature_names = tf_vectorizer.get_feature_names()
print (print_top_words(lda, tf_feature_names, n_top_words))
doc_distr = lda.fit_transform(tf)
topics = print_top_words(lda, tf_feature_names, n_top_words)
for i in range(len(topics)):
print ("Topic {}:".format(i))
docs = np.argsort(doc_distr[:, i])[::-1]
for j in docs[:10]:
print (" ".join(text_list[j].split(",")[:2]))
我的输出:
Topic 0: no order mail received back
Topic 1: cancel order wishes possible wish
Topic 2: keep current informed delivery order
Topic 3: faulty wooden box present side
Topic 4: delivered received be produced urgent
Topic 5: good waiting day response share
后面出现这个错误:
File "lda.py", line 41, in <module>
for i in range(len(topics)):
TypeError: object of type 'NoneType' has no len()
您没有提供完整的代码,但最可能的原因是变量 topics
是 None。唯一可能发生的情况是,如果 print_top_words
函数中的 model.components_
是一个空集合,那么循环永远不会运行,并且函数(隐式地)returns None。检查集合的价值。更好的是,在这种情况下选择要 returned 的值。
另一个不相关的点:你在每次迭代中初始化你的 message
变量,并且你在每次迭代中 return 它。检查你的意思。
如果不了解 LatentDirichletAllocation
的内部工作原理,这个问题很难回答。但是,它的 components_ 与它有关,因为它的重复迭代会产生不同的结果。
您很可能可以通过更改以下内容来避免此错误:
print (print_top_words(lda, tf_feature_names, n_top_words))
doc_distr = lda.fit_transform(tf)
topics = print_top_words(lda, tf_feature_names, n_top_words)
至:
temp = print_top_words(lda, tf_feature_names, n_top_words)
print (temp)
doc_distr = lda.fit_transform(tf)
topics = print_top_words(temp)
第二次调用该函数,model.components_ returns什么都没有,所以循环被跳过,函数returns none.
但是,我不确定这是否是代码的实际意图。看起来您可能希望 print_top_words 成为一个生成器?您正在返回 for 循环内部,这使得它永远不会到达第二次迭代。这可能不是循环的目的。
您的 print_top_words()
功能(至少)有四个问题。
第一个 - 导致您当前的问题 - 是如果 model.components_
为空,for 循环的主体将不会执行,然后您的函数将(隐含地) return None
.
第二个有点微妙:如果 model.components_
不为空,函数将 return 仅第一条消息,然后 return 它并退出 - 这非常return
语句的定义:return 一个值(如果未指定值,则为 None
)并退出该函数。
第三个问题是(当model.components_
不为空时),函数return是一个字符串,调用代码显然需要一个列表。这是一个微妙的错误,因为字符串有长度,所以 range(len(topics))
上的 for 循环似乎 可以工作,但 len(topics)
肯定不是您期望的值。
最后,该函数的命名非常糟糕,因为它没有 "print" 任何东西 - 与前三个问题相比,这看起来微不足道,并且它不会阻止代码确实工作(假设前三个问题已修复),但是代码推理本身就已经足够困难了,因此正确命名 很重要,因为它大大减少了认知负担并使维护/调试更容易。
长话短说:想想你真正想要这个功能做什么,并适当地修复它。我不会在此处 post "corrected" 版本,因为我不确定您要做什么,但以上说明应该有所帮助。
注意:另外,您使用完全相同的参数调用 doc_distr = lda.fit_transform(tf)
和 print_top_words(lda, tf_feature_names, n_top_words)
两次,这要么完全没用,要么纯粹浪费处理器周期(在最好的情况下)或如果您从第二次调用中得到不同的结果,就会有另一个错误的味道。